Skip to content

Docker Compose Operations: Secrets, Limits, Logs, and Updates

This walkthrough builds a small, runnable PostgreSQL lab so you can practice common Docker Compose operations. It demonstrates a persistent volume, health check, resource limits, bounded logs, and file-backed secrets.

This is a local learning stack, not a production-ready deployment. For production, use a platform-appropriate secret manager, tested off-host backups, reviewed image versions, monitoring, and a documented recovery plan. The database port below is bound to localhost only. The example uses a moving major-version tag for convenience; production deployments should pin and review the exact approved image digest.


Step 1: Define the Compose Service

01

Create a PostgreSQL Compose Service

Compose File

Make a project directory such as compose-lab and save this file there as compose.yaml. The stack will be ready to start after Step 2 creates the secret files. The resource limits and log rotation are set on this Compose service.

services:
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: compose_lab
POSTGRES_USER_FILE: /run/secrets/db_user
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_user
- db_password
volumes:
- db_data:/var/lib/postgresql/data
ports:
- "127.0.0.1:5432:5432"
healthcheck:
test: ["CMD", "pg_isready", "-U", "compose_lab_user", "-d", "compose_lab"]
interval: 10s
timeout: 5s
retries: 5
start_period: 15s
mem_limit: 1g
cpus: 1.0
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
volumes:
db_data:
secrets:
db_user:
file: ./secrets/db_user.txt
db_password:
file: ./secrets/db_password.txt

Step 2: Create and Protect File-Backed Secrets

02

Create Local Secret Source Files

Credentials

Run these commands from the project directory containing compose.yaml. Compose grants the files to the database service at /run/secrets/. With a file: source, the files remain on the host; this is not the encrypted, in-memory secret store used by Docker Swarm. Keep the source files out of version control and restrict host access.

Terminal window
mkdir -p secrets
umask 077
printf '%s' 'compose_lab_user' > secrets/db_user.txt
openssl rand -base64 32 > secrets/db_password.txt
chmod 0600 secrets/db_user.txt secrets/db_password.txt
# Add this line to the project's .gitignore.
printf '%s\n' '/secrets/' >> .gitignore
❯ View Expected Console Output
$ ls -l secrets
-rw------- 1 user user 16 Oct 5 10:00 db_user.txt
-rw------- 1 user user 45 Oct 5 10:00 db_password.txt

Step 3: Validate and Start the Stack

03

Start the Database and Check Its Health

Deployment

Validate the resolved Compose configuration before starting the service. Then wait for its health check and confirm the published port is limited to the local machine. β€”wait is available in recent Docker Compose v2 releases; if your version does not support it, check docker compose ps until the health status is healthy.

Terminal window
docker compose config
docker compose up -d --wait
docker compose ps
docker compose exec db pg_isready \
-U "$(cat secrets/db_user.txt)" -d compose_lab
❯ View Expected Console Output
NAME IMAGE STATUS PORTS
compose-lab-db-1 postgres:16-alpine Up 20 seconds (healthy) 127.0.0.1:5432->5432/tcp
/var/run/postgresql:5432 - accepting connections

Step 4: Inspect Logs and Resource Use

04

Check Bounded Logs and Container Resources

Operations

The Compose service sets a maximum log file size and retention count. Inspect recent output and actual runtime resource use; limits constrain the container but do not prove that the database has enough capacity for its workload.

Terminal window
docker compose logs --tail=50 db
docker stats --no-stream
❯ View Expected Console Output
CONTAINER ID NAME CPU % MEM USAGE / LIMIT
... compose-lab-db-1 0.20% 82MiB / 1GiB

Step 5: Apply Image Updates Deliberately

05

Review and Roll Out an Approved Image Update

Maintenance

Do not automatically replace database images without checking the version and recovery plan. Before an approved update, take and verify a database backup, review the target image, and schedule any expected restart. A database major-version change may require a documented migration; changing the image tag alone is not that migration. This example does not promise a zero-downtime update. The Watchtower project is archived; use a maintained and reviewed update process instead.

Terminal window
# Review the current service and image reference.
docker compose ps
docker compose images
# After updating the approved image reference in compose.yaml:
docker compose pull db
docker compose up -d --wait db
docker compose ps
docker compose logs --tail=100 db
❯ View Expected Console Output
The database service is healthy after the planned restart.

Comments