diff --git a/Manifest.toml b/Manifest.toml
index aed827e057d313b7f8fa5c0cbd1c2b2221de3dc1..a4a7ee073294daca4cadfb488cb28ffcc390b800 100644
--- a/Manifest.toml
+++ b/Manifest.toml
@@ -2,7 +2,7 @@
 
 julia_version = "1.8.2"
 manifest_format = "2.0"
-project_hash = "4e8a5dcb55ba02909578a76b57750f4d6fb0a766"
+project_hash = "d37bc0692e4cb75dce4365cae9dc31c02a907c73"
 
 [[deps.AbstractFFTs]]
 deps = ["ChainRulesCore", "LinearAlgebra"]
@@ -147,12 +147,6 @@ deps = ["Artifacts", "Libdl"]
 uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
 version = "0.5.2+0"
 
-[[deps.Conda]]
-deps = ["Downloads", "JSON", "VersionParsing"]
-git-tree-sha1 = "6e47d11ea2776bc5627421d59cdcc1296c058071"
-uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d"
-version = "1.7.0"
-
 [[deps.Contour]]
 git-tree-sha1 = "d05d9e7b7aedff4e5b51a029dced05cfb6125781"
 uuid = "d38c429a-6771-53c6-b99e-75d170b6e991"
@@ -676,12 +670,6 @@ git-tree-sha1 = "2ce8695e1e699b68702c03402672a69f54b8aca9"
 uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7"
 version = "2022.2.0+0"
 
