Github Action, Docker 통한 EC2 자동배포(3)- Docker compose 로 도커컨테이너 두개 띄우기

Featured image

이번이 세번째! 그동안은 하나의 도커에 다넣었는데 이번에 소켓부분만 따로 빼서 서버를 돌리고 싶다고 생각해서 시도했다

중요한점

그동안 왜 안됐었나?

  1. 도커 컴포즈의 서비스 1과 서비스2가 각각 다른 수준에 있었다

그동안은 왜 실행이 됐는지가 사실 의문임

  1. 도커컴포즈 버전 3이상 부터는 도커 파일빌드 할때 명시적으로 arg를 선언해줘야 한다

그동안은 이게 안됐어서 안됐던거 같다

  1. 이게 다 맞는데 실행이 안되는 이유?

-> 포트번호 둘이 다르게 실행하고 있었다

  1. 깃액션에서 왜 하나만 실행되고 멈춰버릴까?

run할때 -d로 안하면 대화형으로 켜져서 하나 설정하고 기다림

코드

깃액션에 env에 환경변수 넣어주기 PORT = $

깃컴포즈 파일에 args 해주고 env넣어주기

그리고 지정할 image라는 이름으로 args랑 같은 수준에 만들 이미지 이름 넣어주기

이거 깃액션에서 만들때 이 이미지 이름으로 만들어진다

도커 파일에도 도커 컴포즈 파일에서 받기 위해 ARG ENV 사용하기

도커 컴포즈에 arg넣는거 기억하기

version: '3.8'
services:
  api:
    build:
      context: ./main
      dockerfile: Dockerfile
      args:
        SOCKET_IO_PORT: $SOCKET_IO_PORT
        PORT: $PORT
        DATABASE_URL: $DATABASE_URL
        DATABASE_HOST: $DATABASE_HOST
        DATABASE_PORT: $DATABASE_PORT
        DATABASE_NAME: $DATABASE_NAME
        DATABASE_USERNAME: $DATABASE_USERNAME
        DATABASE_PASSWORD: $DATABASE_PASSWORD
        JWT_SECRET: $JWT_SECRET
        S3_ACCESS_KEY: $S3_ACCESS_KEY
        S3_SECRET_ACCESS_KEY: $S3_SECRET_ACCESS_KEY
        REDIS_HOST: $REDIS_HOST
        REDIS_PORT: $REDIS_PORT
        REDIS_PASSWORD: $REDIS_PASSWORD
        GOOGLE_ID: $GOOGLE_ID
        GOOGLE_SECRET: $GOOGLE_SECRET
        USER: $USER
        PASS: $PASS
        AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
        AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
        AWS_REGION: $AWS_REGION
        REMOTE_PRIVATE_KEY: $REMOTE_PRIVATE_KEY
        EC2_HOST: $EC2_HOST
    image: ${ECR_REGISTRY}/trello:late
    environment:
      SOCKET_IO_PORT: $SOCKET_IO_PORT
      PORT: $PORT
      DATABASE_URL: $DATABASE_URL
      DATABASE_HOST: $DATABASE_HOST
      DATABASE_PORT: $DATABASE_PORT
      DATABASE_NAME: $DATABASE_NAME
      DATABASE_USERNAME: $DATABASE_USERNAME
      DATABASE_PASSWORD: $DATABASE_PASSWORD
      JWT_SECRET: $JWT_SECRET
      S3_ACCESS_KEY: $S3_ACCESS_KEY
      S3_SECRET_ACCESS_KEY: $S3_SECRET_ACCESS_KEY
      REDIS_HOST: $REDIS_HOST
      REDIS_PORT: $REDIS_PORT
      REDIS_PASSWORD: $REDIS_PASSWORD
      GOOGLE_ID: $GOOGLE_ID
      GOOGLE_SECRET: $GOOGLE_SECRET
      USER: $USER
      PASS: $PASS
      AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
      AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
      AWS_REGION: $AWS_REGION
      REMOTE_PRIVATE_KEY: $REMOTE_PRIVATE_KEY
      EC2_HOST: $EC2_HOST
  socket:
    build:
      context: ./socket
      dockerfile: Dockerfile
      args:
        SOCKET_IO_PORT: $SOCKET_IO_PORT
        PORT: $PORT
        DATABASE_URL: $DATABASE_URL
        DATABASE_HOST: $DATABASE_HOST
        DATABASE_PORT: $DATABASE_PORT
        DATABASE_NAME: $DATABASE_NAME
        DATABASE_USERNAME: $DATABASE_USERNAME
        DATABASE_PASSWORD: $DATABASE_PASSWORD
        JWT_SECRET: $JWT_SECRET
        S3_ACCESS_KEY: $S3_ACCESS_KEY
        S3_SECRET_ACCESS_KEY: $S3_SECRET_ACCESS_KEY
        REDIS_HOST: $REDIS_HOST
        REDIS_PORT: $REDIS_PORT
        REDIS_PASSWORD: $REDIS_PASSWORD
        GOOGLE_ID: $GOOGLE_ID
        GOOGLE_SECRET: $GOOGLE_SECRET
        USER: $USER
        PASS: $PASS
        AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
        AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
        AWS_REGION: $AWS_REGION
        REMOTE_PRIVATE_KEY: $REMOTE_PRIVATE_KEY
        EC2_HOST: $EC2_HOST
    image: ${ECR_REGISTRY}/trello:latest
    environment:
      SOCKET_IO_PORT: $SOCKET_IO_PORT
      PORT: $PORT
      DATABASE_URL: $DATABASE_URL
      DATABASE_HOST: $DATABASE_HOST
      DATABASE_PORT: $DATABASE_PORT
      DATABASE_NAME: $DATABASE_NAME
      DATABASE_USERNAME: $DATABASE_USERNAME
      DATABASE_PASSWORD: $DATABASE_PASSWORD
      JWT_SECRET: $JWT_SECRET
      S3_ACCESS_KEY: $S3_ACCESS_KEY
      S3_SECRET_ACCESS_KEY: $S3_SECRET_ACCESS_KEY
      REDIS_HOST: $REDIS_HOST
      REDIS_PORT: $REDIS_PORT
      REDIS_PASSWORD: $REDIS_PASSWORD
      GOOGLE_ID: $GOOGLE_ID
      GOOGLE_SECRET: $GOOGLE_SECRET
      USER: $USER
      PASS: $PASS
      AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
      AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
      AWS_REGION: $AWS_REGION
      REMOTE_PRIVATE_KEY: $REMOTE_PRIVATE_KEY
      EC2_HOST: $EC2_HOST

