Container
Adapt publishes a container image on every release. This page covers pulling
it, running it against a bind-mounted document root, and the differences
from a local pip install covered in Installation.
Image coordinates and tags
The image is published to GHCR as ghcr.io/mcindi/adapt-server:
ghcr.io/mcindi/adapt-server:<version>— pushed on every release, matching thepyproject.tomlversion (for example0.5.2, the current release)ghcr.io/mcindi/adapt-server:latest— pushed only for non-prerelease releases
Each tag is a multi-arch manifest list covering linux/amd64 and
linux/arm64. Docker and Podman pull the manifest that matches the host
architecture automatically.
docker pull ghcr.io/mcindi/adapt-server:0.5.2
Running the image
The image runs as a non-root user pinned to UID 1000 / GID 1000, and serves
on port 8000 with the default CMD. Bind-mount a document root and publish
the port:
mkdir -p ./docroot
sudo chown 1000:1000 ./docroot # required — see below
docker run -d --name adapt \
-p 8000:8000 \
-v "$(pwd)/docroot:/data" \
ghcr.io/mcindi/adapt-server:0.5.2
Open http://localhost:8000.
The UID 1000 ownership requirement
The container process runs as UID 1000, not root. A bind-mounted directory
that the container cannot write to (for example one owned by root:root, or
by a host user with a different UID) makes Adapt fail immediately, because it
cannot create .adapt/ in the document root:
PermissionError: [Errno 13] Permission denied: '/data/.adapt'
Fix it before starting the container:
sudo chown 1000:1000 ./docroot
If your host user's UID already happens to be 1000 (common on a fresh Linux
desktop or VM install), no chown is needed — the directory is already
writable by that UID.
Creating the first superuser
docker exec -it adapt adapt addsuperuser /data --username admin
The -it flags are required because addsuperuser prompts for the password
interactively; without a TTY the prompt raises EOFError. For scripted or
non-interactive use, pass --password, --password-confirm, and
--allow-weak-password as applicable. Set the password in a shell variable
first — an unquoted <placeholder> on the command line is Bash redirection
syntax, not a value to substitute, and breaks the command:
ADMIN_PASSWORD='choose-your-own-password'
docker exec adapt adapt addsuperuser /data \
--username admin --password "$ADMIN_PASSWORD" --password-confirm "$ADMIN_PASSWORD"
Environment variables
The container reads the same ADAPT_* environment variables as a local
install. Pass them with -e (or --env-file):
docker run -d --name adapt \
-p 8000:8000 \
-v "$(pwd)/docroot:/data" \
-e ADAPT_UPLOAD_ENABLED=true \
-e ADAPT_UPLOAD_MAX_SIZE_BYTES=10485760 \
ghcr.io/mcindi/adapt-server:0.5.2
See Installation → Configuration File for the full variable list and value parsing rules.
Overriding the default command
The image's default CMD is:
adapt serve /data --host 0.0.0.0 --port 8000
Append arguments after the image name to run a different command against the same image, for example to change the port or run a one-off admin command:
docker run --rm -v "$(pwd)/docroot:/data" ghcr.io/mcindi/adapt-server:0.5.2 \
adapt serve /data --host 0.0.0.0 --port 9090
docker run --rm ghcr.io/mcindi/adapt-server:0.5.2 adapt --help
Verifying the image
Inspect the OCI labels a plain docker build or a pulled release image
carries:
docker image inspect ghcr.io/mcindi/adapt-server:0.5.2 --format '{{json .Config.Labels}}'
This includes org.opencontainers.image.version, .source, .revision,
.title, .description, and .licenses.
Inspect the multi-arch manifest list to confirm both platforms are present:
docker buildx imagetools inspect ghcr.io/mcindi/adapt-server:0.5.2
The image also carries a built-in HEALTHCHECK that polls /health every
30 seconds. docker ps shows the container's health status directly:
docker ps --filter name=adapt
Future work: signature verification (cosign/sigstore) and an attached SBOM are not yet part of the publish pipeline — see Phase 3 and milestone M3 in MILESTONES.md.
Kubernetes
Running the same image on Kubernetes, with persistence, service exposure, and an automated superuser bootstrap, is covered in Kubernetes (Helm).
Manual navigation: Previous: Deployment | Index | Next: Kubernetes (Helm)