-[[deps.MacroTools]]
-deps = ["Markdown", "Random"]
-git-tree-sha1 = "42324d08725e200c23d4dfb549e0d5d89dede2d2"
-uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
-version = "0.5.10"
-
 [[deps.Makie]]
 deps = ["Animations", "Base64", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "Distributions", "DocStringExtensions", "FFMPEG", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MakieCore", "Markdown", "Match", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "Printf", "Random", "RelocatableFolders", "Serialization", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "UnicodeFun"]
 git-tree-sha1 = "b0323393a7190c9bf5b03af442fc115756df8e59"
@@ -726,12 +714,6 @@ deps = ["Artifacts", "Libdl"]
 uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
 version = "2.28.0+0"
 
-[[deps.Memoization]]
-deps = ["MacroTools"]
-git-tree-sha1 = "55dc27dc3d663900d1d768822528960acadc012a"
-uuid = "6fafb56a-5788-4b4e-91ca-c0cea6611c73"
-version = "0.1.14"
-
 [[deps.Meshes]]
 deps = ["Bessels", "CircularArrays", "Distances", "IterTools", "IteratorInterfaceExtensions", "LinearAlgebra", "NearestNeighbors", "Random", "ReferenceFrameRotations", "SparseArrays", "StaticArrays", "StatsBase", "TableTraits", "Tables", "TransformsBase"]
 git-tree-sha1 = "589bc39cdaa212b352918b4c11cc4d2eaf899822"
@@ -942,12 +924,6 @@ git-tree-sha1 = "d7a7aef8f8f2d537104f170139553b14dfe39fe9"
 uuid = "92933f4c-e287-5a05-a399-4b506db050ca"
 version = "1.7.2"
 
-[[deps.PyCall]]
-deps = ["Conda", "Dates", "Libdl", "LinearAlgebra", "MacroTools", "Serialization", "VersionParsing"]
-git-tree-sha1 = "53b8b07b721b77144a0fbbbc2675222ebf40a02d"
-uuid = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
-version = "1.94.1"
-
 [[deps.QOI]]
 deps = ["ColorTypes", "FileIO", "FixedPointNumbers"]
 git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce"
@@ -1157,14 +1133,6 @@ git-tree-sha1 = "c79322d36826aa2f4fd8ecfa96ddb47b174ac78d"
 uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
 version = "1.10.0"
 
-[[deps.TaggingBackends]]
-deps = ["Dates", "HDF5", "LazyArtifacts", "MAT", "Memoization", "OrderedCollections", "PlanarLarvae", "PyCall", "Random", "StaticArrays", "Statistics"]
-git-tree-sha1 = "610f42dc290ff67b54b4fbc84edebaec94eba2d8"
-repo-rev = "main"
-repo-url = "https://gitlab.pasteur.fr/nyx/TaggingBackends"
-uuid = "e551f703-3b82-4335-b341-d497b48d519b"
-version = "0.5.0"
-
 [[deps.Tar]]
 deps = ["ArgTools", "SHA"]
 uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"
@@ -1224,11 +1192,6 @@ git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf"
 uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1"
 version = "0.4.1"
 
-[[deps.VersionParsing]]
-git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868"
-uuid = "81def892-9a0e-5fdd-b105-ffc91e053289"
-version = "1.3.0"
-
 [[deps.WGLMakie]]
 deps = ["Colors", "FileIO", "FreeTypeAbstraction", "GeometryBasics", "Hyperscript", "ImageMagick", "JSServe", "LinearAlgebra", "Makie", "Observables", "RelocatableFolders", "ShaderAbstractions", "StaticArrays"]
 git-tree-sha1 = "0c7a980515d2072b1bc094668b5ca94671d020de"
diff --git a/Project.toml b/Project.toml
index c480193e01a5a3f39f4bb7408449e31231b92f33..492c4be584ceb11bfbbf6c8adbd5a1275249f6fc 100644
--- a/Project.toml
+++ b/Project.toml
@@ -20,7 +20,6 @@ PlanarLarvae = "c2615984-ef14-4d40-b148-916c85b43307"
 Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
 StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
 Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
-TaggingBackends = "e551f703-3b82-4335-b341-d497b48d519b"
 TidyObservables = "c8131bbd-73a8-4254-a42d-d5d4c5febb31"
 WGLMakie = "276b4fcb-3e11-5398-bf8b-a0c2d153d008"
 
diff --git a/README.md b/README.md
index f298f5270650de964b0732c555475ce007c02a5a..17a2fff508a673f3e6cbf2e213e7e6ff65cec9fd 100644
--- a/README.md
+++ b/README.md
@@ -75,16 +75,16 @@ julia> using LarvaTagger; display(larvaeditor("path/to/data/file"; backend_direc
 
 Similarly, to let *larvatagger.jl* know about MaggotUBA:
 ```
-scripts/larvatagger.jl open "path/to/data/file" --backends="path/to/MaggotUBA's/parent/directory" --browser
+scripts/larvatagger.jl open <path/to/data/file> --backends=<path/to/MaggotUBA's/parent/directory> --browser
 ```
 
 The larvatagger.jl script can be used to proceed with training a new tagger:
 ```
-scripts/larvatagger.jl train "path/to/backend" "path/to/data/repository" "tagger-name"
+scripts/larvatagger.jl train <path/to/backend> <path/to/data/repository> <tagger-name>
 ```
 and applying a tagger to a tracking data file:
 ```
-scripts/larvatagger.jl predict "path/to/backend" "tagger-name" "path/to/data/file"
+scripts/larvatagger.jl predict <path/to/backend> <tagger-name> <path/to/data/file> --skip-make-dataset
 ```
 
 The `train` and `predict` commands admit more arguments. Check them out with:
diff --git a/recipes/.dockerignore b/recipes/.dockerignore
new file mode 100644
index 0000000000000000000000000000000000000000..0eebccb20a89fd5939ab37e9f18bfd889b21cfc0
--- /dev/null
+++ b/recipes/.dockerignore
@@ -0,0 +1,37 @@
+#*
+
+**/.git
+**/data/raw
+**/data/interim
+**/data/processed
+**/notebooks
+**/*.ipynb
+**/__pycache__
+**/jl.*.cov
+**/*.hdf5
+**/*.mat
+**/*.spine
+**/*.outline
+**/*.csv
+**/*.label
+**/*.labels
+**/*.pt
+**/*.json
+**/*.pkl
+**/*.png
+**/*.svg
+**/*.avi
+**/*.webm
+**/*.gz
+**/*.tgz
+**/*.bz2
+
+!**/*.toml
+!**/*.jl
+!**/*.py
+!**/*.sh
+!**/*.md
+!**/LICENSE
+!**/scripts/tagging-backend
+!**/pretrained_models/default
+!**/models/20221005
diff --git a/recipes/Dockerfile b/recipes/Dockerfile
index 61a03ec76f965107d87bda1c48fe5124a1a703ac..ac5264d3ce6b6dcef3e1b0bb40f1911c9d15b690 100644
--- a/recipes/Dockerfile
+++ b/recipes/Dockerfile
@@ -2,32 +2,30 @@ FROM julia:1.8.2-bullseye
 
 ENV JULIA_PROJECT=/app
 ENV JULIA_DEPOT_PATH=/usr/local/share/julia
+ENV POETRY_VIRTUALENVS_PATH=/usr/local/share/poetry
 
 ARG BRANCH=main
 ARG TIMEZONE=UTC
 RUN apt-get update \
  && apt-get install -y git \
  && rm -rf /var/lib/apt/lists/* \
- && git clone --depth 1 --single-branch -b $BRANCH https://gitlab.pasteur.fr/nyx/larvatagger.jl $JULIA_PROJECT \
- && mkdir -p $JULIA_DEPOT_PATH \
- && echo "JULIA_DEPOT_PATH=$JULIA_DEPOT_PATH" >> /etc/environment \
- && julia -e 'using Pkg; Pkg.instantiate()' \
+ && git clone --depth 1 --single-branch -b $BRANCH https://gitlab.pasteur.fr/nyx/larvatagger.jl "$JULIA_PROJECT" \
+ && julia -e 'using Pkg; try Pkg.rm("TaggingBackends"); catch end; Pkg.instantiate()' \
  && ln -s $JULIA_PROJECT/scripts/larvatagger.jl /bin \
  && ln -snf /usr/share/zoneinfo/$TIMEZONE /etc/localtime \
  && echo $TIMEZONE > /etc/timezone
 
 ARG BACKEND
-RUN cd $JULIA_PROJECT; \
+RUN cd "$JULIA_PROJECT"; \
     if [ "$BACKEND" = "MaggotUBA/20221005" ]; then \
-    apt-get update \
+    julia --project=. -e "using Pkg; Pkg.add(url=\"https://gitlab.pasteur.fr/nyx/TaggingBackends\", rev=\"$BRANCH\")" \
+ && apt-get update \
  && apt-get install -y python3-pip \
  && python3 -m pip install poetry \
+ && mkdir -p "$POETRY_VIRTUALENVS_PATH" \
  && git clone --depth 1 --single-branch -b 20221005 https://gitlab.pasteur.fr/nyx/MaggotUBA-adapter MaggotUBA \
  && cd MaggotUBA \
- && python3 -m poetry install \
- && python3 -m poetry run python -c 'import julia; julia.install()' \
- #&& python3 -m poetry run python -c "from julia.api import Julia; Julia(compiled_modules=False); from julia import Pkg; Pkg.add(url=\"https://gitlab.pasteur.fr/nyx/planarlarvae.jl\", rev=\"$BRANCH\"); Pkg.add(url=\"https://gitlab.pasteur.fr/nyx/TaggingBackends\", rev=\"$BRANCH\")" \
- && cd .. \
+ && poetry install \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*; \
     fi
diff --git a/recipes/Dockerfile.local b/recipes/Dockerfile.local
index 548889d30092a55c13593c53fe514e4be7f6f0be..a3926b81340a76110d3bb0f21e9f6c7cf1ec7721 100644
--- a/recipes/Dockerfile.local
+++ b/recipes/Dockerfile.local
@@ -1,14 +1,48 @@
 FROM julia:1.8.2-bullseye
 
-COPY src /app/src/
-COPY scripts /app/scripts/
-COPY Project.toml Manifest.toml /app/
+ENV JULIA_PROJECT=/app/TaggingBackends
+ENV JULIA_DEPOT_PATH=/usr/local/share/julia
+ENV POETRY_VIRTUALENVS_PATH=/usr/local/share/poetry
+
+ARG PLANARLARVAE=./PlanarLarvae
+ARG LARVATAGGER=./LarvaTagger
+ARG TAGGINGBACKENDS=./TaggingBackends
+ARG MAGGOTUBA_CORE=./MaggotUBA-core
+ARG MAGGOTUBA_ADAPTER=./maggot
+
+COPY $PLANARLARVAE/src /app/PlanarLarvae/src
+COPY $PLANARLARVAE/Project.toml $PLANARLARVAE/Manifest.toml /app/PlanarLarvae/
+COPY $LARVATAGGER/src /app/src
+COPY $LARVATAGGER/scripts /app/scripts
+COPY $LARVATAGGER/Project.toml $LARVATAGGER/Manifest.toml /app/
 
 RUN apt-get update \
- && apt-get install -y git \
- && rm -rf /var/lib/apt/lists/* \
+ && apt-get install -y git python3-pip \
  && cd /app \
- && julia --project=. -e 'using Pkg; Pkg.instantiate()' \
- && ln -s /app/scripts/larvatagger.jl /bin
+ && julia --project=. -e 'using Pkg; try Pkg.rm("TaggingBackends"); catch end; try Pkg.develop(path="PlanarLarvae"); catch end; try Pkg.add(url="https://gitlab.com/dbc-nyx/tidyobservables.jl"); catch end; try Pkg.add(url="https://gitlab.com/dbc-nyx/ObservationPolicies.jl"); catch end; Pkg.instantiate()' \
+ && ln -s /app/scripts/larvatagger.jl /bin \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/* \
+ && ls /app
+
+COPY $TAGGINGBACKENDS/src /app/TaggingBackends/src
+COPY $TAGGINGBACKENDS/scripts /app/TaggingBackends/scripts
+COPY $TAGGINGBACKENDS/Project.toml $TAGGINGBACKENDS/Manifest.toml $TAGGINGBACKENDS/pyproject.toml /app/TaggingBackends/
+COPY $MAGGOTUBA_CORE/src /app/MaggotUBA-core/src
+COPY $MAGGOTUBA_CORE/pyproject.toml /app/MaggotUBA-core/
+COPY $MAGGOTUBA_ADAPTER/src /app/MaggotUBA/src
+COPY $MAGGOTUBA_ADAPTER/pyproject.toml /app/MaggotUBA/
+COPY $MAGGOTUBA_ADAPTER/models/20221005 /app/MaggotUBA/models/20221005
+COPY $MAGGOTUBA_ADAPTER/pretrained_models/default /app/MaggotUBA/pretrained_models/default
+
+RUN python3 -m pip install poetry \
+ && mkdir -p "$POETRY_VIRTUALENVS_PATH" \
+ && cd /app/TaggingBackends \
+ && julia --project=. -e 'using Pkg; Pkg.develop(path="../PlanarLarvae"); Pkg.instantiate()' \
+ && poetry install \
+ && cd /app/MaggotUBA \
+ && poetry add ../MaggotUBA-core \
+ && poetry add ../TaggingBackends \
+ && poetry install
 
 ENTRYPOINT ["larvatagger.jl"]
diff --git a/recipes/README.md b/recipes/README.md
index fd9c54cb77892d91022fc8a598370f1870dd616f..d2847bdc3548158d148dbc5f683b3ca2c60d439d 100644
--- a/recipes/README.md
+++ b/recipes/README.md
@@ -31,18 +31,20 @@ This is required, since no files outside the container can be accessed.
 
 The port *LarvaTagger.jl* listens to must also be exported with `-p 9284:9284` so that it can be accessed from outside the container.
 
-Just like the `scripts/larvatagger.jl` script, the docker image admits more commands, including `import`, `train` and `predict`, or options such as `--help`.
+Just like the `larvatagger.jl` script, the docker image admits more commands, including `import`, `train` and `predict`, or options such as `--help`.
 For these other commands, neither `-i` nor `-p 9284:9284` are necessary.
 
-See also standalone script [`scripts/larvatagger.sh`](https://gitlab.pasteur.fr/nyx/larvatagger.jl/-/blob/main/scripts/larvatagger.sh) that wraps `docker` and exposes a simpler interface. For example:
+For Unix-like systems, see also standalone script [`larvatagger.sh`](https://gitlab.pasteur.fr/nyx/larvatagger.jl/-/blob/main/scripts/larvatagger.sh) that can be downloaded separately and wraps the `docker` command and exposes a simpler interface. For example:
 
 ```
-scripts/larvatagger.sh open path/to/your/file
+./larvatagger.sh open path/to/your/file
 ```
 
+Note you may need to set larvatagger.sh permissions so that it can be executed.
+
 ## Building an image
 
-The `scripts/larvatagger.sh` script features a `build` command:
+The `larvatagger.sh` script features a `build` command:
 
 ```
 scripts/larvatagger.sh build
@@ -54,3 +56,18 @@ Optionally, you can also get the default *20221005* backend with:
 scripts/larvatagger.sh build --get-backend
 ```
 
+The `build` command requires a local copy of the LarvaTagger.jl project. In addition, the larvatagger.sh script must be executed from the project root directory, hence the path `scripts/larvatagger.sh`.
+
+## `train` and `predict`
+
+The larvatagger.sh script is recommended for the `train` and `predict` commands.
+
+Type `scripts/larvatagger.sh` alone to check out about command usage.
+
+For the trained models to be persistant, the `train` command must store them outside the container.
+Per default, `larvatagger.sh train` creates a *models* directory in the current directory and stores the model instances in there.
+
+Note that the `larvatagger.sh` script is required here. Alternatively, the external *models* directory can be manually mounted as */app/MaggotUBA/models*. Ownership of the generated files will have to be fixed (*root* per default on Unix-like systems).
+
+The `predict` command can use external model instances passing paths instead of instance names.
+To distinguish between paths and names, `larvatagger.sh` checks whether the corresponding directory exists. If a directory exists at the path pointed to by `--model-instance` (on the host), then it is mounted into the container as an external trained model.
diff --git a/scripts/larvatagger.sh b/scripts/larvatagger.sh
index 7ff894ced39e07918b88f6c577afb2b66b55a47b..8739258c75d3b4368eb9c28399aabfd7c5b36251 100755
--- a/scripts/larvatagger.sh
+++ b/scripts/larvatagger.sh
@@ -10,10 +10,10 @@ LARVATAGGER_IMAGE=flaur/larvatagger
 fi
 fi
 
-IO_UID=$(id -u $USER)
-IO_GID=$(id -g $USER)
-RUN_ARGS="-u $IO_UID:$IO_GID -v $(pwd):/data"
-RUN_ARGS="-e IO_UID=$IO_UID -e IO_GID=$IO_GID -v $(pwd):/data"
+HOST_UID=$(id -u $USER)
+HOST_GID=$(id -g $USER)
+RUN_ARGS="-u $HOST_UID:$HOST_GID -v $(pwd):/data"
+RUN_ARGS="-e HOST_UID=$HOST_UID -e HOST_GID=$HOST_GID -v $(pwd):/data"
 
 case "$cmd" in
 
@@ -36,7 +36,9 @@ done
 DOCKER_ARGS="--build-arg TIMEZONE=$(cat /etc/timezone) $DOCKER_ARGS"
 if [ "$BUILD" == "--dev" ]; then
 if ! [[ "$LARVATAGGER_IMAGE" == *:* ]]; then LARVATAGGER_IMAGE="${LARVATAGGER_IMAGE}:dev"; fi
-docker build -t "$LARVATAGGER_IMAGE" -f recipes/Dockerfile.local ${DOCKER_ARGS}.
+PROJECT_ROOT=$(basename $(pwd))
+cd ..
+DOCKER_BUILDKIT=1 docker build -t "$LARVATAGGER_IMAGE" -f "$PROJECT_ROOT/recipes/Dockerfile.local" ${DOCKER_ARGS}.
 elif [ "$BUILD" == "--stable" ]; then
 if ! [[ "$LARVATAGGER_IMAGE" == *:* ]]; then LARVATAGGER_IMAGE="${LARVATAGGER_IMAGE}:stable"; fi
 docker build -t "$LARVATAGGER_IMAGE" -f recipes/Dockerfile ${DOCKER_ARGS}.
@@ -68,28 +70,73 @@ docker run $RUN_ARGS "$LARVATAGGER_IMAGE" import "/data/$file" $@
 
 	train)
 
-backend_path=$1; shift
 data_repository=$1; shift
 tagger=$1; shift
-docker run $RUN_ARGS "$LARVATAGGER_IMAGE" train "/data/$backend_path" "/data/$data_repository" "$tagger" $@
+
+external_models_dir=models
+path=$(dirname $tagger)
+if [ "$path" != "." ]; then
+external_models_dir=$path
+tagger=$(basename $tagger)
+fi
+
+backend=MaggotUBA
+while [ -n "$1" ]; do
+if [ "$1" = "--backend" ]; then
+backend=$2; shift 2
+else
+break
+fi
+done
+
+if [ -n "$external_models_dir" ]; then
+mkdir -p "$external_models_dir"
+RUN_ARGS="$RUN_ARGS --mount type=bind,src=$(realpath $external_models_dir),dst=/app/$backend/models"
+fi
+
+echo "docker run $RUN_ARGS \"$LARVATAGGER_IMAGE\" train \"/app/$backend\" \"/data/$data_repository\" \"$tagger\" $@"
+
+docker run $RUN_ARGS "$LARVATAGGER_IMAGE" train "/app/$backend" "/data/$data_repository" "$tagger" $@
 ;;
 
 	predict)
 
-backend_path=$1; shift
-tagger=$1; shift
 data_file=$1; shift
-docker run $RUN_ARGS "$LARVATAGGER_IMAGE" predict "/data/$backend_path" "$tagger" "/data/$data_file" $@
+
+backend=MaggotUBA
+tagger=20221005
+while [ -n "$1" ]; do
+if [ "$1" = "--model-instance" ]; then
+tagger=$2; shift 2
+if [ -d "$tagger" ]; then
+tagger_path=$tagger
+tagger=$(basename $tagger_path)
+fi
+elif [ "$1" = "--backend" ]; then
+backend=$2; shift 2
+else
+break
+fi
+done
+
+if [ -n "$tagger_path" ]; then
+RUN_ARGS="$RUN_ARGS --mount type=bind,src=$(realpath $tagger_path),dst=/app/$backend/models/$tagger"
+fi
+
+echo "docker run $RUN_ARGS \"$LARVATAGGER_IMAGE\" predict \"/app/$backend\" \"$tagger\" \"/data/$data_file\" $@"
+
+docker run $RUN_ARGS "$LARVATAGGER_IMAGE" predict "/app/$backend" "$tagger" "/data/$data_file" $@
 ;;
 
 	*)
 
