DEV Community

SOVANNARO
SOVANNARO

Posted on • Edited on

πŸš€ Full App Lifecycle: Dev, Build & Deploy With a Single Docker Compose Design

When building modern apps, we often juggle multiple environments: development, build pipelines, staging, and production. Wouldn’t it be great to handle them all with a single, unified docker-compose.yml file? Yes, it’s possibleβ€”and powerful!

This article walks you through creating a Compose file that works across the full lifecycle of your application: local development, building, testing, and deployingβ€”even to production with Docker Swarm. Let’s go!


πŸ” Why Use a Single Compose Design?

Managing multiple Compose files (docker-compose.override.yml, docker-compose.prod.yml, etc.) gets messy fast.

Instead, we can:

  • Keep one main docker-compose.yml file.
  • Use profiles, build contexts, and secrets.
  • Control behavior with CLI flags or environment variables.

πŸ—οΈ The App Structure

Let’s imagine a simple full-stack app:

my-app/ β”œβ”€β”€ backend/ (Spring Boot) β”œβ”€β”€ frontend/ (React + Vite) β”œβ”€β”€ nginx/ (Reverse Proxy) β”œβ”€β”€ docker-compose.yml β”œβ”€β”€ .env 
Enter fullscreen mode Exit fullscreen mode

🧠 Compose Design Overview

Here’s what we want in our single Compose file:

  • Profiles to separate dev-only services (like hot reloading).
  • Build contexts to build images during CI or locally.
  • Secrets and configs for secure production-ready deployment.
  • Deploy block for Swarm mode.

πŸ§ͺ Development Stage

services: backend: build: context: ./backend ports: - "8080:8080" volumes: - ./backend:/app profiles: ["dev"] frontend: build: context: ./frontend ports: - "5173:5173" volumes: - ./frontend:/app profiles: ["dev"] 
Enter fullscreen mode Exit fullscreen mode

Run development services:

docker compose --profile dev up 
Enter fullscreen mode Exit fullscreen mode

πŸ—οΈ Build Stage (CI/CD or Local Image Build)

Still using the same file, just with the build option:

 backend: build: context: ./backend image: my-backend:latest frontend: build: context: ./frontend image: my-frontend:latest 
Enter fullscreen mode Exit fullscreen mode

Then build with:

docker compose build 
Enter fullscreen mode Exit fullscreen mode

Or push to a registry:

docker compose build && docker compose push 
Enter fullscreen mode Exit fullscreen mode

πŸš€ Deploy Stage (Swarm or Production)

You can use the same Compose file with Docker Swarm:

services: backend: image: my-backend:latest deploy: replicas: 2 resources: limits: cpus: '0.5' memory: 512M secrets: - db_password frontend: image: my-frontend:latest deploy: replicas: 1 nginx: image: nginx:latest ports: - "80:80" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf 
Enter fullscreen mode Exit fullscreen mode

Initialize Swarm:

docker swarm init 
Enter fullscreen mode Exit fullscreen mode

Deploy the stack:

docker stack deploy -c docker-compose.yml myapp 
Enter fullscreen mode Exit fullscreen mode

πŸ” Add Secrets (For Production)

secrets: db_password: file: ./secrets/db_password.txt 
Enter fullscreen mode Exit fullscreen mode

Use in backend:

services: backend: ... secrets: - db_password 
Enter fullscreen mode Exit fullscreen mode

⚑ Environment Variables for Flexibility

Use a .env file to switch behavior:

NODE_ENV=development FRONTEND_PORT=5173 
Enter fullscreen mode Exit fullscreen mode

In Compose:

frontend: ports: - "${FRONTEND_PORT}:5173" 
Enter fullscreen mode Exit fullscreen mode

βœ… Benefits of This Pattern

  • One file to rule them all.
  • No more config drift between dev/staging/prod.
  • Can scale from local dev to cloud deployment.
  • Great for teams and CI pipelines.

🎁 Final Tips

  • Use --profile to enable/disable services.
  • Use docker-compose.override.yml only for personal overrides, not team-wide differences.
  • Secure your secrets and configs!
  • Combine with GitHub Actions or GitLab CI for automatic deploys.

🏁 Conclusion

A well-designed, unified docker-compose.yml can streamline your entire app lifecycleβ€”from development to production. With smart use of profiles, secrets, and Swarm deployment blocks, you no longer need to duplicate configs or maintain complex scripts.

This pattern makes Docker work for you, not the other way around. πŸ³πŸ’™

Top comments (0)