I was learning about docker compose pull and why the docker-compose.yml on Rodan was getting images from Docker Hub instead of locally building. After a chat with GitHub Copilot, I get this nice document:
Best Practices: Docker Compose in CI/CD
1. Use Compose for Local and Test Environments
- Use
docker-compose.yml to define multi-container environments for local dev, integration, and end-to-end (E2E) testing.
- For production, use Compose only if you fully understand its limitations; otherwise, consider Docker Swarm, Kubernetes, or similar orchestrators.
2. Separate Environment Files
- Use different Compose files for different stages:
docker-compose.yml (base)
docker-compose.override.yml (local/dev)
docker-compose.ci.yml (CI-specific settings)
- Example:
docker-compose -f docker-compose.yml -f docker-compose.ci.yml up --build
3. Build & Test Images in CI
- Build your images as part of the CI process using Docker Compose:
docker-compose build
docker-compose up -d
- Run tests against running containers.
- Clean up after tests with
docker-compose down --volumes.
4. Use Tagged Images for Deployment
- After successful tests, tag and push the images to a registry (Docker Hub, GHCR, etc.).
- Never deploy "latest" or untagged images; always use immutable tags (e.g., git SHA or release version).
5. Avoid Exposing Ports in CI
- Internal service-to-service communication doesn’t require exposed ports.
- Only expose ports if your tests need to access services from outside the Docker network.
6. Inject Secrets Securely
- Use CI/CD secrets management to inject environment variables.
- Do NOT store secrets in Compose files or the repo.
7. Use Healthchecks
- Define
healthcheck for each service in Compose to ensure tests only run when services are ready.
8. Clean Up Resources
- Always shut down containers, networks, and volumes after CI jobs to avoid resource leaks:
docker-compose down --volumes
9. Sample CI Workflow (GitHub Actions)
name: CI
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Run Compose
run: |
docker-compose -f docker-compose.yml -f docker-compose.ci.yml up --build -d
- name: Run Tests
run: |
docker-compose exec -T app pytest
- name: Tear Down
run: |
docker-compose down --volumes
10. Pin Compose Version in CI
- Use a specific Docker Compose version in your CI environment to avoid unexpected behavior due to updates.
References
I was learning about
docker compose pulland why thedocker-compose.ymlon Rodan was getting images from Docker Hub instead of locally building. After a chat with GitHub Copilot, I get this nice document:Best Practices: Docker Compose in CI/CD
1. Use Compose for Local and Test Environments
docker-compose.ymlto define multi-container environments for local dev, integration, and end-to-end (E2E) testing.2. Separate Environment Files
docker-compose.yml(base)docker-compose.override.yml(local/dev)docker-compose.ci.yml(CI-specific settings)3. Build & Test Images in CI
docker-compose down --volumes.4. Use Tagged Images for Deployment
5. Avoid Exposing Ports in CI
6. Inject Secrets Securely
7. Use Healthchecks
healthcheckfor each service in Compose to ensure tests only run when services are ready.8. Clean Up Resources
9. Sample CI Workflow (GitHub Actions)
10. Pin Compose Version in CI
References