0

Docker Compose cho dự án thực tế: từ dev đến production

Nhiều tutorial Docker Compose chỉ dừng ở mức "chạy WordPress + MySQL". Nhưng dự án thực tế phức tạp hơn nhiều. Bài này chia sẻ setup mình đang dùng cho production.

Cấu trúc thư mục

project/
├── docker-compose.yml          # Base config
├── docker-compose.dev.yml      # Dev overrides
├── docker-compose.prod.yml     # Prod overrides
├── .env.dev
├── .env.prod
└── services/
    ├── api/
        │   └── Dockerfile
            ├── worker/
                │   └── Dockerfile
                    └── nginx/
                            └── nginx.conf
                            ```
                            
                            ## Base compose file
                            
                            ```yaml
                            services:
                              api:
                                  build: ./services/api
                                      env_file: .env
                                          depends_on:
                                                db:
                                                        condition: service_healthy
                                                            networks:
                                                                  - backend
                                                                  
                                                                    db:
                                                                        image: postgres:16-alpine
                                                                            volumes:
                                                                                  - pgdata:/var/lib/postgresql/data
                                                                                      healthcheck:
                                                                                            test: pg_isready -U postgres
                                                                                                  interval: 5s
                                                                                                        retries: 5
                                                                                                            networks:
                                                                                                                  - backend
                                                                                                                  
                                                                                                                    redis:
                                                                                                                        image: redis:7-alpine
                                                                                                                            networks:
                                                                                                                                  - backend
                                                                                                                                  
                                                                                                                                  volumes:
                                                                                                                                    pgdata:
                                                                                                                                    
                                                                                                                                    networks:
                                                                                                                                      backend:
                                                                                                                                      ```
                                                                                                                                      
                                                                                                                                      ## Dev overrides
                                                                                                                                      
                                                                                                                                      ```yaml
                                                                                                                                      # docker-compose.dev.yml
                                                                                                                                      services:
                                                                                                                                        api:
                                                                                                                                            volumes:
                                                                                                                                                  - ./services/api:/app  # Hot reload
                                                                                                                                                      ports:
                                                                                                                                                            - "8000:8000"
                                                                                                                                                                command: uvicorn main:app --reload --host 0.0.0.0
                                                                                                                                                                
                                                                                                                                                                  db:
                                                                                                                                                                      ports:
                                                                                                                                                                            - "5432:5432"  # Access from host
                                                                                                                                                                            ```
                                                                                                                                                                            
                                                                                                                                                                            Chạy dev: `docker compose -f docker-compose.yml -f docker-compose.dev.yml up`
                                                                                                                                                                            
                                                                                                                                                                            ## Prod overrides
                                                                                                                                                                            
                                                                                                                                                                            ```yaml
                                                                                                                                                                            # docker-compose.prod.yml
                                                                                                                                                                            services:
                                                                                                                                                                              api:
                                                                                                                                                                                  restart: always
                                                                                                                                                                                      deploy:
                                                                                                                                                                                            resources:
                                                                                                                                                                                                    limits:
                                                                                                                                                                                                              memory: 512M
                                                                                                                                                                                                                  logging:
                                                                                                                                                                                                                        driver: json-file
                                                                                                                                                                                                                              options:
                                                                                                                                                                                                                                      max-size: "10m"
                                                                                                                                                                                                                                              max-file: "3"
                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                nginx:
                                                                                                                                                                                                                                                    image: nginx:alpine
                                                                                                                                                                                                                                                        ports:
                                                                                                                                                                                                                                                              - "80:80"
                                                                                                                                                                                                                                                                    - "443:443"
                                                                                                                                                                                                                                                                        volumes:
                                                                                                                                                                                                                                                                              - ./services/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
                                                                                                                                                                                                                                                                                  depends_on:
                                                                                                                                                                                                                                                                                        - api
                                                                                                                                                                                                                                                                                        ```
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        ## Tips từ production
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        1. **Luôn dùng healthcheck** — `depends_on` không đợi service sẵn sàng, chỉ đợi container start
                                                                                                                                                                                                                                                                                        2. **Pin image version** — `postgres:16-alpine`, không phải `postgres:latest`
                                                                                                                                                                                                                                                                                        3. **Giới hạn memory** — Tránh một container ăn hết RAM
                                                                                                                                                                                                                                                                                        4. **Log rotation** — Không set thì log file sẽ phình to vô hạn
                                                                                                                                                                                                                                                                                        5. **Named volumes cho data** — Bind mount chỉ dùng cho dev, production dùng named volume
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        ---
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        Bạn có tips nào khác cho Docker Compose production không? Share nhé!

All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.