Backend/Docker

도커(Docker) 사용하기

olsohee 2024. 4. 24. 18:41

도커를 통해 프로젝트 구동시키기

1. 서버에 Docker 설치하기

다음 블로그 (https://everydayyy.tistory.com/121)를 따라 서버에 Docker를 설치하면 된다.

2. 이미지 생성하기

도커에는 스프링부트 프로젝트, MySQL, Redis가 각각 컨테이너로 생성되어야 한다. 그리고 컨테이너를 실행시키기 위해서는 도커 이미지가 필요하다.

2-1. 스프링부트 프로젝트 이미지 생성

우선 스프링부트 프로젝트를 기반으로 도커 이미지를 생성해보자. 이를 위해서는 프로젝트 내에 도커 파일을 생성해줘야 한다. 도커 파일은 도커가 이해할 수 있는 설정 파일로, 도커 이미지를 만드는데 필요한 정보를 담고 있다. 따라서 어떤 자바를 사용할 것인지, 어떤 jar 파일을 사용할 것인지 등을 설정해줘야 한다.

 

내가 작성한 도커 파일은 다음과 같다. 도커 파일은 프로젝트 최상단에 위치시켰다.

# 자바 버전
FROM openjdk:17 

# 빌드 결과로 생성된 jar 파일의 위치를 변수에 저장
ARG JAR_FILE=/build/libs/*.jar

# 변수 경로에 있는 모든 jar 파일을 도커 이미지 내의 루트 디렉토리로 복사 (이때 해당 파일 이름은 community.jar)
COPY ${JAR_FILE} community.jar

# 컨테이너 실행 시 반드시 실행될 명령어 (자바는 jar 파일을 실행할 때 java -jar <파일명> 을 실행)
ENTRYPOINT ["java","-jar","community.jar"]

 

이어서 스프링 프로젝트를 빌드한 후에 프로젝트가 위치한 파일에서 docker build 명령어를 실행하면 현재 디렉토리에 있는 도커 파일을 사용하여 도커 이미지가 생성된다. 이때 명령어에 대한 옵션은 다음 블로그(https://velog.io/@whdghk1908/Docker-Image-Build) 또는 공식 문서를 참고하자.

 

나는 다음을 통해 이미지를 빌드했다. 그러면 도커가 현재 디렉토리(community)에 위치한 도커 파일을 읽어서 이미지를 생성한다. 그리고 이때 도커 파일의 이름은 반드시 Dockerfile이어야 한다. 

 

docker images 명령어를 통해 다음과 같이 이미지가 생성된 것을 확인할 수 있다.

 

참고로 빌드한 이미지를 도커 허브에 푸시하기 위해서는, 도커 이미지명을 도커 허브의 리포지토리명과 동일하게 설정해야 한다. 예를 들어 도커 허브의 사용자명이 username, 리포지토리명이 community라면, 도커 이미지 이름을 username/community와 같이 리포지토리 경로로 설정해야 한다. 그리고 docker push username/community:tagname 명령어를 치면, 해당 리포지토리에 해당 이미지가 tagname이라는 태그를 갖고 푸시된다.

2-2. MySQL, Redis 이미지 생성

MySQL과 Redis는 직접 이미지를 만들 필요 없이 만들어진 이미지를 받아오면 된다. docker pull mysql(또는 redis) 라는 명령어를 통해 이미지를 받아올 수 있다. 

 

마찬가지로 docker images 명령어를 통해 확인해보면 모두 정상적으로 이미지를 받아온 것을 확인할 수 있다.

3. 이미지를 컨테이너로 실행시키기

3-1. 컴포즈 파일 생성

이제 준비된 이미지들을 컨테이너로 실행시키면 된다. 나는 도커에 총 3개(스프링부트, MySQL, Redis)의 컨테이너를 실행시켜야 한다. 그리고 매번 명령어를 통해 하나씩 컨테이너를 생성해야 하는 번거로움이 따른다. 만약 3개가 아닌 수많은 컨테이너를 실행시켜야 하는 상황이라면 이는 매우 비효율적이다. 

 

따라서 이때 도커 컴포즈라는 것을 사용하면 된다. 도커 컴포즈는 단일 서버에서 여러 개의 컨테이너들을 하나의 서비스로 정의하고 구성해 하나의 묶음으로 관리할 수 있도록 한다. 

 

도커 컴포즈를 사용하기 위해서는 컴포즈 파일을 작성해야 한다. 내가 작성한 컴포즈 파일은 다음과 같다. 컴포즈 파일도 도커 파일과 마찬가지로 프로젝트의 최상단에 위치시켰다.

services: # 도커 컴포즈에서 관리할 서비스 목록
  springboot:
    build: . # 이미지를 빌드할 디렉토리
    image: community # 빌드된 이미지 이름
    container_name: community # 생성할 컨테이너 이름
    ports: # 호스트 포트와 도커 컨테이너의 포트 매핑
      - "8080:8080"
    depends_on: # 이 서비스가 컨테이너로 구동되기 전에 필요한 의존 서비스
      - mysql
      - redis
  mysql:
    image: mysql
    container_name: mysql
    environment:
      MYSQL_ROOT_PASSWORD: { ... } 
      MYSQL_DATABASE: community 
      MYSQL_USER: { ... }
      MYSQL_PASSWORD: { ... } 
    ports:
      - "3306:3306"
  redis:
    image: redis
    container_name: redis
    ports:
      - "6379:6379"

 

그리고 이때 스프링부트 프로젝트의 application.yml 파일 내의 DB 설정에 주의해야 한다. spring.datasource.url을 로컬 MySQL 서버로 하면 안되고, 컴포즈 파일에 적은대로 설정해야 한다. 컨테이너에서 실행되는 스프링부트 프로젝트는 컨테이너 내에서 실행되는 MySQL과 통신하기 때문이다. 즉, IP 주소를 localhost가 아닌 container_name으로 설정한 mysql로 설정해야 하고, 스키마 이름도 MYSQL_DATABASE로 설정한 community로 설정해야 한다. 

 

그리고 보안적인 이유로 useSSL에 대한 추가 설정이 필요한데 이를 false로 하고 allowPublicKeyRetrieval를 true로 해야 한다.

spring:
  datasource:
    url: jdbc:mysql://mysql:3306/community?useSSL=false&allowPublicKeyRetrieval=true

 

참고로 MySQL Workbench를 통해 도커 컨테이너에 띄워진 MySQL 서버에 접근하려면, 다음과 같이 입력해야 한다.

  • Hostname: local host IP인 127.0.0.1
  • Username: 컴포즈 파일의 MYSQL_USER
  • Password: 컴포즈 파일의 MYSQL_PASSWORD
  • Default Schema: 컴포즈 파일의 MYSQL_DATABASE

3-2. 컨테이너 실행

docker-compose up --build -d 명령어를 입력하면, 해당 디렉토리의 컴포즈 파일을 읽어와서 여러 개의 컨테이너를 실행시킨다. 그리고 이때 컴포즈 파일의 이름은 반드시 docker-compose.yml이어야 한다. 

 

docker ps를 통해 현재 실행 중인 컨테이너를 확인해보면, 다음과 같이 3개의 컨테이너가 실행 중인 것을 알 수 있다. 그리고 이때 컨테이너 이름이 컴포즈 파일에서 container_name으로 설정한 이름과 같은 것을 알 수 있다.

'Backend > Docker' 카테고리의 다른 글

도커 네트워크  (0) 2024.06.25
도커 알아보기  (0) 2024.06.25
깃허브 액션, 도커, EC2, RDS를 통해 배포하기  (0) 2024.04.26