인프라/도커

도커 실무 - Mariadb 를 사용하는 스프링부트 프로젝트 배포해보기

Jake Seo 2022. 6. 7. 21:35

개요

자바 스프링부트 프로젝트와 MariaDB 를 이용한 앱을 도커 가상환경을 이용하여 배포하는 과정을 통해 실무에서 도커를 어떻게 이용하는지 알아보자. 스프링부트 프로젝트는 로컬 환경에 작성이 완료되어 있다고 가정한다.

도커 이미지 세팅하기

이미지란? 특정한 세팅이 된 가상 OS 라고 생각하면 된다. 이를테면 jdk 와 mariadb 가 설치된 리눅스 OS 를 이미지로 올릴 수 있다고 생각하면 된다. 물론 아무것도 안깔린 그냥 OS 도 이미지가 될 수 있다.

우리가 필요한 이미지는 무엇일까?

이 실습에서 우리가 작성한 스프링부트 프로젝트를 실행하기 위해 2가지 이미지가 필요하다.

  1. java 11 버전 기준으로 작성된 프로젝트를 실행하기 위해 jdk 11 이 설치된 리눅스
  2. mariadb 가 설치된 리눅스

위 두개의 이미지를 통해 mariadb 를 이용하는 스프링부트 프로젝트를 구동할 것이다.

jdk 11 이 설치된 리눅스 이미지 가져오기

이미지를 찾을 때는 도커 허브에 있는 검색창을 이용하면 된다.

java 의 경우 위와 같이 openjdk 에 있는 것을 가져오면 된다. 도커 허브 공식 이미지의 경우, URL 에 _ 가 끼어있으며, 다음과 같은 형식으로 이루어져 있다.

https://hub.docker.com/_/openjdk

$ docker pull openjdk:11

위와 같은 형식으로 이미지를 불러올 수 있다.

mariadb 가 설치된 리눅스 이미지 가져오기

같은 방식으로 도커 허브에서 불러오면 된다.

https://hub.docker.com/_/mariadb

이번에도 공식 URL 에서 이미지 pull 이 가능한 URL 을 이용해 이미지를 가져오면 된다.

이미지는 어떻게 실행하는가?

docker pull을 이용해 도커 이미지를 가져오는 방법을 학습해봤는데, 아직 도커 데몬에 올려서 실행시켜보지는 않은 상태이다. docker run 명령어를 이용하여 이를 실행시켜볼 수 있다.

도커 이미지를 실행하면, 실제로 컨테이너에서 자그마한 리눅스가 돌아가게 된다. 우리는 이 자그마한 리눅스에 명령어를 보내 소통할 수도 있고, 그냥 백그라운드에 돌려놓으며 아무런 상호작용도 하지 않을 수도 있다.

docker run 으로 이미지 실행해보기

$ docker run -d --name mariadb -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root1234 -e MYSQL_DATABASE=test mariadb --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

위의 명령어는 조금 복잡해보이지만, mariadb 이미지를 실행시키는 명령어이다.

  • -d 옵션은 데몬을 의미하며, 백그라운드에서 돌아간다는 뜻이다.
  • --name 옵션은 컨테이너의 이름을 설정하는 옵션이다. 이름은 mariadb이다.
  • -p 옵션은 내부 포트를 외부로 여는 것이다.
    • 외부포트:컨테이너포트 로 작성하면 된다. ex) 80:8080 이면 컨테이너 내부의 8080 포트를 외부의 80 포트로 열겠다는 것이다.
    • 여기서는 컨테이너 내부의 mariadb 기본 포트인 3306 을 외부 포트 3306 으로 열겠다는 뜻으로 -p 3306:3306 을 입력했다.

이미지 실행 확인하기

$ docker ps

CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                    NAMES
3de18799b2d2   mariadb   "docker-entrypoint.s…"   3 minutes ago   Up 3 minutes   0.0.0.0:3306->3306/tcp   mariadb

이 명령어의 결과로 나오는 것들이 현재 실행중인 컨테이너이다. 컨테이너가 정말 실행중인지 디비에 연결하여 한번 더 테스트해보면, 아래와 같이 연결에 성공하는 것을 볼 수 있다.

이미지 로그 보기

이미지에서 실행중인 프로그램의 로그를 보려면

$ docker logs mariadb -n 10
$ docker logs mariadb -f

위 두 명령어 중 맘에드는 것으로 실행해보면 된다. 첫번째 명령어는 끝에 10줄만 확인하는 것이고, 2번째 명령어는 끝에서부터 보되, 새로운 출력이 나올 때마다 실시간으로 업데이트하며 보는 것이다.

2022-06-05  8:58:50 0 [Note] InnoDB: File './ibtmp1' size is now 12.000MiB.
2022-06-05  8:58:50 0 [Note] InnoDB: log sequence number 46755; transaction id 14
2022-06-05  8:58:50 0 [Note] Plugin 'FEEDBACK' is disabled.
2022-06-05  8:58:50 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2022-06-05  8:58:50 0 [Warning] You need to use --log-bin to make --expire-logs-days or --binlog-expire-logs-seconds work.
2022-06-05  8:58:50 0 [Note] Server socket created on IP: '0.0.0.0'.
2022-06-05  8:58:50 0 [Note] Server socket created on IP: '::'.
2022-06-05  8:58:50 0 [Note] InnoDB: Buffer pool(s) load completed at 220605  8:58:50
2022-06-05  8:58:50 0 [Note] mariadbd: ready for connections.
Version: '10.8.3-MariaDB-1:10.8.3+maria~jammy'  socket: '/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution

위와 같은 형식으로 로그가 나온다.

스프링부트 프로젝트 이미지 실행해보기

스프링부트 이미지를 실행할 때는 mariadb 실행과는 살짝 다른 점이 있는데, 로컬 파일을 마운트하여 컨테이너에서 사용해야 한다는 것이다. 우리가 작성하고 빌드한 .jar 파일을 컨테이너가 실행해야 하기 때문이다.

$ docker run -it --rm --name api-server-jdk16-2 -v $(pwd)/app/build/libs:/home/api-server -p 80:8080 -e SPRING_PROFILES_ACTIVE=dev openjdk:16 bash -c "java -jar /home/api-server/app.jar"

bash -c 이후로는 옵션을 입력해도 안 먹힌다. 옵션은 bash -c 앞에 두고, bash -c 는 최대한 뒤에 두자.

위의 명령어로 실행이 가능하다. 옵션에 대해 설명하자면,

  • -it 는 터미널을 통해 명령을 주고 받겠다는 것이다.
  • --rm 은 컨테이너와 소통을 종료하면 컨테이너를 종료하겠다는 것이다.
  • -v 옵션을 통해서 내 로컬 파일을 컨테이너 내부로 마운팅할 수 있다.
  • bash -c "java -jar /home..." 부분은 컨테이너가 실행된 뒤 실행할 명령어를 말한다.
  • -e 옵션은 환경변수를 제어할 때 사용한다.

도커 네트워크 만들기

도커는 분리된 가상환경이므로 아무런 설정도 해주지 않으면 컨테이너 내부에서 외부 네트워크와 소통할 수 없다. 내부 포트를 열어주어 나의 로컬 환경과 소통하거나 특정 네트워크 대역에 넣어서 도커 내부에서 돌아가는 이미지끼리 소통을 가능하게 만들어야 한다.

$ docker network create springboot-server

위와 같은 명령어를 입력하면, d7d98ef75b05bca5ecc47eb23d89697a3386d7f2cbcc7d71a1cf747d4dd36922 와 같은 내용이 출력된다.

$ docker network ls

위의 명령어를 이용하여 전체 네트워크 목록을 출력해볼 수도 있다.

NETWORK ID     NAME                DRIVER    SCOPE
47fa5ce10308   bridge              bridge    local
de1d48f41cc2   host                host      local
93cf358103a5   none                null      local
d7d98ef75b05   springboot-server   bridge    local

우리가 만든 springboot-server 가 보인다.

도커 네트워크 안에서 mariadb 실행하기

$ docker run -d --name mariadb --network springboot-server -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root1234 -e MYSQL_DATABASE=test mariadb --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
  • --network springboot-server 옵션이 추가되었다.

도커 네트워크 안에서 스프링 부트 프로젝트 실행하기

$ docker run -it --rm --name api-server-jdk16-2 --network springboot-server -v $(pwd)/app/build/libs:/home/api-server -p 80:8080 openjdk:16 bash -c "java -jar /home/api-server/app.jar"
  • --network springboot-server 옵션이 추가되었다.

정상적으로 둘 다 실행했다면, 스프링부트 프로젝트가 mariadb 에 잘 붙는 것을 확인할 수 있다.

이 과정에서 스프링부트 내부 프로퍼티에서 접속정보는 localhost 가 아닌 mariadb가 되어야 한다.

변경 전

spring:
  datasource:
    url: jdbc:mariadb://localhost:3306/test
    username: root
    password: root123

변경 후

spring:
  datasource:
    url: jdbc:mariadb://mariadb:3306/test
    username: root
    password: root123
반응형