[github action] Github actions을 이용한 ECR 자동화

fastify를 설치하고 작동하는지 확인하자

Fastify를 일단 우선적으로 설치할 수 있어야한다.

fastify를 어떻게 설치할까?

npm install fastify-cli --global

그리고 제너레이트를 해야한다.

fastify generate .

root.js

Module.exports 에 대한 응답을 해줘야한다.

return으로는

return “hello world”

Fastify Module의 reply를 사용해서

reply.code(200)

.send(’hello world’)

이렇게도 표현이 가능하다.

app.js를 실행시키려고한다.

npm run dev

curl http://localhost:3000 포트 사용해서 hello world!가 잘 뜨는지 확인한다.

그리고 root.js에서 hello world를 →Hello world!로 바꾸고

잘 출력되는지 curl로 확인해보니 정상 출력이 되었다.

웹에서도 마찬가지로 Hello world!로 반환해주었다.

그리고 그냥 return 으로 string타입으로 hello world를 해도 정상 출력된걸 확인 할 수 있다.


Docker image build!

Dockerfile 작성!

그리고 도커 이미지를 빌드해야한다.

도커 이미지를 빌드하기 위해서는 Dockerfile이 필요하다.

Dockerfile의 작성의 원형은

https://nodejs.org/ko/docs/guides/nodejs-docker-webapp/

위 링크에서 따왔다. 그리고 커스텀을 하면된다.

FROM에는 내가 사용하는 환경을 적어주면 된다.

FROM에 처음에는 노드 환경인 node:16-alpine을 적었다.

그 이후에 실리콘 맥을 사용하는 나는 추가적으로 FROM에 더 적어줘야한다고 들어서 찾아보니

—platform=linux/amd64

를 넣어줘야한다고 보았다.

그런데 FROM을 두개를 넣어서 하면 안되더라... 그래서 한줄로 정리를 하는 방법은..!

FROM —platform=linux/amd64 node:16-alpine

이렇게 쓸 수 있다.

WORKDIR 는 /usr/src/app 이 default인줄 알았는데 내가 직접 지정을 할 수 있다.

WORKDIR /app

길게 할 필요없고 /app 으로 간단하게 지정했다. (나중에 docker exec에서 컨테이너로 들어가서 확인가능)

COPY package*.json ./

COPY는 package*.json으로 되어있다.

*(와일드카드)로 지정된 이유는 package.json 파일과 package-lock.json파일을 같이 복사하기 위해서이다.

그리고 ./로 지정된곳은 현재 디렉토리인데 여기서는 아까 WORKDIR로 지정한 app/

RUN npm install

RUN 명령어는 도커파일로부터 도커 이미지를 빌드하는 순간에 실행이되는 명령어npm install 을 통해 npm환경을 빌드 해줘야한다.

COPY . .

Caution!

처음에 . 은 지금 작업하고있는 디렉토리 그 자체를의미한다.

그리고 두번째 . 은 app/을 의미한다.

그러면 지금 작업하고 있는 디렉토리를 app/에 복사해서 넣으라는 의미가 되겠지?

나중에 docker exec 으로 뜯어서 확인 가능하다.

EXPOSE 4000

EXPOSE는 내가 컨테이너에서 몇번포트로 노출시킬지 정하는건데 정하면 된다.

나는 4000 번대를 선택했다.

CMD["npm", "run", "start"]

CMD 명령어는 RUN 명령어가 이미지를 빌드할 때 실행되는 것과 달리, 이미지로부터 컨테이너를 생성하여 최초로 실행할 때 수행된다.

package.json 의 scripts에서 "start": "fastify start -p 4000 -l info app.js" 이부분을 볼 수 있는데

npm run start를 하면 fastify start -p 4000 -l info app.js 이 Fastify 커멘드가 실행이 되는것을 알 수 있다.

** -p 4000은 내가 EXPOSE 에 4000을 넣어서 insert한 line이다.


Docker context!

나는 원래 컨텍스트가 myecscontext로 설정이 되어있다.

그래서 context를 바꿔줘야하는데!

	nano(혹은 vi) ~/.zshrc

입력해서 들어간다. .zshrcs는 터미널을 파일의 개념으로 봤을때 파일명이라고 할 수 있다. vi로 열어서 수정이 가능하다.

저번에 myecscontext를 하고 체크아웃을 default로 안해줘서 그렇다.

