Docker 를 이용한 blue/green 배포 - 기본

LST·2023년 8월 28일
0

Docker 와 nginx를 이용한 fastapi 앱 무중단 blue/green 배포(1)

배포 과정

배포 과정은 의외로 간단하다
1. 배포 중인 처음 상태

2. 새로운 컨테이너를 띄운다

3. nginx 설정을 새로운 컨테이너로 연결하도록 변경한다. 이 과정에서 nginx reload 를 진행하는데 이때는 잠시 서버가 내려간다.(구글링해보니 0.1초 라곤 해도 중단되긴 한다. 그럼 엄밀히 무중단이 아니지 않나...?) 이 부분은 더 알아봐야겠다.

4. 기존의 컨테이너를 내린다. 이렇게 되면 최소한의 중단 시간으로 새롭게 배포

파일 구조

project
├── Dockerfile
├── main.py
├── docker-compose.yml
├── requirements.txt
└── nginx
    └── Dockerfile
    └── default.conf

Dockerfile

FROM python:3.10

WORKDIR /code

COPY ./requirements.txt /code/requirements.txt

RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt

COPY ./ /code

main.py

새로운 컨테이너와 기존의 컨테이너를 구분하기 위해 버전을 출력한다. 현재는 초기 상태이므로 old version을 출력하고 새로운 컨테이너를 띄울 땐 new version으로 변경해준다.

@app.get("/")
def root():
    return {"version": "OLD VERSION"}

docker-compose.yml

초기설정을 휘한 fastapi 앱과 nginx 컨테이너를 만든다.

version: '3.7'
services:
  fastapi:
    build:
      context: .
      dockerfile: Dockerfile
    command: uvicorn main:app --host 0.0.0.0
  nginx:
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
      - 80:80
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf

nginx/Dockerfile

nginx 이미지를 사용하고 작성한 default.conf 파일을 컨테이너에 복사한다.

FROM nginx
COPY ./default.conf /etc/nginx/conf.d/default.conf

nginx/default.conf

80번 포트로 요청이 들어오면 upstream에 있는 fastapi 컨테이너 8000번 포트에 연결한다.

upstream backend {
    server fastapi:8000;
}
server {
    listen 80;

    location / {
        proxy_pass http://backend;
    }
}

이렇게 설정하고 docker-compose를 실행하면 nginx, fastapi 컨테이너가 뜨고 localhost:80 을 통해 접속하면 old version이 출력된다.

여기까지가 기존의 컨테이너가 떠있는 상황(1번) 이다. 이 상태에서 새로운 컨테이너를 띄우기 위해 docker-compsoe 파일에 서비스를 추가하고 기존 fastapi 파일을 new version으로 변경한다.

  fastapi2:
    build:
      context: .
      dockerfile: Dockerfile
    command: uvicorn main:app --host 0.0.0.0
@app.get("/")
def root():
    return {"version": "NEW VERSION"}

docker-compose up --build -d fastapi2

그럼 nginx, fastapi, fastapi2 총 3개의 컨테이너가 존재한다. 이 상태에서 nginx 설정 파일을 수정하여 nginx가 새로운 컨테이너에 요청하도록 만든다. 그리고 nginx 컨테이너가 설정 파일을 다시 로드 하도록 명령을 날려준다.

upstream backend {
	server fastapi:8000 down;
    server fastapi2:8000;
}
server {
    listen 80;

    location / {
        proxy_pass http://backend;
    }
}

docker-compose exec nginx service nginx reload

이제 localhost:80 에 접속하면 new version이 출력된다.
그리고 기존의 컨테이너를 내리면 된다.

docker-compose rm -s fastapi

이렇게 되면 4번까지의 과정이 끝났다. 만약 새로운 버전이 배포된 후 롤백하고 싶다면 이 또한 간편하다. 다시 기존의 컨테이너를 띄우고 nginx 설정을 바꾸고 reload 하면 된다. 처음 빌드 했던 이미지가 있으므로 py 코드를 수정할 필요 없이 기존 이미지를 사용하면 된다.

docker-compose up -d fastapi

그리고 위에서처럼 nginx 설정파일을 수정하고 기존 컨테이너를 내리는 명령을 반복하면 다시 처음 버전의 앱이 실행된다.

0개의 댓글

관련 채용 정보