nginx+docker으로 무중단 배포 설정
참고한 싸이트
쿠크캬캬 갓의 블로그
nginx 설치
brew install nginx
설치경로 확인
nginx -t
brew install nginx
nginx -t
무중단 배포 로직
- 3000포트는 a컨테이너를 3001포트는 b컨테이너를 바라본다.
- nginx 는 리버스 프록시로 9090포트를 3000또는 30001 으로 연결시켜준다.
- a컨테이너가 배포중이였다면 b컨테이너를 띄운다.
- nginx의 9090포트가 바라보는 포트를 바꿔준다.
- nginx 리로드
- a컨테이터 down
1. 리버스 프록시할 포트파일 작성
nginx가 설치된 경로에 conf.d 폴더 생성
conf.d에 service-url.inc 파일을 생성후
set $service_url http://127.0.0.1:3000;
을 입력
이후 .sh 에서 현재 시작하는 컨테이너의 포트로 갈아끼워줌(3001포트가 시작하면 3000=>3001으로 바뀜)
sed s/""/""/ 명령어 참고
2. 버츄얼 호스트 설정
nginx가 설치된 경로이 sites-available폴더를 생성
해당 폴더에 kuke.conf 생성후 작성
server {
listen 9090 default_server;
// 1번에서 작성한 파일을 불러온다.
include /usr/local/etc/nginx/conf.d/service-url.inc;
server_name ...;
charset utf-8;
location / {
//9090포트가 패스할 url 1번에서 작성한 파일의 변수를 프록시패스로 설정
proxy_pass $service_url;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header x-Forwarded-For $proxy_add_x_forwarded_$
proxy_set_header Host $host;
}
}
4. nginx.conf 에 버츄얼 호스트 include
http {
...
# virtual host configs
include /usr/local/etc/nginx/sites-available/*;
include /usr/local/etc/nginx/conf.d/*.conf;
...
}
3. 도커파일 작성 (프로젝트 루트디렉토리)
// 베이스 이미지는 Node
FROM node:alpine
// 포트는 3000번
ENV PORT 3000
RUN apk --no-cache add tzdata && \
cp /usr/share/zoneinfo/Asia/Seoul /etc/localtime && \
echo "Asia/Seoul" > /etc/timezone
// 워킹 디렉토리 설정(이 경로에서 다음 명령어를 진행)
WORKDIR /usr/src/app
// 워킹 디렉토리에 패키지제이선 카피
COPY package*.json ./
// 인스톨 진행
RUN npm install
// 루트 디렉토리를 컨테이너로 카피
COPY ./ ./
// ENV환경을 프로덕션을 설정
ENV NODE_ENV production
// 빌드
RUN npm run build
// 스타트
CMD ["npm", "run", "start"]
http {
...
# virtual host configs
include /usr/local/etc/nginx/sites-available/*;
include /usr/local/etc/nginx/conf.d/*.conf;
...
}
// 베이스 이미지는 Node
FROM node:alpine
// 포트는 3000번
ENV PORT 3000
RUN apk --no-cache add tzdata && \
cp /usr/share/zoneinfo/Asia/Seoul /etc/localtime && \
echo "Asia/Seoul" > /etc/timezone
// 워킹 디렉토리 설정(이 경로에서 다음 명령어를 진행)
WORKDIR /usr/src/app
// 워킹 디렉토리에 패키지제이선 카피
COPY package*.json ./
// 인스톨 진행
RUN npm install
// 루트 디렉토리를 컨테이너로 카피
COPY ./ ./
// ENV환경을 프로덕션을 설정
ENV NODE_ENV production
// 빌드
RUN npm run build
// 스타트
CMD ["npm", "run", "start"]
CMD ["npm", "run", "start"] 는
아래 스크립트를 실행
"start": "next start -p 8080",
4. docker-compose a/b파일 작성(루트 디렉토리)
docker-compose.a.yml 작성
version: "3"
services:
// 서비스 명
kuke:
// 루트 디렉토리의 dockerfile을 실행
build: .
ports:
- 3000:8080
docker-compose.b.yml 작성
version: "3"
services:
// 서비스 명
kuke:
// 루트 디렉토리의 dockerfile을 실행
build: .
ports:
- 3001:8080
5. .sh파일 작성(프로젝트 디렉토리에 ./scirpts 폴더안에 작성)
아래 파일을 작성시 nginx의 설치경로에 따라 service-url.inc의 경로를 잡아주어야한다
(설지방법 환경에따라 nginx의 경로가 달라진다)
# 실행 중인 도커 컴포즈 확인
EXIST_A=$(sudo docker-compose -p kukemeet-a -f docker-compose.a.yml ps | grep Up)
if [ -z "${EXIST_A}" ] # -z는 문자열 길이가 0이면 true. A가 실행 중이지 않다는 의미.
then
# B가 실행 중인 경우
START_CONTAINER=a
TERMINATE_CONTAINER=b
START_PORT=3000
TERMINATE_PORT=3001
else
# A가 실행 중인 경우
START_CONTAINER=b
TERMINATE_CONTAINER=a
START_PORT=3001
TERMINATE_PORT=3000
fi
echo "kukemeet-${START_CONTAINER} up"
# 실행해야하는 컨테이너 docker-compose로 실행. -p는 docker-compose 프로젝트에 이름을 부여
# -f는 docker-compose파일 경로를 지정
sudo docker-compose -p kukemeet-${START_CONTAINER} -f docker-compose.${START_CONTAINER}.yml up -d --build
sleep 5 # 실행되었으면 5초 대기
echo "next start!"
echo "change nginx server port"
# sed 명령어를 이용해서 아까 지정해줬던 service-url.inc의 url값을 변경해줍니다.
# sed -i "s/기존문자열/변경할문자열" 파일경로 입니다.
# 종료되는 포트를 새로 시작되는 포트로 값을 변경해줍니다.
# -i.bak 는 백업파일을 만들겠다는 의미입니다.(그래야 변경값이 저장됨)
sudo sed -i.bak "s/${TERMINATE_PORT}/${START_PORT}/" /usr/local/etc/nginx/conf.d/service-url.inc
echo "${TERMINATE_PORT} and ${START_PORT}"
# 새로운 포트로 nextjs 앱이 구동 되고, nginx의 포트를 변경해주었다면, nginx를 재시작해줍니다.
echo "nginx reload.."
sudo nginx -s reload
# 기존에 실행 중이었던 docker-compose는 종료시켜줍니다.
echo "kukemeet-${TERMINATE_CONTAINER} down"
sudo docker-compose -p kukemeet-${TERMINATE_CONTAINER} -f docker-compose.${TERMINATE_CONTAINER}.yml down
echo "success deployment"
6. 실행
아래 파일을 작성시 nginx의 설치경로에 따라 service-url.inc의 경로를 잡아주어야한다
(설지방법 환경에따라 nginx의 경로가 달라진다)
# 실행 중인 도커 컴포즈 확인
EXIST_A=$(sudo docker-compose -p kukemeet-a -f docker-compose.a.yml ps | grep Up)
if [ -z "${EXIST_A}" ] # -z는 문자열 길이가 0이면 true. A가 실행 중이지 않다는 의미.
then
# B가 실행 중인 경우
START_CONTAINER=a
TERMINATE_CONTAINER=b
START_PORT=3000
TERMINATE_PORT=3001
else
# A가 실행 중인 경우
START_CONTAINER=b
TERMINATE_CONTAINER=a
START_PORT=3001
TERMINATE_PORT=3000
fi
echo "kukemeet-${START_CONTAINER} up"
# 실행해야하는 컨테이너 docker-compose로 실행. -p는 docker-compose 프로젝트에 이름을 부여
# -f는 docker-compose파일 경로를 지정
sudo docker-compose -p kukemeet-${START_CONTAINER} -f docker-compose.${START_CONTAINER}.yml up -d --build
sleep 5 # 실행되었으면 5초 대기
echo "next start!"
echo "change nginx server port"
# sed 명령어를 이용해서 아까 지정해줬던 service-url.inc의 url값을 변경해줍니다.
# sed -i "s/기존문자열/변경할문자열" 파일경로 입니다.
# 종료되는 포트를 새로 시작되는 포트로 값을 변경해줍니다.
# -i.bak 는 백업파일을 만들겠다는 의미입니다.(그래야 변경값이 저장됨)
sudo sed -i.bak "s/${TERMINATE_PORT}/${START_PORT}/" /usr/local/etc/nginx/conf.d/service-url.inc
echo "${TERMINATE_PORT} and ${START_PORT}"
# 새로운 포트로 nextjs 앱이 구동 되고, nginx의 포트를 변경해주었다면, nginx를 재시작해줍니다.
echo "nginx reload.."
sudo nginx -s reload
# 기존에 실행 중이었던 docker-compose는 종료시켜줍니다.
echo "kukemeet-${TERMINATE_CONTAINER} down"
sudo docker-compose -p kukemeet-${TERMINATE_CONTAINER} -f docker-compose.${TERMINATE_CONTAINER}.yml down
echo "success deployment"
서버실행
nginx
bash 실행
./scripts/dev.sh
Author And Source
이 문제에 관하여(nginx+docker으로 무중단 배포 설정), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jmyoon8/nginxdocker으로-무중단-배포-설정저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)