DEV Community

Cover image for 10 Best Practices for Writing Maintainable Docker Compose Files
Wallace Freitas
Wallace Freitas

Posted on

9

10 Best Practices for Writing Maintainable Docker Compose Files

For developers working with multi-container applications, Docker Compose is a necessary tool. Web servers, databases, caches, and other related services can be defined and managed more easily with its help. However, your docker-compose.yml files can also become more sophisticated as your applications evolve. Creating maintainable Compose files guarantees that your project will continue to be simple to oversee, debug, and grow over time. Ten best practices that can assist you in producing dependable, scalable, and clean Docker Compose files will be discussed in this post.

1. Use Versioning Properly

πŸ‘‰πŸ» Specify the version field at the top of your Compose file to ensure compatibility.

πŸ‘‰πŸ» Use the latest stable version (e.g., version: "3.9") unless constrained by project requirements.

version: "3.9"
services:
  web:
    image: node:20
Enter fullscreen mode Exit fullscreen mode

2. Keep Services Modular and Purpose-Driven

πŸ‘‰πŸ» Each service should do one thing well (e.g., one for Node.js API, another for PostgreSQL).

πŸ‘‰πŸ» Avoid combining unrelated functionality into a single service to make debugging easier.

3. Use Named Volumes for Data Persistence

πŸ‘‰πŸ» Named volumes ensure that data persists across container restarts.

πŸ‘‰πŸ» Place volumes at the bottom of the file for better readability.

services:
  db:
    image: postgres:15
    volumes:
      - db_data:/var/lib/postgresql/data

volumes:
  db_data:
Enter fullscreen mode Exit fullscreen mode

4. Leverage Environment Variables

πŸ‘‰πŸ» Use environment variables for configuration, especially for secrets and service settings.

πŸ‘‰πŸ» Use .env files to avoid hardcoding sensitive information in the Compose file.

services:
  api:
    image: node:20
    environment:
      - NODE_ENV=production
      - DB_HOST=${DB_HOST}
Enter fullscreen mode Exit fullscreen mode

5. Define Networks Explicitly

πŸ‘‰πŸ» Use custom networks to manage how services communicate.

πŸ‘‰πŸ» Isolate services to prevent unintended access between them.

networks:
  frontend:
  backend:

services:
  web:
    networks:
      - frontend
  db:
    networks:
      - backend
Enter fullscreen mode Exit fullscreen mode

6. Use Dependencies Carefully

πŸ‘‰πŸ» Avoid strict dependencies when possible to reduce complexity.

πŸ‘‰πŸ» Use depends_on when startup order is critical but consider alternatives like health checks.

services:
  web:
    depends_on:
      - db
Enter fullscreen mode Exit fullscreen mode

7. Apply Resource Limits (CPU & Memory)

πŸ‘‰πŸ» Set resource constraints to prevent any service from monopolizing system resources.

services:
  api:
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: "1.0"
Enter fullscreen mode Exit fullscreen mode

8. Use Profiles to Manage Development vs Production Configs

πŸ‘‰πŸ» Profiles allow you to enable or disable services based on the environment.

services:
  debug:
    image: busybox
    profiles:
      - debug
Enter fullscreen mode Exit fullscreen mode
docker-compose --profile debug up
Enter fullscreen mode Exit fullscreen mode

9. Separate Configuration with Multiple Compose Files

πŸ‘‰πŸ» Split configuration into multiple files (docker-compose.dev.yml, docker-compose.prod.yml) for different environments.

docker-compose -f docker-compose.yml -f docker-compose.prod.yml up
Enter fullscreen mode Exit fullscreen mode

10. Document Your Compose Files

πŸ‘‰πŸ» Add comments to clarify configurations and make it easier for team members to understand.

# Web service running Node.js API
services:
  api:
    image: node:20
Enter fullscreen mode Exit fullscreen mode

Conclusion

Keeping your docker-compose.yml files scalable and unambiguous guarantees that your services will continue to be simple to administer during development and deployment. Your Docker-based apps will be more maintainable and scalable if you adhere to these best practices, which include resource restrictions, environment variables, and modular services. These guidelines will also aid in troubleshooting and swiftly onboarding new team members as your project expands.y.

Image of AssemblyAI tool

Transforming Interviews into Publishable Stories with AssemblyAI

Insightview is a modern web application that streamlines the interview workflow for journalists. By leveraging AssemblyAI's LeMUR and Universal-2 technology, it transforms raw interview recordings into structured, actionable content, dramatically reducing the time from recording to publication.

Key Features:
πŸŽ₯ Audio/video file upload with real-time preview
πŸ—£οΈ Advanced transcription with speaker identification
⭐ Automatic highlight extraction of key moments
✍️ AI-powered article draft generation
πŸ“€ Export interview's subtitles in VTT format

Read full post

Top comments (1)

Collapse
 
jangelodev profile image
JoΓ£o Angelo β€’

Hi Wallace Freitas,
Thanks for sharing.

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

πŸ‘‹ Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay