[CI/CD] Docker 와 Github Actions 를 활용한 CI/CD 환경 구축 - (2) Docker 를 활용한 배포

HJ·2024년 3월 20일
0

CI/CD

목록 보기
2/4
post-thumbnail

도커 살펴보기

해당 내용은 드림코딩 도커 영상을 보고 작성하였습니다.

스프링은 애플리케이션 코드와 함께 여러 dependencies 로 이루어져 있고, 이를 실행하기 위해서는 JDK 가 필요합니다.

도커는 컨테이너 안에 애플리케이션 실행에 필요한 모든 것을 담고 있습니다. 이를 활용하여 어떤 환경에서도 애플리케이션을 실행할 수 있도록 도와줍니다.


VM vs Container

Virtual Machine

infrastructure 위에 VM ware 같은 Hypervisor 소프트웨어를 사용하여 각각의 가상 머신을 만들 수 있습니다. 가상머신은 PC 의 운영체제 위해 가상머신 각각의 운영체제를 포함하고 있기 때문에 굉장히 무겁고 infrastructure 의 리소스를 많이 잡아먹게 됩니다.

Container

이런 가상머신에서 조금 경량화된 컨셉이 바로 컨테이너입니다. 컨테이너는 각각의 OS 설치 없이 호스트 OS 에 Container Engine 이라는 소프트웨어를 설치하면 개별적인 컨테이너를 만들어서 각 애플리케이션을 고립된 환경에서 구동할 수 있게 해줍니다. Container Engine 중에서 가장 많이 사용되는 것이 바로 Docker 입니다.


Docker

도커를 이용할 때는 컨테이너를 만들고, 배포하고, 컨테이너를 실행하는 과정을 거치게 되는데 컨테이너를 만들기 위해서는 아래 3가지의 과정이 필요합니다.

1. Dockerfile 을 작성합니다.

Dockerfile 에는 컨테이너를 어떻게 만들어야 하는지를 작성합니다.

도커 파일에는 애플리케이션을 구동하기 위해 필요한 jar 와 같은 파일, 필요한 외부 라이브러리, 환경 변수를 작성할 수 있으며, 어떻게 실행시켜야 하는지 스크립트도 작성할 수 있습니다.

2. Image 를 생성합니다.

Image 는 작성한 도커 파일을 이용해서 만들 수 있으며 Image 는 불변의 상태입니다.

3. 컨테이너를 구동합니다.

Image 를 고립된 환경에서 실행할 수 있도록 해주는 것이 컨테이너입니다. 컨테이너 안에서 애플리케이션이 동작한다고 생각하면 됩니다. 또 하나의 Image 로 여러 개의 컨테이너를 구동할 수 있습니다.

로컬에서 생성한 Image 를 Docker Hub 에 push 하면, 서버에서 pull 을 받아, Image 를 통해 컨테이너를 생성하고 구동할 수 있습니다.


Docker Compose

컨테이너를 실행할 때 각각의 image 를 push 하고, pull 받아서 실행하는데 만약 여러 개의 image 를 한 번에 실행해야 한다면 해당 과정을 여러 번 반복해야 합니다.

이러한 작업을 편하게 할 수 있도록 도와주는 것이 바로 Docker Compose 입니다. docker-compose.yml 설정 파일을 통해 여러 개의 도커 컨테이너를 정의하고 실행할 수 있으며, 컨테이너 간 종속성을 설정할 수 있습니다.



도커로 스프링부트 배포하기

1. 도커 로그인

docker login -u [사용자명]

2. 스프링 빌드

Gradle ➜ Tasks ➜ build ➜ bootJar 실행

이 과정을 수행하면 build/libs 에 jar 파일이 생성됩니다.


3. Dockerfile 생성

FROM openjdk:17

