본문 바로가기
자동배포 (Auto deploy)

4. 전체 정리

by 실짱 2024. 10. 31.

앞에서 열심히 설명했지만

사실 이게 웹페이지로 설명하려니 여간 힘든게 아니다.

오프라인에서 화이트보드에 그림 그리면서 설명하면 개발자들은 뚝딱 알아먹을거 같은데 , 그럴수도 없고 ^^;;

 

그래서 각각 필요한 부분들에 대한 걸 그림과 파일로 정리해보려고 한다.

포스팅을 읽어준 사람에 대한 선물로

 

1. 서브 프로젝트 (프론트앤드도 동일하니 여기서는 백앤드만 기술)

 1-1. 파이프라인 Jenkinsfile

더보기
pipeline {
    agent any

    environment {
        ECR_URL = 'xxxxx.dkr.ecr.ap-southeast-1.amazonaws.com'
    }

    stages {
        stage('Login to AWS ECR') {
            steps {
                script {
                    withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: 'AWS_OPC_ECR_CREDENTIAL']]) {
                        sh 'aws ecr get-login-password --region ap-southeast-1 | docker login --username AWS --password-stdin ${ECR_URL}'
                    }
                }
            }
        }

        stage('Build Docker image') {
            steps {
                script {
                    echo "Docker image build step!!";
                    sh 'chmod +x ./jenkins/production/jenkins_build.prod.sh';
                    sh './jenkins/production/jenkins_build.prod.sh';
                }
            }
        }

        stage('Push to ECR') {
            steps {
                script {
                    echo "Docker image push step!!";
                    sh 'docker push ${ECR_URL}/backend:${BUILD_NUMBER}'
                    sh 'docker push ${ECR_URL}/nginx:${BUILD_NUMBER}'
                }
            }
        }
    }

    post {
        success {
            echo 'All of pipeline stop is clear without any error !!!'
        }

        failure {
            echo 'The build failed, see console output for detail.'
            echo 'We need to do clean up container even after build failed.'
        }
    }

}

 1-2> jenkins_build.prod.sh

더보기
#!/usr/bin/env bash
set -x

# clean docker cache
docker system prune -a -f

# remove previous images
docker images | grep 'backend' | awk '{print $3}' | xargs -r docker rmi -f

# docker build
docker-compose -f ./docker-compose-prod.yml build backend
docker-compose -f ./docker-compose-prod.yml build nginx

# tag docgker image
docker tag backend-backend ${ECR_URL}/backend:${BUILD_NUMBER}
docker tag backend-nginx ${ECR_URL}/nginx:${BUILD_NUMBER}

 

2. Deployment 젠킨스 프로젝트 

 2-1. 파이프라인 Jenkinsfile

더보기
pipeline {
    agent any

    environment {
        ECR_URL = 'xxxxxxx.dkr.ecr.ap-southeast-1.amazonaws.com'
        FRONTEND_BUILD_NUMBER = 33
        BACKEND_BUILD_NUMBER = 33
        // git commit -m '[CICD-269] Release Backend:v1.5.0 Frontend :v1.5.0 | Build # Frontend:33, Backend:33'
    }

    stages {
        stage('Login to AWS ECR') {
            steps {
                script {
                    withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: 'AWS_OPC_ECR_CREDENTIAL']]) {
                        sh 'aws ecr get-login-password --region ap-southeast-1 | docker login --username AWS --password-stdin ${ECR_URL}'
                    }
                }
            }
        }

        stage('Pre-Deploy step') {
            steps {
                script {
                    sh "ansible-playbook -i /etc/ansible/hosts ./pre-deploy-playbook.yml -e ecr_url=${ECR_URL}"
                }
            }
        }

        stage('Pull with Ansible') {
            steps {
                script {
                    sh "ansible-playbook -i /etc/ansible/hosts ./pull-playbook.yml -e ecr_url=${ECR_URL} -e frontend_build_number=${FRONTEND_BUILD_NUMBER} -e backend_build_number=${BACKEND_BUILD_NUMBER}"
                }
            }
        }

        stage('Run with Ansible') {
            steps {
                script {
                    sh "ansible-playbook -i /etc/ansible/hosts ./run-playbook.yml -e ecr_url=${ECR_URL} -e frontend_build_number=${FRONTEND_BUILD_NUMBER} -e backend_build_number=${BACKEND_BUILD_NUMBER}"
                }
            }
        }
    }

    post {
        success {
            echo 'All of pipeline is clear without any error !!'
        }

        failure {
            echo 'The build failed, see console output for detail.'
            echo 'We need to do clean up container even after build failed.'
        }
    }

}

 

 2-2. pre-deploy-playbook.yml

