nginx+dockerを使用して無停止配置を設定する


参考サイト
クックカカガットのブログ

nginxインストール

brew install nginx

インストールパスの確認

nginx -t

無停止配備ロジック

  • 300ポートはaコンテナ、3001ポートはbコンテナです.
  • nginxは、逆プロキシを使用して9090ポートを3000または30001に接続します.
  • aコンテナが配備中である場合、bコンテナは飛ばされる.
  • nginxの9090ポートは、視野を変更します.
  • nginxロード
  • aダウングレード
  • 1.リバースプロキシのポートファイルを作成する


    nginxインストールのパスにconf.dフォルダを作成する
    conf.dにサービス-urlを提供します.incファイルを作成した後
    set $service_url http://127.0.0.1:3000;
    入力
    あとでshから現在起動しているコンテナのポートに切り替えます(3001ポート起動時は3000=>3001)
    「seds/」/「コマンド」を参照

    2.仮想ホストの設定


    nginxのパスをインストールこのサイト-使用可能なフォルダを作成
    このフォルダで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上のVerchualホストは

    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"]
    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のインストールパスサービス-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 
    bashの実行
    ./scripts/dev.sh