본문으로 바로가기
반응형

이 글은 개인적으로 공부를 목적으로 여러 블로그, 문서를 참조하며 작성하여 부정확하거나 내용이 부실할 수 있는점 양해드리며

 잘못된 부분이 있다면 댓글로 알려주시면 감사하겠습니다 :)

 

 

간단한 웹 서비스를 구축한다고 가정한다.

간단하면서 일반적으로, 백엔드 애플리케이션 + DB와 프론트에 Nginx를 두는 구조를 많이 사용한다.

docker 환경에서는 백엔드 애플리케이션, DB, Nginx를 각각 설정하고 컨테이너화 하여 관리할 수 있다.

다만 서버 장비가 증설된다면 각 컨테이너 설정을 다시 해주어야하는 번거로움이 존재한다.

Docker Compose는 한 서비스를 위한 여러 컨테이너를 관리를 하나의 파일에서 할 수 있고 여러 컨테이너들을 동시에 실행시킬 수 있다. 이를 통해 위와 같이 매번 컨테이너를 설정해야하는 반복작업을 줄이며 서비스를 위한 컨테이너들의 관리를 쉽게 해준다.

이 예시에서는 아주 간단한 Spring Boot 애플리케이션 하나와, MySQL DB가 연동된 구조를 Docker Compose로 구성해보겠다.

1. Spring Boot 애플리케이션 구축

  • https://start.spring.io/ 에서 spring-boot-starter-data-jpa, mysql 의존성을 추가해 프로젝트 생성
  • 빌드시스템은 Gradle 사용
  • 간단한 REST API 하나 제공하는 서비스 생성
    • Docker Compose 관련이 핵심이기 때문에, 예시코드가 좀 부실하더라도 양해 바랍니다.
// 엔티티 정의
@Entity
public class User {
    @Id
    private Long id;

    @Column
    private String name;

    // getters, setters
}

// 레파지토리 정의
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

// 컨트롤러 정의
@RestController
@RequestMapping("/users")
public class UserController {

    private final UserRepository userRepository;

    public UserController(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @GetMapping
    public List<User> getUsers() {
        return this.userRepository.findAll();
    }

    @GetMapping("/{id}")
    public User getUsers(@PathVariable Long id) {
        return this.userRepository.findById(id).orElse(null);
    }

}
  • application.yml에 설정 진행
    • MySQL서버가 컨테이너 환경이 아닌 외부에 떠있는 경우엔 아래와같이 설정파일에 DB 설정을 해둔다.
    • 하지만 MySQL 서버가 컨테이너로 구성되어있는 경우엔 설정할 수 있는 방벙이 다양하다.
# 아래는 MySQL이 컨테이너가 아닌 경우에 대한 설정 예시
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/userdb
    username: user
    password: userpwd
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    database-platform: org.hibernate.dialect.MySQL5Dialect
    show-sql: true
    hibernate:
      ddl-auto: none

# 외부 환경변수를 주입받아 설정되도록 할 경우에 대한 예시
spring:
  datasource:
    url: ${DB_CONNECTION_URL}
    username: ${DB_USER}
    password: ${DB_PASSWORD}
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    database-platform: org.hibernate.dialect.MySQL5Dialect
    show-sql: true
    hibernate:
      ddl-auto: none

# 외부 환경변수를 주입받아 설정되도록 할 경우에 대한 예시
# 호스트네임의 "db"는 도커 네트워크상 참조가능한 이름으로, 이후 docker-compose 설정할 때 다시 다루겠습니다.
spring:
  datasource:
    url: jdbc:mysql://database:3306/userdb 
    username: user
    password: userpwd
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    database-platform: org.hibernate.dialect.MySQL5Dialect
    show-sql: true
    hibernate:
      ddl-auto: none
  • 이후 프로젝트를 빌드하면 프로젝트경로/build/libs 밑에 jar 파일이 생성됨
  • 백엔드 애플리케이션 Dockerfile 작성
    • Dockerfile 위치는 프로젝트 루트
FROM openjdk:11
ADD build/libs/app.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

2. Docker Compose 설정

Docker Compose는 docker-compose.yml 이라는 파일을 통해 설정한다.

version: "3"
services:
  database:
    image: mysql
    environment:
      MYSQL_DATABASE: userdb
      MYSQL_USER: user      
      MYSQL_PASSWORD: userpwd
      MYSQL_ROOT_HOST: '%'
      MYSQL_ROOT_PASSWORD: rootpwd
    volumns:
      - ./db/data:/var/lib/mysql
    ports:
      - 3306:3306
    restart: always
  application:
    build: .
    depands_on:
      - database
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://localhost:3306/userdb
      SPRING_DATASOURCE_USERNAME: user
      SPRING_DATASOURCE_PASSWORD: userpwd
    restart: always

설정파일을 살펴보면 아래와 같다.

  • version
    • Comose 파일 버전로 도커 엔진 버전별 사용가능한 버전이 존재
  • services
    • Docker Compose로 하나로 관리할 서비스들을 정의. 이들이 각각 컨테이너가 된다.
    • services 아래 설정되는 각 서비스의 이름으로 컨테이너간 통신할 수 있다.

먼저 DB 서비스을 보면

  • database
    • “database”라는 이름의 서비스
    • 백엔드에서 DB 설정을 한다면 hostname에 이 값을 사용할 수 있다.
    • image
      • mysql 기반 이미지 사용
    • environment
      • 해당 컨테이너에서 사용할 환경변수 설정
      • mysql 이미지는 컨테이너의 환경변수를 참조하여 MySQL DB, 유저 정보등을 구성함
    • volumns
      • 호스트의 파일시스템과 도커 컨테이너의 파일시스템을 마운트함
      • DB 데이터 유지를 위해 필수적으로 설정되야함
    • ports
      • 호스트의 포트와 컨테이너의 포트를 매핑함
    • restarts
      • 오류 등으로 컨테이너가 종료됐을때 재시작 여부

아까

다음은 Spring Boot 애플리케이션 컨테이너에 대한 설정이다.

  • application
    • “application”라는 이름의 서비스
    • build
      • Dockerfile을 이용해 컨테이너화 할 때 사용하는 옵션
      • 위 database 컨테이너와 달리 Dockerfile을 빌드하여 컨테이너화 해야하기 때문에 사용
      • Dockerfile이 docker-compose.yml 파일과 다른 경로에 있을경우엔 “.” 대신 해당 경로 지정
    • depends_on
      • 각 서비스간 종속성을 두어 실행 순서를 정할 수 있다.
      • 이 예시에선 DB가 먼저 올라가야하기 때문에 “database” 서비스에 의존성을 갖게함
    • environment
      • database 설정과 동일하게, 환경변수를 컨테이너 내부에 세팅해주기 위해 사용한다.
      • 프로젝트에서 채택한 방식에 따라 적절하게 설정해준다.
    • restarts
      • 위와 동일

이렇게 docker-compose.yml 파일까지 작성이 완료되면 이제 실행만 하면 된다.

아래 docker-compose 기본적인 명령어들이다. 전체적으로 Docker 명령어와 유사하다

# 컨테이너화 + 데몬모드로 각 컨테이너 실행
docker-compose up -d 

# 상태 체크
docker-compose ps

# 컨테이너 실행 / 종료
docker-compose start
docker-compose stop

# Docker Compose 제거 (volumn, network 포함 제거)
docker-compose down

# 로그 확인
docker-compose logs
반응형