[Docker-Compose] 서버와 db 연동/배포(1)

무1민·2024년 7월 1일
1

infra

목록 보기
13/14
post-thumbnail

이번엔 docker-compose를 이용해서 서버와 db를 연동하며 둘이 함께 배포하는 것을 알아보도록 하겠다.

MSA를 클라우드 환경에 배포하면서, 데이터베이스를 도메인별로 분리하고 배포해야 한다.
이에, docker-compose를 이용해서, docker 컨테이너 기반 springboot 서버 하나와 docker 컨테이너 기반 데이터베이스 하나를 연동하며 배포해보도록 하겠다.

먼저 SpringBoot 서버를 컨테이너화할 수 있는 Dockerfile을 먼저 작성하자.
모두 잘 알겠지만 jar파일 이름은 settings.gradle 파일을 확인하면 된다.
필자는 payment로 되어있기 때문에 아래와 같이 작성했다.

FROM openjdk:17-jdk

ARG JAR_FILE=./build/libs/payment-0.0.1-SNAPSHOT.jar

COPY ${JAR_FILE} app.jar

ENTRYPOINT ["java","-jar","/app.jar"]

이후, SpringBoot 서버 루트 디렉토리에 docker-compose.yml파일을 두도록 한다.
아래의 예시에서는 payment-service의 springboot 서버와 database 서버로 연결되어 있다.

version: '3.8'
services:
  payment-service:
    image: bangjinseong/payment-service:latest
    container_name: payment-container
    restart: unless-stopped
    build: .
    ports:
      - "8300:8300"
    depends_on:
      - database
    environment:
      - ENCRYPT_KEY=${ENCRYPT_KEY}
      - SPRING_DATASOURCE_URL=${SPRING_DATASOURCE_URL}
      - SPRING_DATASOURCE_USERNAME=${MYSQL_USER}
      - SPRING_DATASOURCE_PASSWORD=${MYSQL_PASSWORD}
    networks:
      - payment-network
      
  database:
    image: mysql:8.0.33
    container_name: payment_db_container
    restart: unless-stopped
    ports:
      - "3300:3306"
    environment:
      MYSQL_ROOT_HOST: '%'
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      TZ: ${TZ}
    volumes:
      - ./db_data:/var/lib/mysql
    networks:
      - payment-network
      
networks:
  payment-network:

services 안에는 springboot 서버 하나와 database 서버 하나를 두자.
또한, 각 서비스들은 별도의 네트워크를 만들어서 각 서비스가 서로 통신할 수 있는 네트워크를 정의하도록 하자.

payment-service에서 build : .으로 되어있는데, 이는 현재 디렉토리에 있는 dockerfile로 docker 빌드를 하겠다는 말이다.
아까 작성했던 dockerfile을 docker-compose.yml 파일과 같은 디렉토리에 있다면 변경할 필요없다.

또한, 포트번호를 알맞게 설정해야 하는데, ~~~~:~~~~ 형태로 되어있다.
왼쪽 포트번호는 컨테이너 외부, 다시 말해 외부(클라이언트)에서 해당 서비스를 이용할 때 사용하는 포트번호이다.
오른쪽 포트번호는 컨테이너 내부에서 사용되는 포트번호다.
왼쪽 포트번호는 클라이언트가 각 서비스를 어떤 포트번호로 접근할지에 대해서만 잘 파악하고 개발자가 작성하면 된다.
하지만, 오른쪽 포트번호는 springboot 서버의 경우 우리가 application.yml파일에서 작성했던 포트번호로 작성해야 한다.
만약 작성하지 않았다면, default가 8080번이니, 8080으로 작성해두도록 하자.
데이터베이스의 경우, 필자는 MySQL을 이용했는데, MySQL의 포트번호는 3306을 이용하기 때문에, 3306을 적어두면 된다.

springboot 서버에 depends on이 적혀있는데,
docker-compose 파일에서 하나의 서비스가 다른 서비스보다 먼저 시작되어야 함을 명시할 때 사용한다.
위의 예시같은 경우 depends on: - database라고 되어 있는데, 이는 springboot서버가 시작하기 전에 아래 database라는 서비스가 시작한 후에 시작하라는 것을 말한다.
우리는 Database가 켜져있지 않은 상황에서 springboot 서버를 실행하면 오류가 터진다는 것을 너무 잘 안다.
depends on 명령어를 잘 기술하도록 하자.

아래 environment는 각 변수들이 외부에서 가져오게끔 ${}처리 되어있는데, 이는 민감한 정보니 클라우드 환경에 배포하기 위해서 외부 파일(.env)에 담아서 따로 관리하도록 하자

MYSQL_ROOT_PASSWORD=[패스워드]

이런식으로 작성하면 된다.
SPRING_DATASOURCE_URL같은 경우, spring에서 작성했던 대로 작성하면 된다.
jdbc:mysql://database:3306/[MYSQL_DATABASE 값]

MYSQL_ROOT_HOST: '%'같은 경우는 MYSQL 데이터베이스에서 루트 사용자가 모든 호스트에서 접속할 수 있도록 허용하는 설정이다.
혹시나, 보안상의 문제가 있다면 특정 호스트의 IP 주소나 호스트 이름으로 설정하자.

TZ는 TimeZone을 뜻한다.
TZ=Asia/Seoul이런식으로 .env파일에 작성하자

volumes 섹션은 docker compose 파일에서 컨테이너와 호스트 간의 데이터 볼륨을 정의하는 데 사용된다. 컨테이너의 특정 디렉토리를 호스트의 디렉토리와 공유할 수 있다.
이로 인해, 컨테이너가 삭제되거나 재시작되더라도 데이터가 지속적으로 유지가 된다.
호스트 머신의 ./db_data 디렉토리가 DB 도커 컨테이너의 /var/lib/mysql와 데이터 파일을 공유한다는 이야기가 된다.

이렇게 Docker-compose파일을 하나하나 뜯어보았다.

다음 시간에는 이 파일을 기반으로 어떻게 클라우드에 배포를 할지 이야기해보자

profile
야호

0개의 댓글