kimyu0218
  • [CD] 블루/κ·Έλ¦° 무쀑단 배포 κ΅¬ν˜„ν•˜κΈ° 2편 (GitHub Actions/Shell Script)
    2024λ…„ 01μ›” 08일 00μ‹œ 02λΆ„ 16μ΄ˆμ— μ—…λ‘œλ“œ 된 κΈ€μž…λ‹ˆλ‹€.
    μž‘μ„±μž: @kimyu0218
    πŸ”— [CD] 블루/κ·Έλ¦° 무쀑단 배포 κ΅¬ν˜„ν•˜κΈ° 1편 (NGINX/Docker Compose)

    이번 ν¬μŠ€νŒ…μ—μ„œλŠ” 1νŽΈμ—μ„œ μž‘μ„±ν•œ 도컀 컴포즈 νŒŒμΌμ„ λ°”νƒ•μœΌλ‘œ 블루/κ·Έλ¦° 무쀑단 배포λ₯Ό κ΅¬ν˜„ν•  것이닀.
     

    GitHub Actionsλž€?

    κΉƒν—™ μ•‘μ…˜μ€ κΉƒν—™μ—μ„œ μ œκ³΅ν•˜λŠ” μžλ™ν™” λ„κ΅¬λ‘œ, λΉŒλ“œ, ν…ŒμŠ€νŠΈ, 배포 νŒŒμ΄ν”„λΌμΈμ„ μžλ™ν™”ν•  수 μžˆλ‹€. κΉƒν—™ μ•‘μ…˜μ€ νŠΉμ • μ΄λ²€νŠΈκ°€ λ°œμƒν•˜λ©΄ μ•‘μ…˜μ„ μžλ™μœΌλ‘œ μ‹€ν–‰ν•˜κ²Œ λ˜λŠ”λ°, 이λ₯Ό ν™œμš©ν•˜μ—¬ νŠΉμ • λΈŒλžœμΉ˜μ— μ½”λ“œκ°€ push λ˜μ—ˆμ„ λ•Œ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ 배포할 수 μžˆλ‹€. 이외에도 λ ˆν¬μ§€ν† λ¦¬μ— μ΄μŠˆκ°€ 생성될 λ•Œλ§ˆλ‹€ μžλ™μœΌλ‘œ μ μ ˆν•œ 라벨을 λΆ™μ—¬μ£ΌλŠ” λ“±μ˜ μ›Œν¬ν”Œλ‘œμš°λ₯Ό λ§Œλ“€ 수 μžˆλ‹€.

    workflow

    μ›Œν¬ν”Œλ‘œμš°λŠ” ν•˜λ‚˜ μ΄μƒμ˜ μž‘μ—…μ„ μ‹€ν–‰ν•˜λŠ” μžλ™ν™”λœ ν”„λ‘œμ„ΈμŠ€λ‹€. `.github/workflows` 디렉토리에 YAML 파일둜 μž‘μ„±ν•˜λ©° λ ˆν¬μ§€ν† λ¦¬μ— μ΄λ²€νŠΈκ°€ λ°œμƒν•˜λ©΄ μ‹€ν–‰λœλ‹€.

    runner

    λŸ¬λ„ˆλŠ” μ›Œν¬ν”Œλ‘œμš°λ₯Ό μ‹€ν–‰ν•˜λŠ” μ„œλ²„λ‘œ, ν•œ λ²ˆμ— ν•˜λ‚˜μ˜ μž‘μ—…μ„ μˆ˜ν–‰ν•œλ‹€.

    🚨 λ™μΌν•œ λŸ¬λ„ˆλ₯Ό μ‚¬μš©ν•˜λŠ” μž‘μ—… λ‚΄μ—μ„œλŠ” 데이터λ₯Ό κ³΅μœ ν•  수 μžˆλ‹€. ν•˜μ§€λ§Œ ν™˜κ²½λ³€μˆ˜ 등을 ν™œμš©ν•˜μ—¬ μ—¬λŸ¬ μž‘μ—… 간에 데이터λ₯Ό κ³΅μœ ν•  μˆ˜λ„ μžˆλ‹€.

    job

    μž‘μ—…μ€ μ›Œν¬ν”Œλ‘œμš° λ‚΄μ—μ„œ μ‹€ν–‰λ˜λŠ” κ°œλ³„ μž‘μ—…μ΄λ‹€. μž‘μ—…μ€ λ³‘λ ¬μ μœΌλ‘œ μ‹€ν–‰λ˜λŠ”λ° λ‹€λ₯Έ μž‘μ—…μ΄ μ„ ν–‰λ˜μ–΄μ•Ό ν•˜λŠ” 경우, `needs` μ˜΅μ…˜μ„ ν™œμš©ν•˜μ—¬ μž‘μ—…μ΄ 순차적으둜 μ‹€ν–‰λ˜λ„λ‘ κ΅¬ν˜„ν•  수 μžˆλ‹€.

    step

    λ‹¨κ³„λŠ” μž‘μ—… λ‚΄μ—μ„œ μ‹€ν–‰λ˜λŠ” κ°œλ³„ μ•‘μ…˜μ„ μ˜λ―Έν•œλ‹€.

    action

    μ•‘μ…˜μ€ μΌμ’…μ˜ μ‚¬μš©μž μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ΄λ‹€. 직접 μ•‘μ…˜μ„ μž‘μ„±ν•  μˆ˜λ„ μžˆμ§€λ§Œ κΉƒν—ˆλΈŒμ˜ λ§ˆμΌ“ ν”Œλ ˆμ΄μŠ€μ—μ„œ μ•‘μ…˜μ„ 가져와 μ‚¬μš©ν•˜λŠ” λ“± μ™ΈλΆ€ μ•‘μ…˜μ„ μ‚¬μš©ν•  μˆ˜λ„ μžˆλ‹€.

    event

    μ΄λ²€νŠΈλŠ” μ›Œν¬ν”Œλ‘œμš°λ₯Ό μ‹€ν–‰ν•˜λŠ” 트리거λ₯Ό μ˜λ―Έν•œλ‹€. μ½”λ“œ ν‘Έμ‹œ, PR 생성 등이 μ΄λ²€νŠΈμ— ν•΄λ‹Ήλœλ‹€.


    블루/κ·Έλ¦° 배포λ₯Ό μœ„ν•œ μ›Œν¬ν”Œλ‘œμš° μž‘μ„±ν•˜κΈ°

    λ‘œμ»¬μ—μ„œ μ†ŒμŠ€μ½”λ“œλ₯Ό λΉŒλ“œν•˜κ³ , 원격 μ„œλ²„μ—μ„œ λΉŒλ“œ 결과물을 μ‹€ν–‰ν•˜λŠ” λ“± μˆ˜λ™μœΌλ‘œ λ°°ν¬ν•˜λŠ” 방법도 μ‘΄μž¬ν•œλ‹€. ν•˜μ§€λ§Œ μ΄λŠ” 맀우 번거둜운 과정인데닀가 개발자의 μ‹€μˆ˜κ°€ λ°œμƒν•  수 μžˆμ–΄ μΌκ΄€λœ 배포λ₯Ό 보μž₯ν•  수 μ—†λ‹€. λ”°λΌμ„œ κΉƒν—™ μ•‘μ…˜μœΌλ‘œ 배포 과정을 μžλ™ν™”ν•˜μ—¬ μ‹ μ†ν•˜κ³  μΌκ΄€λœ 배포λ₯Ό μ œκ³΅ν•΄λ³΄μž.

    배포 과정을 μžλ™ν™”ν–ˆμ„ λ•Œμ˜ 이점
    • μ‹ μ†ν•œ 배포 : μžλ™ν™”λœ 배포 ν”„λ‘œμ„ΈμŠ€λ‘œ λΉ λ₯΄κ²Œ 배포할 수 μžˆλ‹€.
    • μΌκ΄€λœ 배포 ν’ˆμ§ˆ : 개발자 μ‹€μˆ˜λ₯Ό 쀄이고 μΌκ΄€λœ 배포 ν™˜κ²½μ„ μ‚¬μš©ν•¨μœΌλ‘œμ¨ 예츑 κ°€λŠ₯ν•˜κ³  μ•ˆμ •μ μΈ 배포λ₯Ό 보μž₯ν•œλ‹€.
    • μžμ› μ ˆμ•½ : 반볡적이고 번거둜운 μž‘μ—…λ“€μ„ μžλ™ν™”ν•˜μ—¬ 개발자의 μ‹œκ°„κ³Ό λ…Έλ ₯을 μ ˆμ•½ν•  수 μžˆλ‹€.

     

    배포 μ›Œν¬ν”Œλ‘œμš°

    μœ„μ˜ μ΄λ―Έμ§€λŠ” 배포 μ›Œν¬ν”Œλ‘œμš°λ₯Ό λ‹€μ΄μ–΄κ·Έλž¨μœΌλ‘œ λ‚˜νƒ€λ‚Έ 것이닀. νŠΉμ • 브랜치둜 push λ˜μ—ˆμ„ λ•Œ μ‹€ν–‰λ˜λ©°, build와 deploy μž‘μ—…μœΌλ‘œ κ΅¬μ„±λ˜μ–΄ μžˆλ‹€.

    name: Blue/Green CD
    
    on:
      push:
        paths: ["backend/**"]
        branches: ["dev"]
    
    env:
      DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
      GITHUB_SHA: ${{ github.sha }}
    
    jobs:
      build:
        runs-on: ubuntu-latest
    
        steps:
          - name: Checkout code
            uses: actions/checkout@v4
    
          - name: Generate .env file and SSL files
            run: |
              cd backend
              echo "${{ secrets.ENV_FILE }}" > .env
              echo "DOCKER_USERNAME=${{ secrets.DOCKER_USERNAME }}" >> .env
              echo "GITHUB_SHA=${{ github.sha }}" >> .env
              mkdir -p config/nginx/ssl/
              echo "${{ secrets.SSL_OPTIONS }}" > config/nginx/ssl/options-ssl-nginx.conf
              echo "${{ secrets.SSL_FULLCHAIN }}" > config/nginx/ssl/fullchain.pem
              echo "${{ secrets.SSL_PRIVKEY }}" > config/nginx/ssl/privkey.pem
              echo "${{ secrets.SSL_DHPARAMS }}" > config/nginx/ssl/ssl-dhparams.pem
    
          - name: Add Remote Host Key to known_hosts
            run: |
              mkdir -p ~/.ssh
              echo "${{ secrets.SSH_PUBLIC_KEY }}" >> ~/.ssh/known_hosts
    
          - name: Copy some files needed for Deployment to Remote Server
            uses: appleboy/scp-action@master
            with:
              host: ${{ secrets.SSH_HOST }}
              username: ${{ secrets.SSH_USERNAME }}
              key: ${{ secrets.SSH_PRIVATE_KEY }}
              port: ${{ secrets.SSH_PORT }}
              source: "backend/.env,backend/deploy.sh,backend/config,backend/compose.blue-deploy.yml,backend/compose.green-deploy.yml,backend/Dockerfile.nginx"
              target: "~/app/"
              overwrite: true
    
          - name: Login to Docker Hub
            uses: docker/login-action@v3
            with:
              username: ${{ secrets.DOCKER_USERNAME }}
              password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
    
          - name: Build & Push Docker Images (Blue & Green)
            run: |
              cd backend
              docker-compose -f compose.blue-build.yml build
              docker-compose -f compose.green-build.yml build
              docker-compose -f compose.blue-build.yml push
              docker-compose -f compose.green-build.yml push
    
      deploy:
        needs: build
        runs-on: ubuntu-latest
    
        steps:
          - name: Login to Docker Hub
            uses: docker/login-action@v3
            with:
              username: ${{ secrets.DOCKER_USERNAME }}
              password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
    
          - name: Run a New Version of the application on Remote Server
            uses: appleboy/ssh-action@master
            with:
              host: ${{ secrets.SSH_HOST }}
              username: ${{ secrets.SSH_USERNAME }}
              key: ${{ secrets.SSH_PRIVATE_KEY }}
              port: ${{ secrets.SSH_PORT }}
              script: |
                cd ~/app/backend
                chmod +x deploy.sh
                source deploy.sh

    build μž‘μ—… μž‘μ„±ν•˜κΈ°

    λΉŒλ“œ μž‘μ—…μ€ 도컀 이미지λ₯Ό λΉŒλ“œν•˜κ³  도컀 ν—ˆλΈŒμ— ν‘Έμ‹œν•˜λŠ” 역할이닀. λ‹¨κ³„λ³„λ‘œ ν•˜λ‚˜μ”© μ‚΄νŽ΄λ³΄μž.

     

    Checkout code

    체크아웃은 λ ˆν¬μ§€ν† λ¦¬μ˜ νŠΉμ • 브랜치, 컀밋 등을 κ°€μ Έμ˜€λŠ” μž‘μ—…μ΄λ‹€. 즉, μ›Œν¬ν”Œλ‘œμš°κ°€ 싀행될 λ•Œμ˜ μƒνƒœλ₯Ό κ°€μ Έμ˜¨λ‹€. 일반적으둜 `actions/checkout` μ•‘μ…˜μ„ μ΄μš©ν•œλ‹€.
     

    Generate .env file and SSL files

    κΉƒν—™ μ‹œν¬λ¦Ώμ„ μ΄μš©ν•˜μ—¬ env 파일과 ssl νŒŒμΌμ„ μƒμ„±ν•˜λŠ” μž‘μ—…μ΄λ‹€. 원격 μ„œλ²„μ— μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λ°°ν¬ν•˜κΈ° μœ„ν•΄μ„œλŠ” ν™˜κ²½λ³€μˆ˜λ“€μ„ μ „λ‹¬ν•΄μ€˜μ•Ό ν•œλ‹€. ν•˜μ§€λ§Œ env νŒŒμΌμ€ λ ˆν¬μ§€ν† λ¦¬μ— μ˜¬λΌκ°€λ©΄ μ•ˆλ˜λŠ” λ―Όκ°ν•œ 정보듀을 λ‹΄κ³  μžˆλ‹€. λ”°λΌμ„œ κΉƒν—™ μ‹œν¬λ¦Ώμ„ μ΄μš©ν•˜μ—¬ env νŒŒμΌμ„ 생성해야 ν•œλ‹€.
     

    Add Remote Host Key to known_hosts

    ssh둜 원격 μ„œλ²„μ— μ ‘μ†ν•˜κΈ° μœ„ν•΄μ„œλŠ” `/.ssh/known_hosts` 파일이 ν•„μš”ν•˜λ‹€. ν•΄λ‹Ή νŒŒμΌμ€ ν΄λΌμ΄μ–ΈνŠΈκ°€ μ„œλ²„μ˜ 신뒰성을 ν™•μΈν•˜λŠ” 데 μ‚¬μš©λ˜λ©° 원격 μ„œλ²„μ˜ κ³΅κ°œν‚€λ₯Ό μ €μž₯ν•œλ‹€.
     

    Copy some files needed for Deployment to Remote Server

    ν™˜κ²½λ³€μˆ˜, 배포 슀크립트 λ“± 배포할 λ•Œ ν•„μš”ν•œ νŒŒμΌλ“€μ„ 원격 μ„œλ²„μ— μ „λ‹¬ν•˜λŠ” μž‘μ—…μ΄λ‹€.
     

    Login to Docker Hub

    λ‹€μŒ λ‹¨κ³„μ—μ„œ 도컀 ν—ˆλΈŒμ— 이미지λ₯Ό ν‘Έμ‹œν•΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— 도컀 ν—ˆλΈŒμ— λ‘œκ·ΈμΈν•œλ‹€.
     

    Build & Push Docker Images (Blue & Green)

    도컀 컴포즈 νŒŒμΌμ„ λ°”νƒ•μœΌλ‘œ 블루 버전, κ·Έλ¦° 버전 이미지λ₯Ό λΉŒλ“œν•œλ‹€. 이미지λ₯Ό λΉŒλ“œν•œ ν›„, μƒμ„±λœ 이미지λ₯Ό 도컀 ν—ˆλΈŒμ— ν‘Έμ‹œν•œλ‹€. 좔후에 원격 μ„œλ²„μ—μ„œ ν‘Έμ‹œλœ 이미지λ₯Ό 가져와 μ‹€ν–‰ν•˜κ²Œ λœλ‹€.


    deploy μž‘μ—… μž‘μ„±ν•˜κΈ°

    배포 μž‘μ—…μ€ 도컀 ν—ˆλΈŒλ‘œλΆ€ν„° 이미지λ₯Ό 가져와 μ»¨ν…Œμ΄λ„ˆλ₯Ό μ‹€ν–‰ν•œλ‹€.

     

    Login to Docker Hub

    λ‹€μŒ λ‹¨κ³„μ—μ„œ 도컀 ν—ˆλΈŒμ— μ ‘κ·Όν•˜μ—¬ 이미지λ₯Ό 가져와야 ν•˜λ―€λ‘œ 도컀 ν—ˆλΈŒμ— λ‘œκ·ΈμΈν•œλ‹€.
     

    Run a New Version of the application on Remote Server

    μ‰˜ 슀크립트λ₯Ό μ‹€ν–‰ν•˜μ—¬ μƒˆλ‘œμš΄ λ²„μ „μ˜ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λ°°ν¬ν•˜λŠ” μž‘μ—…μ΄λ‹€. `deploy.sh` νŒŒμΌμ„ μ‹€ν–‰ν•˜κΈ° μœ„ν•΄μ„œλŠ” 사전에 μ‹€ν–‰κΆŒν•œμ„ λΆ€μ—¬ν•΄μ€˜μ•Ό ν•œλ‹€.


    블루/κ·Έλ¦° 배포 μ‰˜ 슀크립트 μž‘μ„±ν•˜κΈ°

    κΉƒν—™ μ•‘μ…˜μ˜ 배포 μŠ€ν¬λ¦½νŠΈκ°€ λ„ˆλ¬΄ κΈΈμ–΄μ Έμ„œ `deploy.sh`λΌλŠ” λ³„λ„μ˜ 파일둜 λΆ„λ¦¬ν–ˆλ‹€. μœ„μ˜ deploy μž‘μ—…μ—μ„œ ν•΄λ‹Ή μ‰˜ 슀크립트λ₯Ό μ‹€ν–‰ν•˜μ—¬ 블루/κ·Έλ¦° 배포λ₯Ό μˆ˜ν–‰ν•œλ‹€.
     

    μ„œλ²„μ—μ„œ 싀행쀑인 버전 ν™•μΈν•˜κΈ°

    도컀 λͺ…λ Ήμ–΄λ₯Ό μ΄μš©ν•˜μ—¬ μ„œλ²„μ—μ„œ μ–΄λ–€ 버전이 μ‹€ν–‰ 쀑인지 ν™•μΈν•œλ‹€. 이름에 blueλΌλŠ” λ¬Έμžμ—΄μ΄ ν¬ν•¨λœ 경우, 블루 버전이 μ‹€ν–‰μ€‘μ΄λ―€λ‘œ κ·Έλ¦° λ²„μ „μ—μ„œ μ‹ κ·œ λ²„μ „μ˜ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λ„μ›Œμ•Ό ν•œλ‹€. λ°˜λŒ€μ˜ κ²½μš°μ—” 블루 λ²„μ „μ—μ„œ μ‹ κ·œ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ‹€ν–‰ν•œλ‹€.

    if sudo docker ps --filter "name=blue" --format '{{.ID}}' | grep -E .; then
      RUN_TARGET="green"
      STOP_TARGET="blue"
      WAS_RUN_PORT=3002
      WAS_STOP_PORT=3000
    else
      RUN_TARGET="blue"
      STOP_TARGET="green"
      WAS_RUN_PORT=3000
      WAS_STOP_PORT=3002
    fi

    `RUN_TARGET`은 μ‹ κ·œ 버전이 μ‹€ν–‰λ˜λŠ” 버전을, `STOP_TARGET`은 ꡬ버전이 μ‹€ν–‰λ˜λŠ” 버전을 μ˜λ―Έν•œλ‹€.
     

    μ‹ κ·œ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜ λ„μš°κΈ°

    μ•žμ—μ„œ μ‹ κ·œ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ–΄λ””μ„œ λ„μ›Œμ•Ό ν•˜λŠ”μ§€ μ•Œμ•„λƒˆλ‹€. 이제 도컀 λͺ…λ Ήμ–΄λ₯Ό μ΄μš©ν•˜μ—¬ μ»¨ν…Œμ΄λ„ˆλ₯Ό μ‹€ν–‰ν•  것이닀.

    DOCKER_COMPOSE_FILE="compose.$RUN_TARGET-deploy.yml"
    
    sudo docker-compose -f "$DOCKER_COMPOSE_FILE" pull
    sudo docker-compose -f "$DOCKER_COMPOSE_FILE" up -d

    도컀 컴포즈 νŒŒμΌμ„ μ΄μš©ν•˜μ—¬ 도컀 ν—ˆλΈŒλ‘œλΆ€ν„° 이미지λ₯Ό κ°€μ Έμ˜€κ³  μ»¨ν…Œμ΄λ„ˆλ₯Ό μ‹€ν–‰ν•œλ‹€.

     

    NGINXλ₯Ό μ΄μš©ν•˜μ—¬ νŠΈλž˜ν”½ μ „ν™˜ν•˜κΈ°

    μ‹ κ·œ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ‹€ν–‰λ˜κ³  λ‚˜λ©΄ κΈ°μ‘΄ λ²„μ „μœΌλ‘œ κ°€λ˜ νŠΈλž˜ν”½μ„ μ‹ κ·œ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ ν–₯ν•˜λ„λ‘ μˆ˜μ •ν•΄μ•Ό ν•œλ‹€.

    NGINX_ID=$(sudo docker ps --filter "name=nginx" --quiet)
    NGINX_CONFIG="/etc/nginx/conf.d/default.conf"
    
    sudo docker exec $NGINX_ID /bin/bash -c "sed -i 's/was-$STOP_TARGET:$WAS_STOP_PORT/was-$RUN_TARGET:$WAS_RUN_PORT/' $NGINX_CONFIG"
    sudo docker exec $NGINX_ID /bin/bash -c "sed -i 's/signal-$STOP_TARGET:$((WAS_STOP_PORT + 1))/signal-$RUN_TARGET:$((WAS_RUN_PORT + 1))/' $NGINX_CONFIG"
    sudo docker exec $NGINX_ID /bin/bash -c "nginx -s reload"

    μ—”μ§„μ—‘μŠ€λ„ μ»¨ν…Œμ΄λ„ˆμ—μ„œ μ‹€ν–‰ 쀑이기 λ•Œλ¬Έμ— 이름에 nginxκ°€ ν¬ν•¨λœ μ»¨ν…Œμ΄λ„ˆμ˜ 아이디λ₯Ό μ‘°νšŒν•œλ‹€. 이제 `sudo docker exec`λ₯Ό μ΄μš©ν•˜μ—¬ μ—”μ§„μ—‘μŠ€ μ»¨ν…Œμ΄λ„ˆμ˜ μ„€μ •νŒŒμΌμ„ μˆ˜μ •ν•œλ‹€.
     
    λ§Œμ•½ ꡬ버전이 블루 λ²„μ „μ—μ„œ 싀행쀑이라면 μ—”μ§„μ—‘μŠ€λŠ” `was-blue:3000`κ³Ό `signal-blue:3001`둜 ν”„λ‘μ‹œν•œλ‹€. νŠΈλž˜ν”½μ„ μ „ν™˜ν•˜κΈ° μœ„ν•΄ `sed -i`둜 `was-blue:3000`을 `was-green:3002`, `signal-blue:3001`을 `signal-green:3003`둜 μΉ˜ν™˜ν•˜μ—¬ κ·Έλ¦° λ²„μ „μœΌλ‘œ ν”„λ‘μ‹œν•˜λ„λ‘ λ³€κ²½ν•œλ‹€. λ§ˆμ§€λ§‰μœΌλ‘œ μˆ˜μ •λœ μ„€μ •νŒŒμΌμ„ λ°˜μ˜ν•˜κΈ° μœ„ν•΄ μ—”μ§„μ—‘μŠ€λ₯Ό λ¦¬λ‘œλ“œν•œλ‹€.

     

    κ΅¬λ²„μ „μ˜ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜ μ’…λ£Œν•˜κΈ°

    이전 λ‹¨κ³„λ‘œ 인해 νŠΈλž˜ν”½μ΄ μ‹ κ·œ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ ν–₯ν•˜λ„λ‘ λ³€κ²½λ˜μ—ˆλ‹€. 이제 더 이상 μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” κ΅¬λ²„μ „μ˜ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ’…λ£Œν•˜λŠ” μž‘μ—…λ§Œ λ‚¨μ•˜λ‹€.

    STOP_CONTAINER_ID=$(sudo docker ps --filter "name=$STOP_TARGET" --quiet)
    if [ -n "$STOP_CONTAINER_ID" ]; then
      sudo docker stop $STOP_CONTAINER_ID
      sudo docker rm $STOP_CONTAINER_ID
      sudo docker image prune -af
    fi

    도컀 λͺ…λ Ήμ–΄λ₯Ό μ΄μš©ν•˜μ—¬ κ΅¬λ²„μ „μ˜ μ»¨ν…Œμ΄λ„ˆλ₯Ό λ©ˆμΆ”κ³  μ‚­μ œν•œλ‹€. λ‚˜λŠ” λ””μŠ€ν¬ 곡간 λ‚­λΉ„λ₯Ό 막기 μœ„ν•΄ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 이미지도 μ‚­μ œν•΄μ€¬λ‹€.
     
    도컀 + μ—”μ§„μ—‘μŠ€ + κΉƒν—™ μ•‘μ…˜μ„ ν™œμš©ν•œ 블루/κ·Έλ¦° 무쀑단 배포 완성이닀!!

    πŸ”— Blue/Green CD μ›Œν¬ν”Œλ‘œμš°
    πŸ”— deploy.sh

    참고자료

    λŒ“κΈ€