ARG JAR_FILE=build/libs/*.jar

COPY ${JAR_FILE} app.jar
COPY src/main/resources/firebaseKey.json firebaseKey.json

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

스프링부트 프로젝트 루트 디렉터리에 Dockerfile 을 생성합니다.

이때 저는 firebaseKey 가 담긴 json 파일까지 함께 실행되어야 하기 때문에 COPY 명령어로 파일도 추가해주었습니다.

COPY [파일위치] [도커 내 파일위치]

COPY 는 위와 같은 형태로 작성하는데, 위처럼 작성한 파일의 경로는 /firebaseKey.json 이 됩니다.


4. 도커 이미지 생성

docker build -t [사용자명]/[이미지명] [도커파일위치]

ex> docker build -t test/testDemo ./

터미널을 열고 Dockerfile 이 위치한 곳까지 이동합니다. 그 후 [도커파일위치] 에 ./ 을 입력합니다.


5. 생성된 이미지 확인

docker images

6. 도커 허브에 이미지 업로드

docker push [사용자명]/[이미지명]

ex> docker push test/testDemo

7. 도커 이미지 pull

sudo docker pull [사용자명]/[이미지명]

8. 환경변수 세팅 방법

환경변수명=VALUE

.env 에 따옴표 없이 위와 같은 형태로 환경변수 파일을 생성합니다.


9. 도커 실행

# 실행
docker run -p [로컬 port]:[도커 port] [사용자명]/[이미지명]

# 환경변수 파일 포함 실행
docker run -p 8080:8080 --env-file ./파일명.env [사용자명]/[이미지명]

-d 옵션을 주면 백그라운드로 실행되게 됩니다.


10. 실행 중인 컨테이너 조회

sudo docker ps

-a 옵션을 주면 중지된 컨테이너까지 조회됩니다.


11. 컨테이너 중지

sudo docker stop [컨테이너ID]

12. 삭제

컨테이너 확인

sudo docker ps -a 

컨테이너 삭제

sudo docker rm [컨테이너ID]

이미지 삭제

sudo docker image rm [사용자명]/[이미지명]

이미지를 삭제하기 전, 컨테이너 삭제가 필요합니다.



Docker Compose (with mariaDB)

Docker Compose 로 스프링과 mariaDB 를 함께 실행해보겠습니다. 수행해본 결과 따로 mariaDB 이미지를 pull 받지 않아도, docker-compose 를 실행하면 자동으로 이미지를 가져와 실행해줍니다.

저는 docker-compose.yml 파일을 바로 서버에서 작성하였습니다.


1. docker-compose.yml 작성

version: "3"
services:
  database:
    container_name: mariadb
    image: mariadb
    volumes:
      - ~/docker/mariadb/etc/mysql/conf.d:/etc/mysql/conf.d:ro
      - ~/docker/mariadb/var/lib/mysql:/var/lib/mysql
      - ~/docker/mariadb/var/log/maria:/var/log/maria
    environment:
      - MYSQL_DATABASE=데이터베이스명
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_ROOT_HOST=root
    command: ['--character-set-server=utf8mb4','--collation-server=utf8mb4_unicode_ci']
    ports:
      - 3306:3306

  application:
    container_name: spring-app
    image: "test/testDemo"
    ports:
      - 8080:8080
    environment:
      - BUCKET=${BUCKET}
      - CONFIG_FILE_PATH=${CONFIG_FILE_PATH}
    depends_on:
      - database

depends_on 명령어는 서비스 간의 종속성 순서대로 실행되게 합니다. 위에서는 mariadb 가 실행된 후에 spring-app 이 실행됩니다.

docker-compose.yml 과 같은 위치에 .env 로 환경변수 파일을 만들면 별도로 파일을 지정하지 않아도 자동으로 불러옵니다. 저는 env 파일에 파일명을 주니 읽어오지 못했고, 파일명 없이 .env 만 작성하니 정상적으로 읽어왔습니다.

그냥 실행하면 데이터베이스를 찾을 수 없다는 오류가 뜨면서 실행되지 않습니다. 찾아보니 스크립트를 작성하면 된다는데 저는 스크립트 파일을 읽지 못하는 것 같아 application.yml 에서 설정해주었습니다.

데이터베이스를 자동으로 생성하게 할 때는 application.yml 에서 데이터베이스 URL 뒤에 ?createDatabaseIfNotExist=true 옵션을 추가하면 됩니다.


2. 실행

docker-compose up

이미지를 pull 받지 않아도 docker-compose.yml 을 작성해놓고 docker-compose up 을 실행하면 자동으로 이미지를 pull 받아서 수행합니다.

profile
공부한 내용을 정리해서 기록하고 다시 보기 위한 공간

0개의 댓글