0

[Java Backend Zero to Hello] BÀI 7.5: DOCKER COMPOSE

Java Backend Zero to Hello

📚 Bài viết thuộc series Java Backend Zero to Hello 📌 Phần: Phase 7: Testing & DevOps Cơ Bản | Bài 75/86


BÀI 7.5: DOCKER COMPOSE

Mục tiêu

  • Sử dụng Docker Compose cho multi-container
  • Cấu hình services, networks, volumes
  • Triển khai full stack application

1. DOCKER COMPOSE LÀ GÌ?

Docker Compose là công cụ định nghĩa và chạy multi-container Docker applications thông qua file YAML.

Lợi ích

  • Khai báo toàn bộ stack trong 1 file
  • Dễ dàng reproduce môi trường
  • Quản lý nhiều service cùng lúc
  • Tích hợp tốt với development

2. CÀI ĐẶT

  • Windows/Mac: Đã có sẵn với Docker Desktop
  • Linux: sudo apt install docker-compose-plugin

3. CẤU TRÚC FILE

version: '3.8'

services:
  service-name:
    image: nginx:latest
    build: .
    ports:
      - "8080:80"
    environment:
      - KEY=value
    volumes:
      - ./data:/data
    depends_on:
      - other-service
    networks:
      - my-network
    restart: always

volumes:
  data:

networks:
  my-network:
    driver: bridge

4. VÍ DỤ: SPRING BOOT + MYSQL + REDIS

4.1 docker-compose.yml

version: '3.8'

services:
  app:
    build: .
    image: myapp:1.0
    container_name: myapp
    ports:
      - "8080:8080"
    environment:
      SPRING_PROFILES_ACTIVE: docker
      SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/mydb?useSSL=false
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: password
      SPRING_DATA_REDIS_HOST: redis
      SPRING_DATA_REDIS_PORT: 6379
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - app-network
    restart: unless-stopped

  db:
    image: mysql:8
    container_name: mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: mydb
    volumes:
      - mysql-data:/var/lib/mysql
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "3306:3306"
    networks:
      - app-network
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    container_name: redis
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
    networks:
      - app-network
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  mysql-data:
  redis-data:

networks:
  app-network:
    driver: bridge

4.2 application-docker.yml

spring:
  datasource:
    url: ${SPRING_DATASOURCE_URL}
    username: ${SPRING_DATASOURCE_USERNAME}
    password: ${SPRING_DATASOURCE_PASSWORD}
  data:
    redis:
      host: ${SPRING_DATA_REDIS_HOST}
      port: ${SPRING_DATA_REDIS_PORT}

5. CÁC LỆNH

# Khởi động
docker-compose up
docker-compose up -d              # Chạy nền
docker-compose up --build         # Build lại image

# Dừng
docker-compose stop
docker-compose down               # Dừng và xóa container
docker-compose down -v            # Xóa cả volumes

# Xem thông tin
docker-compose ps
docker-compose logs
docker-compose logs -f app        # Follow log của service
docker-compose logs --tail=100

# Thực thi
docker-compose exec app bash
docker-compose exec db mysql -uroot -ppassword

# Khác
docker-compose restart app
docker-compose pull               # Pull images mới
docker-compose config             # Validate config

6. PROFILES

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    profiles:
      - dev
docker-compose --profile dev up

7. ENVIRONMENT FILE

7.1 .env

DB_PASSWORD=secretpassword
REDIS_PASSWORD=redispass

7.2 docker-compose.yml

services:
  db:
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}

8. SCALING

# Chạy 3 instance của app
docker-compose up -d --scale app=3

9. NGINX REVERSE PROXY

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - app

  app:
    build: .
    expose:
      - "8080"

nginx.conf

events {
    worker_connections 1024;
}

http {
    upstream app {
        server app:8080;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://app;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

10. DEVELOPMENT WORKFLOW

10.1 docker-compose.dev.yml

version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - ./src:/app/src          # Live reload
    command: ./mvnw spring-boot:run
    environment:
      SPRING_DEVTOOLS_LIVERELOAD_ENABLED: "true"

  db:
    image: postgres:16
    # ...

10.2 Dockerfile.dev

FROM eclipse-temurin:17-jdk-jammy
WORKDIR /app
RUN apt-get update && apt-get install -y curl
COPY .mvn/ .mvn
COPY mvnw pom.xml ./
RUN ./mvnw dependency:go-offline
COPY src ./src
EXPOSE 8080
CMD ["./mvnw", "spring-boot:run"]

11. BÀI TẬP THỰC HÀNH

Bài 1: Full Stack

Setup app + database + cache với Docker Compose.

Bài 2: Nginx

Thêm Nginx reverse proxy.

Bài 3: Dev Environment

Tạo docker-compose cho development với live reload.


12. TÓM TẮT

Khái niệm Mô tả
docker-compose.yml File cấu hình
services Các container
volumes Persistent storage
networks Kết nối
depends_on Thứ tự khởi động
healthcheck Kiểm tra sức khỏe
profiles Môi trường

Bài tiếp theo: 7.6 CI/CD với GitHub Actions


🧭 Điều Hướng Series

⬅️ Bài trước: BÀI 7.4: DOCKER CƠ BẢN

📋 Lộ trình tổng quan: Xem Toàn Bộ Series

➡️ Bài tiếp theo: BÀI 7.6: CI/CD VỚI GITHUB ACTIONS


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí