Docker works natively on Linux, macOS, and Windows through Docker Engine or
Docker Desktop. These instructions assume Docker Compose v2, which is invoked
as docker compose.
Docker Compose starts the required PostgreSQL/PostGIS/TimescaleDB and Redis containers. Developers do not need to install PostgreSQL, PostGIS, TimescaleDB, or Redis on the host machine.
Before building, initialize the Angular UI submodule:
git submodule update --init ng_seed/seed-angularThe Dockerfiles install Python with uv and use Node 24 with pnpm through
Corepack. The development image also builds the Angular UI assets that Django
serves from /ng-app/.
Follow instructions here.
- Install Docker Compose if your Docker installation does not already include Compose v2.
Follow instructions for Mac or for Windows. Docker Desktop includes Compose v2.
On Windows, use Docker Desktop with the WSL 2 backend. Run repository commands from a WSL 2 shell when you need Linux-compatible paths or shell behavior.
The Docker Compose database service uses timescale/timescaledb-ha:pg18.3-ts2.26.4-oss.
The Redis service uses redis:8-alpine.
The image's default PGDATA directory is /home/postgres/pgdata/data; compose mounts the
seed_pgdata volume at /home/postgres/pgdata so the container can manage its data
subdirectory.
Existing volumes from older major Postgres versions cannot be started directly
with this image. If you need to keep data from an older Postgres volume, follow
the dump/restore process in :doc:`postgres_upgrade` before starting Postgres 18.
If you do not need the old data, recreate the database volume instead.
Run Docker Compose
docker compose build
Be Patient ... If the containers build successfully, then start the containers
docker volume create --name=seed_pgdata docker volume create --name=seed_media docker compose up
Note that you may need to build the containers a couple times for everything to converge
Login to container
The Docker Compose file creates a default user and password. Below are the defaults but can be overridden by setting environment variables.
username: user@seed-platform.org password: super-secret-password
Note
Don't forget that you need to reset your default username and password if you are going to use these Docker images in production mode!
The development environment is configured for live reloading and debugging. It
builds from Dockerfile-dev and layers docker-compose.dev.yml on top of
the base docker-compose.yml.
# create volumes for the database and media directory
docker volume create --name=seed_pgdata
docker volume create --name=seed_media
# initialize the Angular UI submodule
git submodule update --init ng_seed/seed-angular
# build the images
docker compose -f docker-compose.yml -f docker-compose.dev.yml buildNOTE: the server config is sourced from config.settings.docker_dev, which will include your local_untracked.py if it exists. If you have a local_untracked.py, make sure it doesn't overwrite the database or celery configuration!
docker compose -f docker-compose.yml -f docker-compose.dev.yml upThe AngularJS application is available at http://localhost/app/. To see the
new Angular application at http://localhost/ng-app/, build the Angular
assets and launch the container stack.
The health check is available at http://localhost/api/health_check/. A
healthy container stack returns 200 OK with postgres, redis, and
celery all set to success. If the endpoint returns 418 I'm a Teapot,
one of the required services is not connected; the JSON response identifies the
failing service.
If the server doesn't start successfully, and docker compose logs doesn't help,
the Hypercorn dev server probably failed to start due to an error in your config or code.
Unfortunately docker application logging doesn't appear to work when the container is first started.
Just try running the server yourself with docker exec, and see what the output is.
The development Docker Compose file has some configurable parameters for specifying volumes to use:
- SEED_DB_VOLUME: the name of the docker volume to mount for postgres
- SEED_MEDIA_VOLUME: the name of the docker volume to mount for the seed media folder
Docker will use environment variables from the shell or from a .env file to set these values.
This is useful if you want to switch between different databases for testing. For example, if you want to create a separate volume for storing a production backup, you could do the following
docker volume create --name=seed_pgdata_prod
SEED_DB_VOLUME=seed_pgdata_prod docker compose -f docker-compose.yml -f docker-compose.dev.yml upNOTE: you'll need to run docker compose down to remove the containers before you
can restart the containers connecting to different volumes.
While the containers are running (i.e., after running the docker compose up command), use docker exec to run tests in the web container:
docker exec -it seed_web uv run manage.py test --settings config.settings.docker_testAdd the setting --nocapture in order to see stdout while running tests. You will need to do this in order to make use of debugging as described below or the output to your debug commands will not display until after the break point has passed and the tests are finished.
Also worth noting: output from logging (_log.debug, etc) will not display in any situation unless a test fails.
To use pdb on the server, the web container has remote-pdb installed. In your code, insert the following
import remote_pdb; remote_pdb.set_trace()Once the breakpoint is triggered, you should see the web container log something like "RemotePdb session open at 127.0.0.1:41653, waiting for connection ...". To connect to the remote session, run netcat from inside the container (using the appropriate port).
docker exec -it seed_web nc 127.0.0.1:41653The dev image includes debugpy and the web container publishes port 5678 on localhost, so you can set breakpoints in VS Code and attach to a process running in the container. Rebuild the image and recreate the containers after pulling these changes.
Add the following configuration to .vscode/launch.json (.vscode is git-ignored, so this is a local file):
{
"name": "Docker: Attach to seed_web (debugpy)",
"type": "debugpy",
"request": "attach",
"connect": {"host": "localhost", "port": 5678},
"pathMappings": [
{"localRoot": "${workspaceFolder}/seed", "remoteRoot": "/seed/seed"},
{"localRoot": "${workspaceFolder}/config", "remoteRoot": "/seed/config"}
],
"django": true,
"justMyCode": false
}Then:
Set a breakpoint in a file under
seed/.Start a process in the container that waits for the debugger, for example a test module:
docker exec -it seed_web python -Xfrozen_modules=off -m debugpy --listen 0.0.0.0:5678 --wait-for-client manage.py test --settings config.settings.docker_test seed.tests.test_benchmark_data_views
In VS Code, run the "Docker: Attach to seed_web (debugpy)" configuration. Execution stops at your breakpoint.
The command blocks until VS Code attaches, and you must attach again every time you start a new process. This approach
is intended for tests and one-off commands such as manage.py shell; it is not reliable for the hypercorn server
because of --reload.