로컬 테스트를 위한 docker-compose 만들기

rejs·2025년 12월 17일

로컬에서 테스트해보기 위해서 docker 컨테이너들을 만들고자 한다.

마리아db 헬스체크

https://mariadb.org/mariadb-server-docker-official-images-healthcheck-without-mysqladmin/

  services:
    mariadb:
      image: mariadb:latest
      env:
        MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: true
        MARIADB_MYSQL_LOCALHOST_USER: 1
        MARIADB_MYSQL_LOCALHOST_GRANTS: USAGE
      ports:
        - 3306
      healthcheck:
        test: [ "CMD", "healthcheck.sh", "--su-mysql", "--connect", "--innodb_initialized" ]
        start_period: 1m
        start_interval: 10s
        interval: 1m
        timeout: 5s
        retries: 3

마리아 db 헬스체크를 해야하는 이유는 spring 컨테이너가 db 컨테이너보다 더 빨리 실행되면 스프링컨테이너가 꺼지기 때문이다.

restart option을 줄 수 있겠지만 그냥 health check를 사용하기로 했다.

spring health check

spring actuator를 사용하여 /health를 열었다

  reservation-1:
    container_name: reservation-1
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 8081:8080
    environment:
      PORTONE_API_SECRET: ${PORTONE_API_SECRET}
      PORTONE_API_STOREID: ${PORTONE_API_STOREID}
      PORTONE_WEBHOOK_SECRET: ${PORTONE_WEBHOOK_SECRET}
      DATASOURCE_URL: ${DATASOURCE_URL}
      DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
      DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
      JWT_SECRET_KEY: ${JWT_SECRET_KEY}
    depends_on:
      mariadb:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:8080/api/actuator/health || exit 1"]
      start_period: 1m
      start_interval: 10s
      interval: 1m
      timeout: 5s
      retries: 3

amazoncorretto:21-alpine에는 curl이 기본적으로 깔려있지 않아서 wget을 사용하였다.

스프링 시큐리티를 쓰고 있다면 permitAll하는 것을 잊지 않아야한다.

caddy

./caddy/conf/Caddyfile

http://localhost {
    reverse_proxy reservation-1:8080 reservation-2:8080 {
        header_down X-Server-Name {upstream_hostport}
    }
}

caddy를 사용한 이유는 가장 빨리 쓸 수 있기 때문이다.
https가 있어야하는 테스트는 아니므로 http://localhost를 설정한다.

알아서 로드 밸런싱 해준다.

header_down옵션을 사용하면 header에 서버이름을 적어서 보내준다

docker-compose 전체보기

services:
  mariadb:
    container_name: reservation-db
    image: mariadb:latest
    ports:
      - 3306:3306
    environment:
      MARIADB_DATABASE: movie_db
      MARIADB_USER: ${DATASOURCE_USERNAME}
      MARIADB_PASSWORD: ${DATASOURCE_PASSWORD}
      MARIADB_ROOT_PASSWORD: root_password
    healthcheck:
      test: [ "CMD", "healthcheck.sh", "--connect", "--innodb_initialized" ]
      start_period: 1m
      start_interval: 10s
      interval: 1m
      timeout: 5s
      retries: 3

  reservation-1:
    container_name: reservation-1
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 8081:8080
    environment:
      PORTONE_API_SECRET: ${PORTONE_API_SECRET}
      PORTONE_API_STOREID: ${PORTONE_API_STOREID}
      PORTONE_WEBHOOK_SECRET: ${PORTONE_WEBHOOK_SECRET}
      DATASOURCE_URL: ${DATASOURCE_URL}
      DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
      DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
      JWT_SECRET_KEY: ${JWT_SECRET_KEY}
    depends_on:
      mariadb:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:8080/api/actuator/health || exit 1"]
      start_period: 1m
      start_interval: 10s
      interval: 1m
      timeout: 5s
      retries: 3

  reservation-2:
    container_name: reservation-2
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 8082:8080
    environment:
      PORTONE_API_SECRET: ${PORTONE_API_SECRET}
      PORTONE_API_STOREID: ${PORTONE_API_STOREID}
      PORTONE_WEBHOOK_SECRET: ${PORTONE_WEBHOOK_SECRET}
      DATASOURCE_URL: ${DATASOURCE_URL}
      DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
      DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
      JWT_SECRET_KEY: ${JWT_SECRET_KEY}
    depends_on:
      mariadb:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:8080/api/actuator/health || exit 1"]
      start_period: 1m
      start_interval: 10s
      interval: 1m
      timeout: 5s
      retries: 3

  caddy:
    container_name: caddy
    image: caddy:latest
    restart: unless-stopped
    ports:
      - "8080:80"
    volumes:
      - ./caddy/conf:/etc/caddy
      - caddy_data:/data
      - caddy_config:/config
    depends_on:
      reservation-1:
        condition: service_healthy
      reservation-2:
        condition: service_healthy
volumes:
  caddy_data:
  caddy_config:

이제 k6나 locust 같은 걸로 테스트할 시간이다.

0개의 댓글