이전글에서 Spring Logback을 적용하고 docker-compose 파일에 외부 볼륨을 설정하는 작업까지 해줬다.
이제 GitHub Action을 이용해서 Ec2에서 도커 컨테이너가 docker-compose를 통해 실행될 수 있게 설정해줘야한다.
name: Server Deploy
on:
push:
branches: [main]
paths:
- 'server/**'
jobs:
server:
runs-on: ubuntu-latest
env:
AWS_ACCESS_KEY: ${{secrets.AWS_ACCESS_KEY}}
AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}}
JWT_SECRET_KEY: ${{secrets.JWT_SECRET_KEY}}
KAKAO_CLIENT_ID: ${{secrets.KAKAO_CLIENT_ID}}
KAKAO_CLIENT_SECRET: ${{secrets.KAKAO_CLIENT_SECRET}}
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'zulu'
- name: Grant execute permission for gradlew
working-directory: ./server
run: chmod +x gradlew
- name: Build with Gradle
working-directory: ./server
run: ./gradlew build
- name: Docker build
run: |
docker login -u ${{secrets.DOCKER_HUB_USERNAME}} -p ${{secrets.DOCKER_HUB_PASSWORD}}
cd server
docker build -t celebee-server .
docker tag celebee-server ${{secrets.DOCKER_HUB_USERNAME}}/celebee-server:v3
docker push ${{secrets.DOCKER_HUB_USERNAME}}/celebee-server:v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{secrets.AWS_ACCESS_KEY}}
aws-secret-access-key: ${{secrets.AWS_SECRET_ACCESS_KEY}}
aws-region: ap-northeast-2
- name: Check if container exists
run: |
if docker ps -a --format '{{.Names}}' | grep -q '^celebee-server$'; then
docker rm -f celebee-server
fi
continue-on-error: true
- name: Run scripts in server
uses: appleboy/ssh-action@master
with:
key: ${{secrets.EC2_KEY}}
host: ${{secrets.EC2_HOST}}
username: ubuntu
port: ${{secrets.EC2_PORT}}
script: |
whoami
sudo docker login -u ${{secrets.DOCKER_HUB_USERNAME}} -p ${{secrets.DOCKER_HUB_PASSWORD}}
sudo docker pull ${{secrets.DOCKER_HUB_USERNAME}}/celebee-server:v3
sudo docker-compose -f ./docker-compose.yml up -d
변경된 부분만 설명하면,
- name: Run scripts in server
uses: appleboy/ssh-action@master
with:
key: ${{secrets.EC2_KEY}}
host: ${{secrets.EC2_HOST}}
username: ubuntu
port: ${{secrets.EC2_PORT}}
script: |
whoami
sudo docker login -u ${{secrets.DOCKER_HUB_USERNAME}} -p ${{secrets.DOCKER_HUB_PASSWORD}}
sudo docker pull ${{secrets.DOCKER_HUB_USERNAME}}/celebee-server:v3
sudo docker-compose -f ./docker-compose.yml up -d
기존에 docker run 으로 pull 받아온 이미지를 실행시켰던 로직에서 위와같이 변경했다. ec2에 접속해서 도커 로그인을하고, 허브에 있는 도커 이미지를 pull 한뒤 docker-compose를 실행시키는 명령어이다.
각 host, username 등 환경변수 처리한 값들에 어떤걸 넣어야하는지나 예제가 보고싶으면 아래 공식 페이지를 참고하면된다.
GitHub Action SSH Remote Commands
key 값으로 넣은 SSH가 문제였는지
ssh: handshake failed: ssh: unable to authenticate, attempted methods [none], no supported methods remain
오류가 계속 났다.
key, host 등 with에 넣은 값이 잘못되어서 나는 오류라는 글을 확인했는데, 값이 뭐가 잘못된건지 모르겠었다.
.pem 키를 텍스트 편집기로 열어서 값을 넣어줬는데 계속 오류가 났다. 권한 문제인가 싶어서 권한도 추가해줬는데 어림없었다.
이유는 이 pem키를 복사할 때
-----BEGIN RSA PRIVATE KEY-----
어쩌구
-----END RSA PRIVATE KEY-----
이렇게 되어있는데, 이 어쩌구 부분만 넣어줘서 그랬다.....
-----BEGIN RSA PRIVATE KEY----- 부터 전부 다 넣어줬어야했다....아니 그냥 시작이란걸 알려주는줄...
몇시간을 왜 잘못된거지? 로컬에서는 접속 되는데 왜?! 이러면서 싸웠는데 조금 허무했다.
sudo docker-compose up -d
이렇게만 설정하고 실행했는데, docker-compose.yml을 찾지못해 오류가 났다. 파일이 있는 곳으로 경로 설정을 해줘야한다해서 프로젝트 경로인 ./server로 지정해주고 실행했는데,
cd: ./server: No such file or directory
err: no configuration file provided: not found
같은 문제로 실행이 안되었다..
아무리 생각해도 도커는 이미지로 실행하는데...?docker-compose는 프로젝트 루트 경로에 두라고해서 dockerfile과 같은 위치에 뒀는데...? 근데 어떻게 경로를 설정하지...? 하면서 진짜 엄청 고민하고 구글링 계속했다.
나와 같은 케이스는 못찾았고, 그 이후에 생각한게 그럼 docker-compose.yml을 작성해서 ec2에 넣어두고 그 경로를 참고시키는건가...? 하고 gpt에 이렇게 물어보니 이렇게 하는거란다
웃기는 자식이다. 아까는 또 원래 그게 맞다며 새꺄
아무튼 docker-compose 파일을 작성해서 ec2로 전송해두고, 그 경로를 추가해줬다.
sudo docker-compose -f ./docker-compose.yml up -d이렇게
-f ./docker-compose.yml 이게 경로 설정하는 부분이다.
그랬더니 성공했다. 서버도 성공적으로 배포되었다.
추가로, 환경변수들을 .env 파일로 관리하라고 들었을때 .env 파일은 깃헙에 못올리는데... 깃헙에 안올라갔으면 git action이 안될텐데...? 그럼 어떻게 주입해주는거지 내가 뭘 모르지하고 실행을 못시켜 -e 명령어로 주입시켰었는데, 이제 이 .env 파일도 docker-compose.yml이 있는 위치에서 관리해주는거구나 하는 생각이 들었다.
(사실 이게 맞는 방법인지 모르겠다.. 함께 공부한 친구들 모두 docker는 아예 사용을 안해서 모른다고하고 ec2에서 docker로 배포한 글을 찾아봐도 이런 부분에 대한 설명이 없다.. 물론 더 공부해보고 틀린 정보가 였다면 추후에 수정할 예정이다. )
err: Error response from daemon: Conflict. The container name "/server" is already in use by container
중복된 컨테이너가 있어서 충돌났는 거라고한다.
컨테이너명을 바꾸고, 태그도 바꾸면서 기존에 있던 컨테이너가 종료가 안되었던거같다.
docker stop <container_name>
docker rm <container_name>
명령어로 중복된 컨테이너를 종료시켜서 해결했다.
프로젝트 끝나고 혼자 리팩토링하면서 운영서버 관리한지 거의 5개월 정도 되었다. 문제 생기면 서버 꺼졌다고 연락와서 심장 철렁하고, 또 이렇게 만나본적 없는 문제 해결하면서 잘 돌아가는 사이트보면 예뻐죽겠고.. 이맛에 백엔드 개발하는건가 싶다.
(근데 이유모르겠고 어떻게 해결해야할지 모르겠어서 며칠 고민하다보면 너무 어려워서 때려치고싶다.)
혹시 이 글에서 잘못된 정보가 있다면 꼭!! 가르침 부탁드립니다..ㅠㅠ