Docker, Nginx 사용 Blue-Green 배포

AFDB·2024년 11월 6일
post-thumbnail

Docker란?

애플리케이션과 그 실행 환경(설정, 라이브러리, OS 등)을 하나의 '컨테이너'에 포장하여, 어디서나 동일하게 실행될 수 있도록 해주는 도구.

처음엔 Docker 이미지와 컨테이너의 개념이 헷갈려서 제대로 정리하는 시간이 필요했다.

Docker image = 레시피
어떻게 준비하고 조리해야 하는지 알려주는 고정된 틀

  • Docker 이미지란, 특정 애플리케이션을 실행하기 위한 설정과 코드, 종속성들이 포함된 정적인 파일로 이 이미지는 마치 요리할 때 필요한 레시피 처럼, 애플리케이션을 어떻게 실행할지에 대한 지침서와 같다.

Docker container = 요리된 음식
레시피에 따라 실제로 만들어진 실행 환경

  • Docker 컨테이너는 이미지를 기반으로 실제 실행되는 환경이다. 이미지가 레시피라면, 컨테이너는 그 레시피에 따라 요리된 음식인 셈. 컨테이너는 이미지를 바탕으로 메모리에서 독립적으로 실행되는 애플리케이션으로, 실질적으로 실행되는 인스턴스다.

docker-compose.yml 파일은? = 레시피 북
파스타는 8000번 포트, 피자는 9000번 포트에서 제공해라!
레시피가 필요한 재료와 단계를 정의하듯, docker-compose.yml 파일은 어떤 컨테이너(Docker 이미지)를 사용할지, 그리고 각 컨테이너의 설정(포트, 네트워크, 볼륨 등)을 정의한다.

로컬에서

1. Docker 이미지 빌드

최신 코드를 가진 이미지를 로컬에 빌드한다.
docker build -t scar0329/backend-app:241106v2 .
여기서 app: 뒤에는 원하는 태그명을 넣는다.

2. 해당 이미지를 Docker hub로 push(태그명까지 동일하게)

그래야 배포서버의 도커에서도 이 최신 코드(이미지)를 pull할 수 있다.
docker push scar0329/backend-app:241106v2


배포서버에서

1. 방금 허브에 푸시된 최신 코드(이미지) pull 받기

sudo docker pull scar0329/backend-app:241106v2
그러면 241106v2라는 태그를 가진 새로운 이미지가 잘 추가되었고,

REPOSITORY              TAG        IMAGE ID       CREATED             SIZE
scar0329/backend-app    241106     c3633d8a7906   About an hour ago   1.98GB
ubuntu-nginx            latest     b3d5b8ea1752   20 hours ago        219MB
scar0329/backend-app    241106v2   0ba7d46a2e34   24 hours ago        1.98GB
scar0329/frontend-app   latest     92db08e6b046   26 hours ago        2.14GB

2. 최신 이미지의 태그를 참조해서 컨테이너를 실행할 수 있도록 설정

미리 생성해둔 docker-compose.yml 파일에 bluegreen 컨테이너에 대해 참조할 태그 이름을 설정해뒀으므로, 이 설정을 변경해준다.
(🤔 참고로 새 태그를 가진 이미지를 실행할 때마다 설정을 바꾸는 것은 비효율적이므로 최종적으로는 CI/CD 도구를 사용해 자동화해야한다.)
nano docker-compose.yml

version: '3'
services:
  backend_blue:
    image: scar0329/backend-app:241106
    container_name: backend_blue
    ports:
      - "3001:3001"
    env_file:
      - /home/ubuntu/envs/backend.env
    networks:
      - app-network

  backend_green:
    image: scar0329/backend-app:241106v2
    container_name: backend_green
    ports:
      - "3002:3001"
    env_file:
      - /home/ubuntu/envs/backend.env
    networks:
      - app-network

  nginx:
    build: ./nginx
    container_name: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    networks:
      - app-network

위 설정에서, 현재 사용중인 blue 말고, 최신화된 이미지를 green으로 실행시켜야하니, backend_green 부분에서 태그명을 241106v2로 수정해준다.

3. 이제 최신 이미지로 컨테이너 실행

sudo docker-compose up -d backend_green
backend_green으로 실행하면 최신 241106v2 태그를 가진 컨테이너가 실행된다. (위에서 미리 dcoker-compose.yml 파일에서 backend_green241106v2태그를 참조할 수 있게 설정해둔 덕분에)
잘 작동하는지 확인해주고, sudo docker ps
이제 이전 코드인 blue와 최신 코드인 green 컨테이너가 모두 실행 중이다.
현재는 nginx의 업스트림이 blue로만 트래픽을 보내고 있기 때문에 아직은 이전 코드로 실행 중이다.

4. nginx가 backend_green로 트래픽을 보낼 수 있도록 업스트림 수정

cd nginx, nano nginx.conf

    upstream backend {
#       server backend_blue:3001;
        server backend_green:3001;
    }

green으로 트래픽을 보내야하므로 기존의 blue를 주석처리한다.

5. nginx 설정 리로드

sudo docker exec nginx nginx -s reload

docker-compose.yml 파일에서 nginx 서비스에 대한 볼륨 마운트를

    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf

이렇게 설정해둔 덕분에 호스트에서 nginx.conf 파일을 변경하면 컨테이너 내부에도 반영된다.
덕분에 blue를 주석처리한 변경사항이 바로 적용되고, 배포가 끊기지 않는다.

5. 이전 코드 컨테이너 종료, 삭제, 이미지 삭제

sudo docker-compose stop backend_블루나 그린
sudo docker-compose rm backend_블루나 그린
sudo docker image prune -a 사용하지 않는 모든 이미지 삭제

0개의 댓글