더보기
- hosts: aws
  become: yes
  tasks:
    # 1. get authentification
    - name: Login to AWS ECR
      shell: |
        aws ecr get-login-password --region ap-southeast-1 | docker login --username AWS --password-stdin {{ ecr_url }}
      environment:
        AWS_ACCESS_KEY_ID: "xxxx"
        AWS_SECRET_ACCESS_KEY: "xxxxx"

    # 2. copy sh file to ECR
    - name: Copy script file to ECR
      copy:
        src: ./pre_deploy.sh
        dest: /home/ec2-user/xxx/deployment/pre_deploy.sh
        mode: '0755' # 실행 권한 부여

    # 3. Run sh file
    - name: Run script
      command: /home/ec2-user/xxx/deployment/pre_deploy.sh

 

 2-2-1. pre-deploy.sh

더보기
#!/bin/sh

# stop all docker containers
docker stop $(docker ps -q)

# remove all docker containers
docker rm $(docker ps -a -q)

# remove all docker images
docker rmi $(docker images -q)

# clear cache
docker system prune -a -f

 

 2-3. pull-playbook.yml

더보기
- hosts: aws
  become: yes
  tasks:
    - name: Print build_number
      debug:
        msg: "frontend_build_number is {{ frontend_build_number }}, backend_build_number is {{ backend_build_number }}"

    # 1. get authentification
    - name: Login to AWS ECR
      shell: |
        aws ecr get-login-password --region ap-southeast-1 | docker login --username AWS --password-stdin {{ ecr_url }}
      environment:
        AWS_ACCESS_KEY_ID: ""
        AWS_SECRET_ACCESS_KEY: ""

    # 2. pull docker image from ECR
    - name: Pull frontend image from ECR
      docker_image:
        name: "{{ ecr_url }}/frontend"
        tag: "{{ frontend_build_number }}"
        source: pull
    - name: Pull backend image from ECR
      docker_image:
        name: "{{ ecr_url }}/backend"
        tag: "{{ backend_build_number }}"
        source: pull
    - name: Pull nginx image from ECR
      docker_image:
        name: "{{ ecr_url }}/nginx"
        tag: "{{ backend_build_number }}"
        source: pull

 

 2-4. run-playbook.yml

더보기
- hosts: aws
  become: yes
  tasks:
    - name: Print build_number
      debug:
        msg: "frontend_build_number is {{ frontend_build_number }}, backend_build_number is {{ backend_build_number }}"

    # 1. get authentification
    - name: Login to AWS ECR
      shell: |
        aws ecr get-login-password --region ap-southeast-1 | docker login --username AWS --password-stdin {{ ecr_url }}
      environment:
        AWS_ACCESS_KEY_ID: ""
        AWS_SECRET_ACCESS_KEY: ""

    # 2. Generate docker-compose.yml
    - name: Generate docker-compose.yml
      template:
        src: ./docker-compose.yml.j2
        dest: /home/ec2-user/xxx/deployment/docker-compose.yml
        owner: ec2-user
        group: ec2-user
        mode: '0755'
      vars:
        ECR_URL: "{{ ecr_url }}"
        FRONTEND_TAG: "{{ frontend_build_number }}"
        BACKEND_TAG: "{{ backend_build_number }}"

    # 3. copy files
    - name: Copy .env.prod to EC2
      copy:
        src: ./.env.prod
        dest: /home/ec2-user/xxx/deployment/.env.prod
        owner: ec2-user
        group: ec2-user
        mode: '0644'
 
    # 4. Down previous container
    - name: docker-compose down
      command: docker-compose down
      args:
        chdir: /home/ec2-user/xxx/deployment

    # 5. Run container
    - name: docker-compose up
      command: docker-compose up -d
      args:
        chdir: /home/ec2-user/xxx/deployment

 

 2-5. docker-compose.yml.j2

더보기
version: '3'
services:
    frontend:
        image: "{{ ECR_URL }}/frontend:{{ FRONTEND_TAG }}"
        hostname: frontend
        restart: always
    backend:
        image: "{{ ECR_URL }}/backend:{{ BACKEND_TAG }}"
        hostname: backend
        restart: always
        env_file:
            - .env.prod
        ports:
            - '5555:5555'
    nginx:
        image: "{{ ECR_URL }}/nginx:{{ BACKEND_TAG }}"
        hostname: nginx
        depends_on:
            - backend
            - frontend
        restart: always
        ports:
            - '80:80'

 

조만간에 샘플 프로젝트를 만들어서 Github 에 올리려고 한다.

아직도 이해가 안된다면, github 를 기대하세요~~~

 

진짜 끝!!!!!

'자동배포 (Auto deploy)' 카테고리의 다른 글

1. ECR에 Docker image push (3/3)  (1) 2024.10.31
2. EC2에서 Pull & Run (1/3)  (1) 2024.10.31
2. EC2에서 Pull & Run (2/3)  (0) 2024.10.31
2. EC2에서 Pull & Run (3/3)  (2) 2024.10.31
3. 릴리즈 담당자가 할일  (0) 2024.10.31