-echo "usage: $0 build [--get-backend]"
+echo "usage: $0 build [--stable] [--get-backend]"
 echo "       $0 open <filepath>"
 echo "       $0 import <filepath> [<outputfilename>] [--id=<runid>] [--framerate=<fps>]"
-echo "       $0 train <backendpath> <datarepository> <taggername>"
-echo "       $0 predict <backendpath> <taggername> <datafile>"
+echo "       $0 train <datarepository> <taggername> [--backend <name>]"
+echo "       $0 predict <datafile> [--backend <name>] [--model-instance <taggername>]"
 echo 'see also `larvatagger.jl --help` for more arguments'
+echo '`larvatagger.jl` arguments must come after the above mentioned arguments'
 ;;
 
 esac
diff --git a/src/Taggers.jl b/src/Taggers.jl
index 22de6b00be453a7d8e6437d76435e918a791af61..cb1b637d9cc0ab69aca742b8cff18d6b9dc1ab16 100644
--- a/src/Taggers.jl
+++ b/src/Taggers.jl
@@ -110,12 +110,12 @@ end
 
 Attempt to fix file ownership.
 This is useful in a Docker container that runs as root.
-Environment variables IO_UID and IO_GID are set in the container by the larvatagger.sh script
+Environment variables HOST_UID and HOST_GID are set in the container by the larvatagger.sh script
 so that the actual user is known.
 """
 function check_permissions(file)
     try
-        uid, gid = ENV["IO_UID"], ENV["IO_GID"]
+        uid, gid = ENV["HOST_UID"], ENV["HOST_GID"]
         @info "Changing file ownership" uid gid file
         chown(file, parse(Int, uid), parse(Int, gid))
     catch
diff --git a/src/cli.jl b/src/cli.jl
index 914f26707efaecca78cbce845eb29e96c778a2fc..26c02376afe005b049503b399b6034333e04bb34 100644
--- a/src/cli.jl
+++ b/src/cli.jl
@@ -8,7 +8,7 @@ usage = """Larva Tagger.
 Usage:
   larvatagger.jl import <input-path> [<output-file>] [--id=<id>] [--framerate=<fps>]
   larvatagger.jl open <file-path> [--backends=<path>] [--port=<number>] [--quiet] [--viewer] [--browser]
