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

2. EC2에서 Pull & Run (3/3)

by 실짱 2024. 10. 31.

6. Run 단계 셋업

이제 ECR 로부터 필요한 docker image 들을 서버를 실행해야 하는 컴퓨터인 EC2 로 댕겨왔다.

실행만 시키면 된다.

 

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}"
        }
    }
}

* 이젠 정말 설명 안해도 알아야 된다.

* 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: "xxxxx"
        AWS_SECRET_ACCESS_KEY: "xxxxx"

    # 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

* 로그인은 설명 생략

 

4번, 5번은 docker 로 서비스 다운했다가 실행하는 거니 보기만 해도 알수 있다.

(물론 docker 는 기본적으로 다 안다고 가정)

 

2번, 3번이 좀 생소할 수 있다.

 

docker 로 여러 서비스를 동시에 돌리기 위해서는 기본적으로 docker-compose.yml 파일이 필요하다.

여기에 docker container 들의 정보들을 다 기술해서 docker 가 실행할 수 있게 해줘야 한다.

그리고 이 docker-compose.yml 은 특정한 환경 파일(env.prod) 을 필요로 할 수 있다.

이렇게 docker 를 돌리기 위한 파일들을 EC2 서버에 저장하는 과정이다.

 

쉬운 3번부터 보자.

3번은 내용에서 알 수 있듯이 , 젠킨스 서버에 저장된 .env.prod 파일을 EC2 서버의 타겟 위치로 복사하는 과정이다.

*copy : 역시 ansible 이 제공하는 copy module 을 이용하면 된다. 

              src, dest 를 지정해주고 파일 소유자, mode 까지 지정해 줄 수 있다.

이렇게 해서 docker 를 돌리는데 필요한 .env.prod 파일을 EC2 서버에 복사하자.

 

2번이 좀 재밌다.

파일내의 내용이 모두 fix 되어 있는 .env 파일과는 달리 docker-compose.yml 파일은 파일내의 내용이 매번 바뀌어야 된다.

잘 이해가 안될 수 있는데 소스 보면 금방 안다.

 

아래는 최종모습의 docker-compose.yml 의 일부이다.

services:
    frontend:
        image: "xxxxxxx/frontend:33"
        hostname: frontend
        restart: always
    backend:
        image: "xxxxxx/backend:33"
        hostname: backend
        restart: always
        env_file:
            - .env.prod
        ports:
            - '5555:5555'

* xxxxxx: ECR URL 이 들어간다.

* 33 : 앞에서 푸쉬할때 docker image 를 만든 젠킨스 빌드 번호다.

눈치챘을지 모르겠지만 , url 은 고정이라서 하드 코딩을 할 수 있다고 해도 (이 마저도 변동 ip 라면 바뀔수도 있다)

33과 같은 빌드 번호는 매 릴리즈시마다 변경되는 값이다.

물론, 하드하게 적어서 위의 copy module 을 이용해서 복사해도 되겠지만 , 이러면 진정한 자동 CD 가 될수 없다.

그래서 젠킨스 서버에서 필요한 정보들을 이용해서 EC2 서버에 docker-compose.yml 파일을 만들어야 했고 이를 Ansible 이 제공하고 있다.

 

다시 2번 부분을 떼서 보자.

 # 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 }}"

* template : ansible 에서 제공하는 모듈로 template 파일을 지정하면 그 템플릿 파일의 형태로 파일을 생성시켜주는 기능이다.

* vars : template src file 에서 사용할 수 있는 변수를 정의하는 부분이다. 변경되는 부분들 (여기서는 url 과 빌드 번호) 을 변수로 정의할 수 있다.

-> 즉 젠킨스 서버의 어딘가에 있는 docker-compose.yml.j2 라는 템플릿 파일을 변수 부분을 참고해서 EC2 서버의 dest 위치에 docker-compose.yml 이라는 이름의 파일로 만들라는 명령이다.

 

자, 그러면 이 템플릿 파일이 중요하겠지?

간단하다. 최종 모습의 docker-compose.yml 파일에서 변경되는 부분만 변수로 대치하면 된다.

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'

* ECR_URL, FRONTEND_TAG, BACKEND_TAG 를 플레이북으로부터 받도록 하면 된다.

 

이러면 docker 운영에 필요한 파일들이 생성되고 카피 되었다.

서버에가서 확인해 보자.

 

잘~ 들어와 있다.

 

docker ps -a 로 컨테이너들이 돌아가고 있는지 보자

33번 태그를 물고 잘 돌아가고 있다!!!

 

여기까지 자동으로 배포하고 실행하는것까지 완료했다.

이제 우리 회사는 자동 CI/CD 시스템을 갖춘 회사가 되었다!!!

 

끝!!!

 


Prev << 2. EC2에서 Pull & Run (2/3)

'자동배포 (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
3. 릴리즈 담당자가 할일  (0) 2024.10.31
4. 전체 정리  (0) 2024.10.31