# 부모 이미지 지정
FROM node:alpine
# app 디렉토리 생성

#Docker 이미지 내부에서 RUN, CMD, ENTRYPOINT의 명령이 실행될 디렉터리를 설정합니다.

WORKDIR /app

# 외부 패키지 설치를 위해 package.json과 yarn.lock 파일 복사
COPY package.json .
COPY yarn.lock .

# 패키지 설치
RUN  yarn install

# 나머지 모두 복사
COPY . .
# 현재 디렉터리에 있는 파일들을 이미지 내부 /app 디렉터리에 추가함

ADD     . /app

# ARG로 빌드 시점 변수를 선언
ARG DATABASE_URL
ARG PORT
ARG DATABASE_HOST
ARG DATABASE_PORT
ARG DATABASE_NAME
ARG DATABASE_USERNAME
ARG DATABASE_PASSWORD
ARG JWT_SECRET
ARG S3_ACCESS_KEY
ARG S3_SECRET_ACCESS_KEY
ARG PASS
ARG USER
ARG GOOGLE_ID
ARG GOOGLE_SECRET
ARG REDIS_HOST
ARG REDIS_PORT
ARG REDIS_PASSWORD

ENV DATABASE_URL=$DATABASE_URL 
ENV PORT=$PORT 
ENV DATABASE_HOST=$DATABASE_HOST 
ENV DATABASE_PORT=$DATABASE_PORT 
ENV DATABASE_NAME=$DATABASE_NAME 
ENV DATABASE_USERNAME=$DATABASE_USERNAME 
ENV DATABASE_PASSWORD=$DATABASE_PASSWORD 
ENV S3_ACCESS_KEY=$S3_ACCESS_KEY 
ENV S3_SECRET_ACCESS_KEY=$S3_SECRET_ACCESS_KEY 
ENV PASS=$PASS 
ENV USER=$USER 
ENV GOOGLE_ID=$GOOGLE_ID 
ENV GOOGLE_SECRET=$GOOGLE_SECRET 
ENV REDIS_HOST=$REDIS_HOST 
ENV REDIS_PORT=$REDIS_PORT 
ENV REDIS_PASSWORD=$REDIS_PASSWORD
ENV JWT_SECRET=$JWT_SECRET


LABEL creator="no6@trello"
LABEL version="1.0.0"




RUN yarn prisma generate
# 하기 포트를 외부로 노출합니다.


