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.env.<CONTAINER_NAME>
(e.g..env.gitea
) 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.db
├── .env.gitea
├── .env.tunnel
├── docker-compose.yml
├── start.sh
└── volumes/
├── gitea_config/
│ └── ...
├── gitea_data/
│ └── ...
└── postgres_data/
└── ...
See Cloudflare Tunnel Configuration for instructions on how to configure a tunnel and get a tunnel token.
Gitea
.env.db
POSTGRES_USER=gitea
POSTGRES_PASSWORD=gitea
POSTGRES_DB=gitea
.env.gitea
GITEA__database__DB_TYPE=mysql
GITEA__database__HOST=db:3306
GITEA__database__NAME=gitea
GITEA__database__USER=gitea
GITEA__database__PASSWD=gitea
.env.tunnel
TUNNEL_TOKEN=abc...
docker-compose.yml
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
depends_on:
- gitea # Ensure dependencies start in the correct order.
networks:
- frontend # Use multiple networks to isolate services.
env_file:
- .env.tunnel # Use environment variables loaded via a .env file for tokens.
gitea:
image: gitea/gitea:1.21-rootless
restart: unless-stopped
healthcheck: # Use healthchecks if possible.
test: curl --fail http://localhost:3000/api/healthz || exit 1
interval: 60s
retries: 5
start_period: 20s
timeout: 10s
depends_on:
- db
networks:
- frontend
- backend
volumes:
- './volumes/gitea_data:/var/lib/gitea' # Mount volumes into the ./volumes directory.
- './volumes/gitea_config:/etc/gitea' # Relative volumes must be wrapped in single quotes.
- '/etc/timezone:/etc/timezone:ro' # Mount timezone/localtime so that timestamps are correct.
- '/etc/localtime:/etc/localtime:ro'
env_file:
- .env.gitea
db:
image: postgres:14
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready", "-d", "db_prod"]
interval: 60s
retries: 5
start_period: 20s
timeout: 10s
networks:
- backend
volumes:
- './volumes/postgres_data:/var/lib/postgresql/data'
env_file:
- .env.db
networks:
backend:
frontend:
No Comments