Docker Compose Template
Guidelines
These guidelines are suggested in order to maximise reliability of hosted services.
- Store secrets and tokens in a
.env
file adjacent to thedocker-compose.yml
file.- The environment variables are automatically interpolated when
docker compose up
is called. - If multiple
.env
files are required (for separation of secrets), then use<CONTAINER_NAME>.env
(e.g.gitea.env
) and add an override in thedocker-compose.yml
file. See the Docker documentation for more details.
- The environment variables are automatically interpolated when
- Always used tagged images.
- Avoid using
latest
. By default, Docker hub automatically tags the most recently pushed image aslatest
, unless overriden by the image maintainer. This means that you might be running bleeding edge/alpha/vulnerable versions. - Often images expect a specific version of a container to be running in order for DB migrations to work. This is especially important with Postgres where major versions are not always forwards compatible.
- Avoid using
- Separate frontend and backend services using different networks.
- Docker Compose manages the creation/destruction of these networks for you. Please see the examples below.
- Volumes should be placed in a volumes directory adjacent the
docker-compose.yml
file.- Prefix volume directories with the name of the container.
- See the directory structure below for an example.
- Mount
/etc/timezone
and/etc/localtime
where timestamps are used by the container.- See below for an example.
An example directory structure is shown below:
.
├── .env
├── docker-compose.yml
├── start.sh
└── volumes/
├── gitea_config/
│ └── ...
├── gitea_data/
│ └── ...
└── postgres_data/
└── ...
Gitea
.env
CLOUDFLARE_TUNNEL_TOKEN=abc...
docker-compose.yml
version: '3'
services:
tunnel:
image: cloudflare/cloudflared:2024.4.0 # Use version tags to ensure only stable software is used.
restart: unless-stopped # This restart command helps with crashing services.
command: tunnel run
networks:
- frontend # Use multiple networks to isolate services.
environment:
- TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN} # Use environment variables loaded via a .env file for tokens.
gitea:
image: gitea/gitea:1.12.10-rootless
restart: unless-stopped
networks:
- frontend
- backend
volumes:
- ./volumes/gitea_data:/var/lib/gitea
- ./volumes/gitea_config:/etc/gitea
- /etc/timezone:/etc/timezone:ro # Mount timezone/localtime so that timestamps are correct.
- /etc/localtime:/etc/localtime:ro
db:
image: postgres:14
restart: unless-stopped
networks:
- backend
volumes:
- ./volumes/postgres_data
environment:
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=gitea
- POSTGRES_DB=gitea
networks:
backend:
frontend: