오늘은 도커를 활용하여 Spring 프로젝트를 로컬에서 띄우는 방법과 DB와 연결하는 방법에 대해서 써보겠다.

 

주의 및 정보 :

  1. 내 PC에 Docker Desktop이 설치되어 있어야 함.
  2. IDE로 Intellij를 사용하고 있으나 Eclipse에서도 동일하게 동작함.
  3. .jar로 아티팩트를 빌드하지 않고 .war로 아티팩트를 만들어서 실행할 것임.
    • jar는 Spring Boot 프로젝트에서 사용하는 형태이다. jar로 빌드하고 싶다면 Spring에서 Spring Boot 프로젝트로 기반을 바꿔야 함.
  4. Maven을 사용하여 빌드할 것이다. 
  5. DB는 MySQL을 사용하고 있다.

 


 

1. 도커 이미지 생성 준비

도커로 Spring프로젝트를 띄우고 싶다면 우선 도커 이미지를 먼저 만들어야 한다.

  • 도커 이미지란 파일로 애플리케이션 실행에 필요한 독립적인 환경을 포함하며, 런타임 환경을 위한 일종의 템플릿이다.
  • 도커 이미지에는 소스 코드, 라이브러리, 종속성, 도구 및 응용 프로그램을 실행하는데 필요한 기타 파일을 포함하는 파일이다.

이미지가 없다면 컨테이너를 실행할 수 없다.

 

1-1. Dockerfile 만들기

도커이미지 생성을 위해 프로젝트 디렉터리에 Dockerfile을 만들어주겠다.

 

'프로젝트 디렉터리(여기서는 board) 우클릭 > 새로 만들기 > 파일'을 눌러 빈 파일을 만들어주고

그 파일의 이름을 Dockerfile로 변경해 준다.

 

 

 

Dockerfile에는 이미지 생성에 필요한 명령어들이 들어간다.

 

# 1. Java 11 + Tomcat 9 베이스 이미지 사용
FROM tomcat:9.0-jdk11-temurin

# 2. 기존 webapps 제거
RUN rm -rf /usr/local/tomcat/webapps/*

# 3. WAR 복사
COPY *.war /usr/local/tomcat/webapps/ROOT.war

# 4. 포트 노출
EXPOSE 8080

# 5. 톰캣 실행
CMD ["catalina.sh", "run"]

 

 

  • FROM : 도커의 베이스이미지를 지정한다. war 파일의 경우 jar와 다르게 자체적으로 실행할 수 없으므로 톰캣 같은 웹 서버 컨테이너에 배포해서 실행해야 하므로 tomcat을 베이스 이미지로 지정해 주겠다.
  • RUN : tomcat을 설치해서 실행해 보면 알다시피 tomcat 기본 웹서비스라던지 샘플 파일들이 들어가 있다. 그 파일들을 제거해 주는 명령어를 작성한다.
  • COPY : 나중에 Maven으로 빌드할 아티팩트를 베이스이미지로 지정한 톰캣에 복사해 주는 명령어다. 
  • EXPOSE : EXPOSE 지시어는 컨테이너가 실행될 때 컨테이너로 들어오는 트래픽을 특정 포트로 받아들일 수 있도록 지정하는 역할이다.
  • CMD : 컨테이너가 실행될 때 실행할 커맨드를 입력한다. 톰캣을 띄우기 위한 명령어를 입력한다.

 

도커 이미지 생성을 위한 Dockerfile의 작성이 끝났다.

이어서 이미지에 들어갈 아티팩트를 빌드해 주겠다.

 

1-2. 내 프로젝트 빌드

프로젝트 빌드를 위해 인텔리제이에서 설정을 하겠다.

 

 

1. '파일 > 프로젝트 구조'를 클릭하여 프로젝트 구조창을 열고

 

 

2. '프로젝트 설정 > 아티팩트 > '+' 버튼 > 웹 애플리케이션 Archive > '내 프로젝트명:war exploded'에 대해 클릭 '을 클릭하여 새로운 빌드 생성 준비

 

 

 

3. 빌드 이름은 개인이 원하는 방식으로 작성하고

출력 디렉터리는 Dockerfile이 위치한 경로로 지정한다.

확인을 눌러 변경 사항을 저장하고 이어서 빌드를 하겠다.

 

인텔리제이에서 '빌드 > 아티팩트 빌드 > 방금 위에서 만든 빌드 선택' 빌드를 진행한다.

 

빌드가 완료되면 내가 지정한 출력 디렉터리에서 war 파일을 확인이 가능하다.

 

 

빌드와 Docker파일이 생성되었으므로 이제 컨테이너를 띄워보겠다.

 

명령콘솔을 열어 Dockerfile이 위치한 경로로 이동해서 아래의 명령어를 순서대로 입력하면 이미지가 생성되고 컨테이너가 띄워질 것이다.

 

my-project-namemy-container-name본인이 원하는 이름을 적어 넣으면 된다.

 

# 1. 도커 빌드 :
docker build -t my-project-name .

# 2. 도커 컨테이너 실행 : 
docker run -d -p 8080:8080 --name my-container-name my-project-name

 

 

성공적으로 띄워졌는지는 http://localhost:8080으로 접속해서 확인 가능하다.

 

 


 

 

이렇게 해서 이미지를 컨테이너에 성공적으로 띄웠다면 이제는 DB와 연결을 해보도록 하겠다.

 

 

2. DB와 내 프로젝트 연결 준비

내 프로젝트와 연결된 로컬 DB가 있고  로컬에서 DB가 실행 중일 때 컨테이너를 띄웠다면, DB와 내 Spring앱이 연결이 안 되는 걸 확인할 수 있다.

 

이런 현상이 발생하는 이유는 도커 컨테이너는 완전히 독립된 네트워크 공간에서 동작하기 때문에 locahost:3306에 띄워진 로컬 DB랑 연결을 못하는 것이다.

 

이것을 해결하기 위해서는 Docker Compose로 DB도 컨테이너로 띄워야 한다.

 

도커 컴포즈(Docker Compose)란 단일 서버에서 여러 개의 컨테이너를 하나의 서비스로 정의해 컨테이너들을 묶음을 관리할 수 있는 작업 환경을 제공하는 관리도구이다.

우리는 웹서버와 DB를 각각 다른 컨테이너로 띄우고 동시에 운영을 할 것이다.

 

DB를 도커 컨테이너로 띄우기 위해서는 로컬 DB에서 스키마 구조와 초기 데이터를 담은 DDL과 DML 쿼리를 가져와야 한다.

 

2-1. DB 데이터 Export (덤프 준비)

나는 DDL과 초기데이터 둘 다 필요하기 때문에 아래의 방법으로 쿼리를 준비했다.

 

1. MySQL workbench를 실행하여 'Server > Data Export' 선택

 

 

 

 

2. 테이블 구조와 초기데이터를 가져올 스키마 선택

Dump 디렉터리 설정하고 Start Export 버튼을 눌러 추출

 

 

 

 

3. Dump 디렉터리로 가보면 sql 파일들을 확인 가능하다.

 

 

2-2. Docker Compose 준비

sql 파일이 준비가 되었다면 Dockerfile일 위치한 경로db-init 폴더를 만들어주고 sql 파일들을 복사 붙여 넣기 해준다.

 

my-project/
├── Dockerfile           // 이미지 생성을 위한 도커파일
├── my-project.war       // 아까 빌드한 내 프로젝트
├── 
└── db-init/		     // 덤프한 sql 파일을 넣어둘 db-init 경로 생성
    └── init1.sql
    └── init2.sql        // sql 파일들 위치
        ...

 

 

만약 컨테이너에서 테이블 생성 시 Foreign Key(외래키)등 제한 조건들로 인해 테이블 생성 순서가 중요하다면 각 sql 파일 이름 앞에 아래와 같이 숫자를 입력해 줘서 생성 순서를 지정해줘야 한다.

 

db-init/		     // 덤프한 sql 파일을 넣어둘 db-init 경로 생성
    └── 01_init1.sql		// 01 부터 02,03...n번 순으로 실행된다.
    └── 02_init2.sql        
        ...

 

 

이제 Docker Compose를 생성을 위한 docker-compose.ymlDockerfile이 위치한 경로에 만들어 주겠다.

 

helldivers2-docker/
├── Dockerfile
├── board_docker.war
├── docker-compose.yml     // docker compse를 위한 템플릿
└── db-init/
    └── init.sql

 

 

2-3. docker-compose.yml 작성 

docker-compose.yml은 아래와 같이 작성하면 된다. 주석이 붙어있는 부분들을 내 프로젝트 정보에 맞춰 작성하면 된다.

 

version: "3.8"

services:
  db:
    image: mysql:8              // mysql DB 버전
    container_name: my-db       // db를 띄울 컨테이너 이름
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: myproject // root-context.xml에 작성되어 있는 스키마명
      MYSQL_USER: root         //내 DB 계정명
      MYSQL_PASSWORD: 1q2w3e4r //내 DB 계정 비밀번호
    ports:
      - "3306:3306"            // localhost:3306과 컨테이너 내부의 3306 포트 연결
    volumes:
      - dbdata:/var/lib/mysql
      - ./db-init:/docker-entrypoint-initdb.d


  web:
    build: .
    container_name: my-container-name // 아까 컨테이너로 실행한 내 프로젝트 컨테이너 명
    ports:
      - "80:8080"     // http://localhost:8080 이 보기 싫으면 80포트 입력
    depends_on:
      - db            // 위에 작성한 db와 내 웹서버를 연결

volumes:
  dbdata:

 

 

2-4. root-context.xml 수정

docker-compse.yml을 작성 완료했다면 마지막으로 수정이 필요한 파일이 있다.

Spring 애플리케이션 전체에서 공유되는 공통 리소스 정보를 하나 수정해줘야 한다.

해당 정보는 root-context.xml에 저장되어 있다.

 

root-context.xml에서 DB와 연결되는 정보가 있는데 여기서 url 정보를 수정해 줘야 한다.

myproject?db?로 바꿔주기만 하면 된다.

 

<!-- 기존 로컬 DB 연결 -->
<!--<property name="url" value="jdbc:log4jdbc:mysql://localhost:3306/myproject?useUnicode=true&amp;characterEncoding=utf8"></property>-->

<!-- 도커용 -->
<property name="url" value="jdbc:log4jdbc:mysql://db:3306/myproject?useUnicode=true&amp;characterEncoding=utf8" />

 

 

root-context.xml의 정보를 수정하고 저장했다면

위에서 했던 거처럼 프로젝트를 다시 한번 빌드해서 war 파일을 만들어준다.

 


 

 

3. Docker Compose를 실행하여 웹서버와 DB 동시 실행

war파일을 새로 빌드했다면 이제 모든 준비가 끝났으므로 웹서버와 DB 컨테이너를 동시에 실행해 보겠다.

 

아래의 명령어를 순서대로 실행하면 된다.

 

만약 DB를 만든 적이 있다면 0. 번 명령어를 실행해서 DB를 제거해 주고 그게 아니라면 1번부터 순차적으로 실행하면 된다.

 

# 0. 이전에 만든 DB가 있다면 해당 DB 볼륨 초기화
# docker-compose down -v    # 이전 db 제거

# 1. 새로 시작하는 것이라면
docker-compose down

# 2. 컨테이너 + DB + 웹 한 번에 빌드 및 실행
docker-compose up --build

 

 

Docker 컨테이너가 성공적으로 띄워졌다면

http://localhost:8080로 접속해서 서비스를 확인해 보자.

 


 

여기까지가 로컬 환경에서 Spring 기반 애플리케이션과 DB를 띄우고 연결하는 방법에 대해 작성해 보았다.

 

만약 AWS에서 컨테이너로 띄운다고 하면 

1. 웹서버의 이미지를 도커 허브로 올리고

2. EC2에서 해당 이미지를 pull 해서 도커 컴포즈를 실행하면 되고

 

RDS로 DBMS를 따로 운영한다고 하면

0. RDS에 내 데이터베이스 생성

1. root-context.xml의 url 정보를 AWS RDS url 정보로 변경 

     db? -> 내 RDS명. ap-northeast-2.rds.amazonaws.com? 으로 변경

 

2. docker-compose.yml에서 db 서비스 제거

아래처럼 web 부분만 남기면 된다.

 

version: "3.8"

services:
  web:
    build: .
    container_name: my-container-name 
    ports:
      - "80:8080"

 

 

3. RDS 설정을 내 환경에 맞춰 설정 (네트워크 보안그룹 설정)

4. EC2에서 도커 컴포즈 실행하면 된다.

 

 

블로그 이미지

Ahan

책, 영화, 게임! 인생의 활력 요소가 되는 취미들을 하자!

,