CMD [ "node","src/app.js" ]
# 부모 이미지 지정
FROM node:alpine
# app 디렉토리 생성

WORKDIR /app

COPY package.json .
COPY yarn.lock .

# 패키지 설치
RUN  yarn install

COPY . .
ADD     . /app

# ARG로 빌드 시점 변수를 선언
ARG DATABASE_URL
ARG PORT
ARG DATABASE_HOST
ARG DATABASE_PORT
ARG DATABASE_NAME
ARG DATABASE_USERNAME
ARG DATABASE_PASSWORD
ARG JWT_SECRET
ARG S3_ACCESS_KEY
ARG S3_SECRET_ACCESS_KEY
ARG PASS
ARG USER
ARG GOOGLE_ID
ARG GOOGLE_SECRET
ARG REDIS_HOST
ARG REDIS_PORT
ARG REDIS_PASSWORD

ENV DATABASE_URL=$DATABASE_URL 
ENV PORT=$PORT 
ENV DATABASE_HOST=$DATABASE_HOST 
ENV DATABASE_PORT=$DATABASE_PORT 
ENV DATABASE_NAME=$DATABASE_NAME 
ENV DATABASE_USERNAME=$DATABASE_USERNAME 
ENV DATABASE_PASSWORD=$DATABASE_PASSWORD 
ENV S3_ACCESS_KEY=$S3_ACCESS_KEY 
ENV S3_SECRET_ACCESS_KEY=$S3_SECRET_ACCESS_KEY 
ENV PASS=$PASS 
ENV USER=$USER 
ENV GOOGLE_ID=$GOOGLE_ID 
ENV GOOGLE_SECRET=$GOOGLE_SECRET 
ENV REDIS_HOST=$REDIS_HOST 
ENV REDIS_PORT=$REDIS_PORT 
ENV REDIS_PASSWORD=$REDIS_PASSWORD
ENV JWT_SECRET=$JWT_SECRET

LABEL creator="no6_socket@trello"
LABEL version="1.0.0"




RUN yarn prisma generate

CMD [ "node", "src/app.js" ]
name: Deploy to EC2 with ECR
#이미 도커파일이 이미지화되어 넘어감-> 자꾸 없다고 컴포즈 파일 없다고 뜸.
on:
  push:
    branches:
      - feat/seperate
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2

      # AWS에 로그인
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          aws-access-key-id: $
          aws-secret-access-key: $
          aws-region: $

      - name: Check if S3 credentials are set
        run: |
          if [[ -z "$" ]] || [[ -z "$" ]]; then
            echo "S3 credentials are not set."
            exit 1
          else
            echo "S3 credentials are set."
          fi

      # ECR에 로그인
      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1
        with:
          mask-password: 'true'

      # Docker 이미지 빌드 및 푸시
      - name: Build, tag, and push image to Amazon ECR
        env:
          ECR_REGISTRY: $
          ECR_REPOSITORY: trello
          IMAGE_TAG: latest
          SOCKET_IO_PORT: 4000
          PORT: 3000
          DATABASE_URL: $
          DATABASE_HOST: $
          DATABASE_PORT: $
          DATABASE_NAME: $
          DATABASE_USERNAME: $
          DATABASE_PASSWORD: $
          JWT_SECRET: $
          S3_ACCESS_KEY: $
          S3_SECRET_ACCESS_KEY: $
          REDIS_HOST: $
          REDIS_PORT: $
          REDIS_PASSWORD: $
          GOOGLE_ID: $
          GOOGLE_SECRET: $
          USER: $
          PASS: $!
          AWS_ACCESS_KEY_ID: $
          AWS_SECRET_ACCESS_KEY: $
          AWS_REGION: $
          REMOTE_PRIVATE_KEY: $
          EC2_HOST: $
          EC2_USERNAME: $

        run: |
          docker-compose build
          docker-compose push

      # SSH로 EC2 인스턴스에 접속하여 Docker 컨테이너 재시작
      - name: SSH into EC2 instance and restart Docker container
        uses: appleboy/ssh-action@master
        with:
          key: $
          host: $
          username: $
          port: 22
          script: |
            docker login -u AWS -p $(aws ecr get-login-password --region $) $
            docker pull $/trello:late
            docker pull $/trello:latest
            sudo docker ps -a
            sudo docker stop $(docker ps -a -q)
            sudo docker ps -a
            sudo docker rm $(docker ps -a -q)
            sudo docker run -d -p 4000:4000 $/trello:latest
            sudo docker run -d -p 3000:3000 $/trello:late