아키텍처 구조
본 글에서는 SpringBoot와 Vue3 사용한 '날숨' 프로젝트의 자동 빌드, 배포하는 과정을 설명한다. 아래는 필자가 진행한 '날숨' 프로젝트의 아키텍처 구조이다.
Docker를 사용하며, Docker를 개념적으로 두 개의 영역으로 구분했다. 왼쪽은 배포한 웹 애플리케이션이 동작하는 영역이며, 클라이언트 요청에 대해 응답한다. 오른쪽은 그 외 컨테이너들이 있는 영역이다. 각 컨테이너의 역할은 아래와 같다.
- Nginx: Nginx 웹 서버가 동작하는 컨테이너. 리버스 프록시 역할을 수행한다. 빌드된 Vue3의 파일들을 갖고 있어 정적 파일 요청(HTML, JS, CSS)을 처리하며 백엔드 요청을 Spring Boot 컨테이너로 프록시한다.
- Spring Boot : jdk 21이 설치된 컨테이너. 톰캣 서버가 동작하며 백엔드 요청을 처리한다.
- mysql : Mysql 서버가 동작하는 컨테이너
- Jenkins : 젠킨스 서버가 동작하는 컨테이너. 젠킨스를 통해 빌드와 배포를 자동화한다. 빌드 과정 중에 정적 분석 서버인 Sonar Cude에 요청을 넣는다.
- Sonar Cude : 소나 큐브 서버가 동작하는 컨테이너. 소나 큐브는 정적 분석 툴이다. 코드를 보고 코드 버그, 취약점, 코드 스멜 등을 식별한다.
- Portainer : 포테이너가 동작하는 컨테이너. 포테이너는 도커 컨테이너를 관리해주는 툴이다. 도커 환경을 시작적으로 모니터링 할 수 있으며 도커 컨테이너의 쉘에 바로 접근할 수 있다. 매우 편리하기에 사용을 추천한다.
Docker Compose 설치
EC2는 Ubuntu 22.04 (LTS) 버전이며 이미 Docker가 설치되어 있다고 가정한다. 아래는 Docker 설치에 관한 공식 문서이다.
https://docs.docker.com/engine/install/ubuntu/
Install Docker Engine on Ubuntu
Jumpstart your client-side server applications with Docker Engine on Ubuntu. This guide details prerequisites and multiple methods to install Docker Engine on Ubuntu.
docs.docker.com
여러개의 컨테이너를 한번에 생성하기 위해 docker compose를 사용한다. docker compose를 통해 한 번에 여러 개의 컨테이너를 생성, 실행, 폐기할 수 있다. 아래는 docker compose 설치에 관한 공식 문서이다.
https://docs.docker.com/compose/install/linux/
Install the Compose plugin
Download and install Docker Compose on Linux with this step-by-step handbook. This plugin can be installed manually or by using a repository.
docs.docker.com
apt 패키지 설치 도구로 docker compose 플러그인을 간편하게 설치할 수 있다. 아래 명령어를 입력한다.
sudo apt-get update
sudo apt-get install docker-compose-plugin
버전을 출력해 docker compose가 잘 설치되었는지 확인한다.
Docker Compose version vN.N.N(N에는 버전 정보가 들어감)
Docker Copose up 수행
우선 필자는 편의를 위해 아래와 같이 EC2의 디렉터리 구조를 만들었다. 홈 디렉터리에서 아래 명령어를 실행했다.
mkdir docker-compose
mkdir docker-compose/volumns
mkdir deploy
mkdir deploy/backend
mkdir deploy/frontend
그리고 아래 docker-compose.yml을 docker-compose 디렉터리에 넣었다. (docker-compose.yml를 자신의 환경에 맟춰서 수정하자)
version: '3.0'
services:
nginx:
networks:
- appnet
ports:
- '80:80'
- '443:443'
image: nginx
springboot:
networks:
- appnet
command: sh -c 'if [ -e /app.jar ]; then java -jar /app.jar --spring.profiles.active=production; else echo "app.jar not found, skipping execution"; fi'
image: openjdk:21
mysql:
ports:
- '3306:3306'
volumes:
- mysql_data:/var/lib/mysql
networks:
- appnet
environment:
MYSQL_ROOT_PASSWORD: adminPassword
MYSQL_DATABASE: databaseName
MYSQL_USER: userName
MYSQL_PASSWORD: userPassword
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
image: mysql:8.0.34
jenkins:
ports:
- '8080:8080'
user: root
networks:
- jenkinsnet
image: jenkins/jenkins:jdk21
sonarqube:
ports:
- '9000:9000'
networks:
- jenkinsnet
image: sonarqube
portainer:
ports:
- '9443:9443'
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
image: portainer/portainer-ce:latest
volumes:
mysql_data: {}
portainer_data: {}
networks:
jenkinsnet: {}
appnet: {}
이 후 docker-compose 디렉터리로 이동하여 아래의 명령어를 실행한다. docker-compose.yml에 정의된 컨테이너, 볼륨, 네트워크가 생성된다.
sudo docker compose up -d
또한 아래의 명령어로 생성시킨 컨테이너, 네트워크를 삭제시킬 수 있다. 단 볼륨은 삭제되지 않는다.
sudo docker compose down
배포 쉘 스크립트 생성
젠킨스가 배포 과정 사용할 쉘 스크립트 파일을 생성하자. 젠킨스 컨테이너에 있는 빌드 결과물을 운영 또는 개발 서버가 동작하는 컨테이너로 옮기기 위해 필요하다. 아래의 deploy.sh 파일을 만들어 /deploy/backend 디렉터리에 넣는다.
docker cp docker-compose-jenkins-1:/var/jenkins_home/workspace/pipeline/backend/target/jenkins-0.0.1-SNAPSHOT.jar /home/ubuntu/deploy/backend/app.jar
docker cp /home/ubuntu/deploy/backend/app.jar docker-compose-springboot-1:/
docker restart docker-compose-springboot-1
내용은 간단하다. 젠킨스 컨테이너에 있는 spring boot 앱 빌드 결과물인 jar 파일을 ec2(호스트)로 옮기고, 다시 ec2에서 springboot 컨테이너로 옮긴 후 springboot 컨테이너를 재실행한다.
또, 아래의 deploy.sh 파일을 만들어 /deploy/frontend 디렉터리에 넣는다.
rm -rf /home/ubuntu/deploy/frontend/dist
docker cp docker-compose-jenkins-1:/var/jenkins_home/workspace/pipeline/frontend/dist /home/ubuntu/deploy/frontend/dist
docker exec -it docker-compose-nginx-1 rm -rf /usr/share/nginx/html
docker cp /home/ubuntu/deploy/frontend/dist docker-compose-nginx-1:/usr/share/nginx/html
docker restart docker-compose-nginx-1
이것도 위와 비슷하다. 젠킨스 컨테이너에 있는 vue3 빌드 결과물인 dist 디렉터리를 ec2로 옮기고 다시 ec2에서 nginx 컨테이너로 옮긴 후 nginx 컨테이너를 재실행한다.
'Infra > CI&CD' 카테고리의 다른 글
SpringBoot, Vue3 프로젝트 CI/CD (2) (0) | 2024.01.27 |
---|---|
Django Channels 배포 (0) | 2022.09.12 |