-  larvatagger.jl train <backend-path> <data-path> <model-instance> [--pretrained-model=<instance>] [--labels=<comma-separated-list>] [--sample-size=<N>]
+  larvatagger.jl train <backend-path> <data-path> <model-instance> [--pretrained-model=<instance>] [--labels=<comma-separated-list>] [--sample-size=<N>] [--layers=<L>]
   larvatagger.jl predict <backend-path> <model-instance> <data-path> [--skip-make-dataset]
   larvatagger.jl -h | --help
 
@@ -23,6 +23,7 @@ Options:
   --browser            Automatically open a browser tab at the served location.
   --skip-make-dataset  Skip the make_dataset stage; makes `predict` faster.
   --sample-size=<N>    Sample only N track segments from the data repository.
+  --layers=<L>         (MaggotUBA) Number of layers of the classifier.
   --labels=<comma-separated-list>  Comma-separated list of behavior tags/labels.
   --pretrained-model=<instance>    Name of the pretrained encoder (from `pretrained_models` registry).
 
@@ -88,10 +89,14 @@ function main(args=ARGS)
         tagger = Tagger(parsed_args["<backend-path>"], parsed_args["<model-instance>"])
         Taggers.reset(tagger)
         Taggers.push(tagger, parsed_args["<data-path>"])
+        kwargs = Dict{Symbol, Any}()
+        layers = parsed_args["--layers"]
+        isnothing(layers) || (kwargs[:layers] = layers)
         train(tagger;
               pretrained_instance=parsed_args["--pretrained-model"],
               labels=parsed_args["--labels"],
               sample_size=parsed_args["--sample-size"],
+              kwargs...
              )
     elseif parsed_args["predict"]
         tagger = Tagger(parsed_args["<backend-path>"], parsed_args["<model-instance>"])