.zshrc에 들어가서 AWS_ACCESS_KEY랑 AWS_SECRET_KEY를 넣어준다. 나올때 저장하는거 잊지말고

 source ~/.zshrc

이 커멘드는 터미널을 다시 시작하는거라고 생각하면 됨

내가 이거 안써도 위에 수정된 zshrc는 새 터미널을 열면 적용이 된다.

근데 이거 써서 그냥 다시 새로운거 안 열어도 적용이 되는거라고 할 수 있음

docker context ls

를 사용해서 지금 있는 컨텍스트들의 목록을 볼 수 있다. 이름에 *표시 되어있는게 내가 지금 쓰고있는 context

docker context use default

이걸로 context를 default로 바꿔준다.

docker context use show 

그리고 context가 바꼈는지 다시 확인한다 default가 출력이되면 성공이다.


Docker build image and make it run in container

docker build . -t <your username>/node-web-app 

빌드 뒤 . 은 현재 Dockerfile이 있는 작업 디렉토리 , <your username>에는 내 도커 아이디를 넣고, /뒤에는 docker image파일로 지정할 이름을 넣는다.

docker build . -t crossnest/fastify 

실제 넣은 코드는 이렇다.

열심히 빌드한다.

그러면 GUI 도커로 확인해본 docker에서 crowssnest/fastify로 이미지파일이 생성된것을 확인 할 수 있다.

그리고 내가 만든 이미지를 컨테이너로 실행해본다.

docker run —-name (지정할 컨테이너이름) -p 49160(로컬에서 내가 사용할 포트):4000(내가 컨테이너에서 노출할 포트) -d <your username>/<docker image파일로 지정할 이름>

docker run —-name (지정할 컨테이너이름) -p 49160(로컬에서 내가 사용할 포트):4000(내가 컨테이너에서 노출할 포트) -d(백그라운드 실행) <your username>/<docker image파일로 지정할 이름>

docker run —-name fastify -p 49160:4000 -d crowssnest/fastify

이미지를 컨테이너로 실행한다. (나의 경우, 컨테이너 이름도 fastify로 동일)

컨테이너가 실행되고 있는중에

docker exec -it (실행되고 있는 컨테이너 이름: 나의 경우 fastify) /bin/bash

이렇게 입력하면! 될 줄 알았는데ㅜ

node 가 alpine이면 /bin/bash가 없다고 한다 ☹️

그래서!

docker exec -it  fastify sh

이걸로 진입가능하다.

쨘 이렇게!

여기서 sh는 raw shell 을 의미하는 그 sh

Dockerfile에서 /app 에 아까 COPY 한거 기억날거다...

/app에서 ls 하면 내가 빌드할때 있던 작업 레파지토리들 싹다 복사 해서 가져온거 확인 할수 있다.


Amazon ECR Manual push!

Amazon ECR 구글에 검색해서 들어가는게 편리하더라

들어가면 리포지토리 생성이 있는데 딱히 신경써야할건 없고, 생성할 때 스캔하는거 설정하면 편한거같다.

리포지토리를 생성하면 내가 생성한 리포지토리에 대한 푸시명령을 할수 있다.

순서대로 복사해서 넣으면 될 거 같았는데, 제일 위에 영어로

Make sure that you have the latest version of the AWS CLI and Docker installed.

적혀있다. 나는 Docker는 설치되어있는데, AWS CLI는 설치 안되어있어서 그랬던거다. 그래도 좀 친절하다.

aws configure

자격부여는 이걸로 하면 된다.

rootkey.csv 파일을 찾아서 순서대로 Access key 그리고 secret key를 입력시켜주면된다.

aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 349873998748.dkr.ecr.ap-northeast-2.amazonaws.com

이걸 넣고 터미널에 입력하면, AWS CLI에 권한이 있는상태면 알아서 로그인이 된다.

region name에는 나는 ECR을 서울에 만들었으니 ap-northeast-2를 넣고

그 밑에 output format은 json yaml text 이렇게 들어갈 수 있는데, 일단은 그렇게 중요하지않은거같아서 text

docker tag fastify 349873998748.dkr.ecr.ap-northeast-2.amazonaws.com/project002:latest

docker tag <내가 만든 도커 이미지 이름> 349873998748.dkr.ecr.ap-northeast-2.amazonaws.com/project002:latest

docker push 349873998748.dkr.ecr.ap-northeast-2.amazonaws.com/project002:latest

그리고 이렇게 ECR repository에 push 해주면

도커에 내가 만들어놓은 이미지 파일이 올라간것을 알 수 있다.

