Configure Docker apps¶
Important
When using Docker, configure an external firewall.
Note
This guide works with existing images. See the Software Development Handbook for how to build images from a Dockerfile using GitHub Actions.
See also
The docker_apps
state file performs common operations for apps deployed using Docker Compose. In your app’s state file, include it with:
include:
- docker_apps
If you already have an include
state, add docker_apps
to its list.
This will:
Install the Docker service
Configure Docker¶
One-time setup
Do this only once per server.
Add - docker
to the server’s entry in the pillar/top.sls
file.
In the server’s Pillar file, add, for example:
docker:
user: deployer
syslog_logging: True
This will:
Add a non-root user to the
docker
groupConfigure container logs to be written to
/var/log/docker-custom/CONTAINER_NAME.log
, with rotation
Add Docker Compose file¶
Create an {app}.yaml
file in the salt/docker_apps/files directory. For example:
services:
web:
image: "ghcr.io/open-contracting/myrepo:latest"
restart: unless-stopped
Validate the file, for example:
docker compose config -q salt/docker_apps/files/registry.yaml
Stateful containers
Containers are designed to be interrupted at any time, whereas stateful services like PostgreSQL and RabbitMQ can fail in such conditions. Instead, run these on the host, where they are easier to operate with high reliability.
One-off commands
To run a one-off command, like a database migration, use docker compose run on the command line, instead of creating a one-time container. See Docker tasks for examples.
If you need to run a scheduled task in a cron job, use docker compose --progress=quiet run --rm --name my-app-cron
, replacing my-app
. If needed, change the log level by adding -e LOG_LEVEL=WARNING
, for example.
Confirm the meaning of a cron expression using Cronhub.
Shared configuration
To share configuration between services, you can use this pattern:
x-shared: &shared
image: "ghcr.io/open-contracting/myrepo:latest"
restart: unless-stopped
services:
web:
<<: *shared
worker:
<<: *shared
command: "python -m worker"
deploy:
replicas: 2
Reference:
Configure Docker app¶
In the server’s Pillar file, add, for example:
docker_apps:
myapp:
target: mytarget
env:
FATHOM_ANALYTICS_ID: ABCDEFGH
In the server’s private Pillar file, add, for example:
docker_apps:
myapp:
env:
SENTRY_DSN: https://1234567890abcdef1234567890abcdef@o123456.ingest.sentry.io/1234567890123456
This will create files in the /data/deploy/mytarget
directory:
docker-compose.yaml
, with the contents of thesalt/docker_apps/files/myapp.yaml
file.env
, containing the values under theenv
key
To reuse a Docker Compose file, specify the configuration, which otherwise defaults to the app’s name. For example:
docker_apps:
cove_ocds:
configuration: cove # default cove_ocds
target: cove-ocds
cove_oc4ids:
configuration: cove # default cove_oc4ids
target: cove-oc4ids
See also
Environment variables for Django projects
Reference:
Use host services¶
To connect to the host’s services, like PostgreSQL or RabbitMQ, add to the Docker Compose file:
services:
web:
image: "ghcr.io/open-contracting/myrepo:latest"
restart: unless-stopped
extra_hosts:
- "host.docker.internal:host-gateway"
Then, under the env
key in the server’s Pillar file, use host.docker.internal
instead of localhost
. For example:
docker_apps:
myapp:
target: mytarget
env:
DATABASE_URL: "postgresql://USERNAME:PASSWORD@host.docker.internal:5432/name"
Reference:
Map a port¶
If the Dockerfile exposes a port, in the server’s Pillar file, add, for example:
docker_apps:
myapp:
target: mytarget
port: 8001
env:
MYVAR: myvalue
This makes it easier for multiple Docker Compose files to refer to the port.
Then, in the Docker Compose file, add, for example:
services:
web:
image: "ghcr.io/open-contracting/myrepo:latest"
restart: unless-stopped
ports:
- {{ entry.port }}:8000
Alternatively, if port
is already set in the context
of an Apache site, do: {{ site.port }}
Add a bind mount¶
See the last step for Bind mounts in the Software Development Handbook.
Configure Apache¶
Apache is used as a reverse proxy to any web servers in the Docker containers. See Configure Apache. The configuration can simply be ProxyPass
directives.
Additional files¶
Setup¶
Create additional files needed to setup the service (e.g. SQL migrations) in the /data/deploy/TARGET/files
directory.
Use¶
Create additional files needed to use the service (e.g. sudoer binaries) in the /opt
or /opt/TARGET
directory.