[Docker] Docker Compose 프로젝트 무중단 배포
1. 사전에 필요한 내용
[참고] CICD - AWS EC2 Jenkins 설치
[참고] CICD - AWS EC2 Jenkins GitHub 설정
[참고] CICD - AWS EC2 Jenkins 프로젝트 War 배포
[참고] Docker, Jenkins를 이용한 프로젝트 실행
2. Docker Compose 프로젝트 무중단 배포
1) 전체적인 구조
2) Jenkins 설정
Execute Shell 항목을 이용하여 빌드 후 샐행할 명령어를 쉘 스크립트로 동작하도록 한다.
bash ${WORKSPACE}/deploy.sh
2) Nginx 설정 파일
EC2 서버에 http 영역을 수정한 nginx.conf 파일을 생성해준다. 'http://springproject'로 Proxy pass를 지정하면 'upstream springproject'에 의해 로드 밸런싱이 된다.
- 8082가 구동 중일 때 GitHub에 Push
- 변경된 내용 빌드
- 빌드한 War 파일 8081에 배포
- 8082 서버 다운
- 로드 밸런싱에 의해 8081을 실행
- 반복
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
#include /etc/nginx/conf.d/*.conf;
upstream springproject{
least_conn;
server 127.0.0.1:8081 weight=5 max_fails=3 fail_timeout=10s;
server 127.0.0.1:8082 weight=10 max_fails=3 fail_timeout=10s;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://springproject;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}
}
※ 도커에서는 컨테이너 간의 통신이 가능하다. 하지만 로드 밸런싱을 하기 위해서는 기본 또는 여러 네트워크가 아닌 호스트(서버)로 네트워크를 수동적으로 연결해주어야 한다. 만약 기타의 네트워크로 연결할 경우 blue, green 서버를 찾는데 어려움이 생긴다.
3) docker-compose.nginx.yml
EC2 서버에 Dockerfile_nginx로 이미지를 만들도록 docker-compose.nginx.yml 파일을 생성한다. (네트워크는 localhost 네트워크로 연결)
version: '3.7'
services:
nginx:
build:
context: .
dockerfile: Dockerfile_nginx
image: ozofweird/nginx:0.1
ports:
- "80:80"
container_name: nginx_springproject
network_mode: "host"
4) Dockerfile_nginx
EC2 서버에 Dockerfile_nginx 파일을 생성해준다. 보안 그룹에 80번 포트가 허용되어 있어야 한다.
- COPY로 설정 파일을 컨테이너로 복사
- VOLUME으로 log를 서버에서 확인할 수 있도록 컨테이너에 저장하지 않고 호스트에 저장
- EXPOSE로 호스트와 연결시킬 포트 번호 지정
- CMD 명령으로 컨테이너 구동 후 명령을 실행
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
VOLUME /var/log/nginx/log
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
5) 웹 서버 Nginx 실행
- -p 옵션으로 nginx 프로젝트명 지정
- -f 옵션으로 Compose 파일 지정
- -d 옵션으로 백그라운드 실행
sudo docker-compose -p nginx -f docker-compose.nginx.yml up -d
6) docker-compose.blue.yml
프로젝트 내부에 docker-compose.blue.yml 파일을 생성해준다.
version: '3.7'
services:
springproject:
build:
context: .
dockerfile: Dockerfile_springproject
args:
WAR_FILE: build/libs/springproject-1.0.1-SNAPSHOT.war
image: ozofweird/springproject:0.1
ports:
- "8082:8080"
container_name: springproject_blue
7) Dockerfile_springproject
프로젝트 내부에 Dockerfile_springproject 파일을 생성해준다.
FROM openjdk:8-jdk-alpine
ARG WAR_FILE=springproject-1.0.1-SNAPSHOT.war
COPY ${WAR_FILE} springproject.war
ENTRYPOINT ["java","-jar","-Dserver.port=8080","springproject.war"]
8) docker-compose.green.yml
프로젝트 내부에 docker-compose.green.yml 파일을 생성해준다.
version: '3.7'
services:
springproject:
build:
context: .
dockerfile: Dockerfile_springproject
args:
WAR_FILE: build/libs/springproject-1.0.1-SNAPSHOT.war
image: ozofweird/springproject:0.1
ports:
- "8081:8080"
container_name: springproject_green
9) deploy.sh
프로젝트 내부에 deploy.sh 파일을 생성해준다.
- EXIST_BLUE 동작 확인
- BlUE 서버가 동작할 경우 if
- BLUE 서버가 동작하지 않을 경우 else
#!/bin/bash
DOCKER_APP_NAME=springproject
EXIST_BLUE=$(/usr/local/bin/docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml ps | grep Up)
if [ -z "$EXIST_BLUE" ]; then
echo "blue up"
/usr/local/bin/docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml up -d --build
sleep 10
/usr/local/bin/docker-compose -p ${DOCKER_APP_NAME}-green -f docker-compose.green.yml down
else
echo "green up"
/usr/local/bin/docker-compose -p ${DOCKER_APP_NAME}-green -f docker-compose.green.yml up -d --build
sleep 10
/usr/local/bin/docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml down
fi
10) 구현 화면
깃허브에 push 할 때마다 변경이 되는 것을 확인할 수 있다.
[참고] bhsbhs235.github.io/