Docker Deployment
July 8, 2026 ยท View on GitHub
Build the BisQue app image:
BISQUE_DOCKER_TAG=dev just docker-build
just docker-build builds the reusable Flox environment image first when
BISQUE_ENV_IMAGE does not already exist, then builds the runnable BisQue app
image from deploy/docker/Dockerfile.
The equivalent manual build is:
docker build \
-f deploy/docker/Dockerfile \
--build-arg BISQUE_ENV_IMAGE=bisque:env \
-t bisque:local .
bisque:env is the reusable Flox environment image. bisque:local is the
locally built BisQue app image used by Compose and the k3s examples; set
BISQUE_ENV_IMAGE or BISQUE_IMAGE when you want to use a registry or
production tag instead.
The app image build runs uv sync, installs the converter wrappers, and bakes
static asset links into /app/public. Container startup only prepares runtime
config/data, renders legacy config files from environment variables, runs the
idempotent BisQue setup steps, and starts BisQue.
Bio-Formats is excluded from the Docker image by default because it is GPL
licensed. For a private/local image that intentionally bundles Bio-Formats, add
--build-arg BISQUE_INSTALL_BIOFORMATS=1 to the app image build.
Run the compose stack with nginx in front:
cp .env.example .env
# edit .env for local ports, secrets, site metadata, or SMTP if needed
docker compose -f deploy/docker/compose.yml up --build
The compose stack starts nginx, BisQue, and Postgres. BisQue uses Postgres by
default in compose, while direct local Flox runs still default to SQLite unless
BISQUE_DBURL is set. Postgres must be healthy before BisQue starts, and nginx
waits for BisQue's HTTP healthcheck before accepting traffic.
Compose uses the same env-first config generator as local development. It reads
the root .env in two ways: Compose uses it for ${...} interpolation, and the
BisQue service also receives it through env_file. Explicit values in
deploy/docker/compose.yml override .env for container-only settings such as
/app/.bisque runtime paths, /app/public static assets, and the in-container
HTTP port.
The most important production settings are:
BISQUE_DBURL=postgresql://bisque:bisque@postgres:5432/bisque
BISQUE_SECRET=replace-me
BISQUE_HTTP_PORT=8080
BISQUE_DEBUG=false
BISQUE_JS_ENVIRONMENT=production
Compose defaults to deployment-style debug settings; set BISQUE_DEBUG=true
and BISQUE_JS_ENVIRONMENT=development in .env only when debugging the
containerized app.
Leave BISQUE_PUBLIC_URL unset for normal compose runs. Compose defaults it to
http://127.0.0.1:${BISQUE_HTTP_PORT}, matching the host port published by
nginx. Docker-backed module containers receive rewritten callback URLs through
BISQUE_DOCKER_CALLBACK_URL, which defaults to
http://host.docker.internal:${BISQUE_HTTP_PORT}. Use
http://localhost:${BISQUE_HTTP_PORT} or the machine's IP address in the
browser.
Startup writes generated config under the bisque-runtime volume at
.bisque/config. Changed generated files are backed up before they are
rewritten, but production secrets should still be supplied from the deployment
environment rather than edited into generated files. Static assets are not
linked during container startup; /app/public is immutable image content while
/app/.bisque remains mutable runtime state.
Large uploads through compose use nginx's X-File handoff path. nginx writes
request bodies into the shared bisque-upload-tmp volume and BisQue reads the
same path from its container.
The compose stack stores BisQue runtime config/data/log state in the
bisque-runtime volume and database state in the postgres-data volume.
Docker-backed module execution uses the host Docker daemon through
/var/run/docker.sock, which is mounted into the bisque service. The app image
inherits the Docker CLI from the Flox environment for module launchers. For local
module images, compose sets BISQUE_DOCKER_HUB to empty by default so module
image names are used exactly as written in each runtime-module.cfg.
On Linux, generated module launchers use host networking and add
host.docker.internal as a host-gateway alias so module callback URLs resolve
inside the spawned module container.
Build the EdgeDetection module image before running that module:
docker build \
-f source/modules/EdgeDetection/Dockerfile \
-t edgedetection:v1.0.0 \
source/modules/EdgeDetection