Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docker/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
examples/
package/
README.md
docker-bake.hcl
.gitignore
59 changes: 59 additions & 0 deletions docker/Dockerfile
Comment thread
C-Achard marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# syntax=docker/dockerfile:1

ARG PYTORCH_VERSION=2.5.1
ARG CUDA_VERSION=12.4
ARG CUDNN_VERSION=9
ARG DEEPLABCUT_VERSION=3.0.0rc14

# ── core ──────────────────────────────────────────────────────────────────────
FROM pytorch/pytorch:${PYTORCH_VERSION}-cuda${CUDA_VERSION}-cudnn${CUDNN_VERSION}-runtime AS core

ARG DEEPLABCUT_VERSION
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update -yy && \
apt-get install -yy --no-install-recommends \
libgl1 \
libglib2.0-0 \
build-essential \
git \
ffmpeg \
&& rm -rf /var/lib/apt/lists/*

RUN pip install --upgrade pip && \
pip install "deeplabcut[modelzoo,wandb]==${DEEPLABCUT_VERSION}"

# Create pretrained weights directory and make it writable
# (same default as HuggingFaceWeightsMixin in backbones/base.py: Path(__file__).parent / "pretrained_weights")
RUN PRETRAINED=$(python -c "from pathlib import Path; import deeplabcut.pose_estimation_pytorch.models.backbones.base as b; print(Path(b.__file__).parent / 'pretrained_weights')") && \
mkdir -p "$PRETRAINED" && \
chmod a+rwx -R "$PRETRAINED"

RUN mkdir -p /app && chmod a+rwx /app
Comment thread
deruyter92 marked this conversation as resolved.

COPY motd.sh /home/motd.sh
RUN echo "source /home/motd.sh" >> /etc/profile

ENV CUDA_VERSION=${CUDA_VERSION}
ENV PYTORCH_VERSION=${PYTORCH_VERSION}
ENV DEEPLABCUT_VERSION=${DEEPLABCUT_VERSION}

WORKDIR /app

# ── jupyter ───────────────────────────────────────────────────────────────────
# (runs as root intentionally; deeplabcut-docker adds a host-matched user at runtime)
FROM core AS jupyter

ENV NOTEBOOK_TOKEN=deeplabcut

RUN pip install "notebook<7"
Comment thread
deruyter92 marked this conversation as resolved.
EXPOSE 8888
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8888/api/', timeout=3).read()" || exit 1
ENTRYPOINT ["jupyter", "notebook", \
"--no-browser", "--NotebookApp.token=${NOTEBOOK_TOKEN}", "--ip", "0.0.0.0"]

# ── test (CI only, not published to Hub) ─────────────────────────────────────
FROM core AS test

RUN pip install --no-cache-dir pytest
32 changes: 0 additions & 32 deletions docker/Dockerfile.base

This file was deleted.

9 changes: 0 additions & 9 deletions docker/Dockerfile.core

This file was deleted.

9 changes: 0 additions & 9 deletions docker/Dockerfile.jupyter

This file was deleted.

15 changes: 0 additions & 15 deletions docker/Dockerfile.test

This file was deleted.

4 changes: 0 additions & 4 deletions docker/MANIFEST.in

This file was deleted.

69 changes: 39 additions & 30 deletions docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
documentation contains its own user documentation on the provided docker images.**

This repo contains build routines for the following official DeepLabCut docker images:
- `deeplabcut/deeplabcut:${DLC_VERSION}-base-cuda${CUDA_VERSION}-cudnn9`: Base image with DLC
- `deeplabcut/deeplabcut:${DLC_VERSION}-core-cuda${CUDA_VERSION}-cudnn9`: DLC in light mode
- `deeplabcut/deeplabcut:${DLC_VERSION}-jupyter-cuda${CUDA_VERSION}-cudnn9`: DLC with jupyter installed
- `deeplabcut/deeplabcut:latest` — default runtime image (same as the former “core” image)
- `deeplabcut/deeplabcut:latest-jupyter` — Jupyter Notebook server
- `deeplabcut/deeplabcut:${DLC_VERSION}-core-cuda${CUDA_VERSION}` and `...-jupyter-cuda...` — versioned tags

All images come with Python 3.11 installed.
The images are synced to DockerHub: https://hub.docker.com/r/deeplabcut/deeplabcut
Expand Down Expand Up @@ -51,16 +51,15 @@ when calling `docker run`:
deeplabcut-docker bash --gpus all -v /home/john:/home/john
```

You can select which DeepLabCut version and CUDA version to use through the
`DLC_VERSION` and `CUDA_VERSION` environment variables. So to launch a container with
CUDA 12.1 and DLC 3.0.0, you can run:
Use `DLC_VERSION` and `CUDA_VERSION` to select the Hub tag (unset `DLC_VERSION` uses
`latest` / `latest-jupyter`):

```bash
DLC_VERSION=3.0.0 CUDA_VERSION=12.1 deeplabcut-docker bash --gpus all
DLC_VERSION=3.0.0rc14 CUDA_VERSION=12.4 deeplabcut-docker bash --gpus all
```

*Note: Advanced users can also directly download and use the `deeplabcut-docker.sh`
script if this is preferred over a python helper script.*
To use a specific image instead of the default tags, pass `--image repo:tag`.
Make sure that the image supports jupyter notebooks when passing `notebook`.

### Jupyter Notebooks Running on Remote Servers

Expand All @@ -70,6 +69,16 @@ This is straightforward, and there are many resources you can explore on how to
such as [this StackOverflow post](https://stackoverflow.com/a/69244262) or the [Jupyter
Notebook docs](https://jupyter-notebook.readthedocs.io/en/4.x/public_server.html)).

```{warning}
The Jupyter image uses a fixed default access token (deeplabcut) that is publicly
known. Anyone who can reach port 8888 on your machine can execute arbitrary
code in the container. Do not expose port 8888 to the internet (e.g. via
a cloud VM's firewall or a public 0.0.0.0 binding without a reverse proxy).
For local use, bind the port to localhost only (e.g. -p 127.0.0.1:8888:8888)
and use SSH port forwarding to access the server remotely, as described below.
To use a custom token, pass -e NOTEBOOK_TOKEN=<your-token> to docker run
```

This can easily be done with `deeplabcut-docker`. To run a DeepLabCut notebook on a
remote server:

Expand Down Expand Up @@ -99,31 +108,31 @@ the container with the current user instead of root) won't be there.
The `core` image can simply be run by pulling the image and using `docker run`:

```bash
docker pull deeplabcut/deeplabcut:3.0.0-core-cuda11.8-cudnn9
docker run -it --rm --gpus all deeplabcut/deeplabcut:3.0.0-core-cuda11.8-cudnn9
docker pull deeplabcut/deeplabcut:latest
docker run -it --rm --gpus all deeplabcut/deeplabcut:latest
```

The `jupyter` image cannot be run in the same way. Notebook servers cannot be run as
the root user (which can be dangerous) without passing the `--allow-root` option, so
running `docker run deeplabcut/deeplabcut:3.0.0-jupyter-cuda11.8-cudnn9` will lead to an
running `docker run deeplabcut/deeplabcut:latest-jupyter` will lead to an
error (`Running as root is not recommended. Use --allow-root to bypass`). What you can
do (and we do in the `deeplabcut-docker` package) is to build a docker image with the
`jupyter` image as a base. We would recommend doing this for the `core` images as well.
You can create the `Dockerfile`:

```dockerfile
FROM deeplabcut/deeplabcut:3.0.0-jupyter-cuda11.8-cudnn9
FROM deeplabcut/deeplabcut:latest-jupyter
ARG UID
ARG GID
ARG UNAME
ARG GNAME

# Create same user as on the host system
RUN mkdir -p /home
RUN mkdir -p /home/${UNAME}
RUN mkdir -p /app
RUN groupadd -g ${GID} ${GNAME} || groupmod -o -g ${GID} ${GNAME}
RUN useradd -d /home -s /bin/bash -u ${UID} -g ${GID} ${UNAME}
RUN chown -R ${UNAME}:${GNAME} /home
RUN useradd -d /home/${UNAME} -s /bin/bash -u ${UID} -g ${GID} ${UNAME}
RUN chown -R ${UNAME}:${GNAME} /home/${UNAME}
RUN chown -R ${UNAME}:${GNAME} /app
WORKDIR /app

Expand All @@ -146,26 +155,26 @@ docker run -p 127.0.0.1:8889:8888 -it --rm --gpus all my-dlc-image

## For developers

Make sure your docker daemon is running and navigate to the repository root directory.
You can build the images by running
Make sure your Docker daemon is running. From the `docker/` directory, build with
Buildx bake (see `docker-bake.hcl`):

```bash
cd docker
docker buildx bake
```
docker/build.sh build
```

Note that this assumes that you have rights to execute `docker build` and `docker run` commands which requires either `sudo` access or membership in the `docker` group on your local machine. If you are not in the `docker` group, run the script with the environment variable `DOCKER="sudo docker"` set to override the default docker command.

Images can be verified by running
Set `MARK_LATEST=true` when building the primary CUDA variant if you want `latest` /
`latest-jupyter` tags included. Push to Docker Hub (after `docker login`):

```bash
docker buildx bake --push
```
docker/build.sh test
```

Built images can be pushed to DockerHub by running

```
docker/build.sh push
```
Note that this assumes that you have rights to execute `docker build` and `docker run`
commands which requires either `sudo` access or membership in the `docker` group on
your local machine. If you are not in the `docker` group, run `sudo docker buildx bake`
(and `sudo docker buildx bake --push` when pushing) or add your user to the `docker`
group.

## Prerequisites (if you don't have Docker installed already)

Expand Down
Loading
Loading