나는 처음에 도커에 Push 할 때 태그는 따로 안달아서 latest인데 처음부터 도커에 이미지파일을 만들때 crowssnest/fastify:1.0.0 이렇게했으면 저기에 1.0.0으로 갔을거라고 추측중

이렇게 하면 수동으로 ECR에 올리는것 완성!


Amazon ECR Auto push!

GitHub action으로 할거다 

GitHub action에서 yaml 파일을 만들어도 되고, 아니면 그냥 로컬에서 touch crowecr.yaml로 만들어서 내용 넣어도 된다.

name: Deploy to Amazon ECS

on:
  push:
    branches:
      - crow

env:
  AWS_REGION: ap-northeast-2                   # set this to your preferred AWS region, e.g. us-west-1
  ECR_REPOSITORY: project002        # set this to your Amazon ECR repository name
  # ECS_SERVICE: MY_ECS_SERVICE                 # set this to your Amazon ECS service name
  # ECS_CLUSTER: MY_ECS_CLUSTER                 # set this to your Amazon ECS cluster name
  # ECS_TASK_DEFINITION: MY_ECS_TASK_DEFINITION # set this to the path to your Amazon ECS task definition
                                               # file, e.g. .aws/task-definition.json
  # CONTAINER_NAME: MY_CONTAINER_NAME           # set this to the name of the container in the
                                               # containerDefinitions section of your task definition

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v3

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.CROW_AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.CROW_AWS_SECRET_ACCESS_KEY }}
        aws-region: ${{ env.AWS_REGION }}

    - name: Login to Amazon ECR
      id: login-ecr
      uses: aws-actions/amazon-ecr-login@v1

    - name: Build, tag, and push image to Amazon ECR
      id: build-image
      env:
        ECR_REGISTRY: 349873998748.dkr.ecr.ap-northeast-2.amazonaws.com
        IMAGE_TAG: latest
      run: |
        docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
        docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG

    # - name: Fill in the new image ID in the Amazon ECS task definition
    #   id: task-def
    #   uses: aws-actions/amazon-ecs-render-task-definition@v1
    #   with:
    #     task-definition: ${{ env.ECS_TASK_DEFINITION }}
    #     container-name: ${{ env.CONTAINER_NAME }}
    #     image: ${{ steps.build-image.outputs.image }}

    # - name: Deploy Amazon ECS task definition
    #   uses: aws-actions/amazon-ecs-deploy-task-definition@v1
    #   with:
    #     task-definition: ${{ steps.task-def.outputs.task-definition }}
    #     service: ${{ env.ECS_SERVICE }}
    #     cluster: ${{ env.ECS_CLUSTER }}
    #     wait-for-service-stability: true

github action에서 ECS 템플릿을 원형으로 가져와서 ECS부분은 다 주석처리 하셨다. (빛킹갓...)

나에게 맞게 조금 수정을 해야한다.

on:
  push:
    branches:
      - crow

Trigger 부분이다. 나는 main branch 말고 crow branch 사용중이니까 crow branch 에 Push되는것을 트리거로 사용

  - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.CROW_AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.CROW_AWS_SECRET_ACCESS_KEY }}

Configure AWS credentials 여기에서 secrets 는 환경변수로 넣어주면 된다. (AWS access, AWS secret)

ECR_REGISTRY: [349873998748.dkr.ecr.ap-northeast-2.amazonaws.com](<http://349873998748.dkr.ecr.ap-northeast-2.amazonaws.com>)

내 repository의 url 처음 숫자를 넣어주면 된다.

yaml 파일 작성 끝!

그리고 나는 crow branch 에 Push를 할거다 trigger에서 crow브렌치에 push 를하면 작동하게 했으니까 push 하고 결과를 보자.

complicated 내가 만든건데 workflows에서 생성이 되어서 작동중인것을 확인 가능

클릭해서 들어가면 더 자세히 확인할 수 있다.

그리고 완료가된것을 확인하고 ECR에 가서 확인해본다.

둘다 latest태그를 달고 있는데, 내가 지금 만든것도 latest태그니까

그 전 수동으로 push 했던 <latest>는 <untagged> 로 바뀌고 가장 최근에 푸쉬된것이 latest 태그를 단 것을 확인할 수 있다.

JUNE .

20'S LIFE IN SYDNEY and BUSAN

    이미지 맵

    DevOps Study/Github action 다른 글

    이전 글

    다음 글