Mafia Game - 역대글
▶ Github Actions으로 배포 자동화
지금까지 Nginx와 Next.js, Node.js 서버를 Docker를 통해서 배포하는 방법을 알아봤다.
이번에는 Github Actions를 사용해서 main 브랜치에 머지 되면 Docker를 통해 자동으로 배포되도록 설정하는 작업을 진행하려고 한다.
이 글에서는 Dockjer에 대한 설정을 추가로 다루지 않고, GitHub Actions와 Linux 환경 설정에 초점을 맞추고 있습니다. Docker 설정이 필요하다면, Node.js, Next.js 배포하기를 먼저 참고해 주시길 바랍니다.
Linux 설정
GitHub에서 Linux 서버로 배포를 진행하기 위해서는 원격 접속을 해야 한다. 이를 위해 SSH키를 생성하고 서버에 추가하는 과정을 진행한다.
1. SSH 키 생성
ssh-keygen -t rsa -b 4096 -C "github-actions" -f ~/.ssh/github-actions
- -t rsa : SSH 키 생성 시 사용할 알고리즘을 지정한다. 여기서는 RSA를 사용한다.
- -b 4096 : 키 길이를 4096비트로 설정한다. 일반적으로 더 긴 키는 보안성을 높인다.
- -C 'github-actions' : 키에 주석을 추가한다. 이 주석은 키의 용도나 소유자를 구분할 때 사용할 수 있다.
- -f ~/.ssh/github-actions : 키 파일의 저장 경로와 이름을 지정한다.
위 명령어를 실행하면 공개 키(~/.ssh/github-actions.pub)와 비공개 키(~/.ssh/github-actions) 두 개의 파일이 생성된다.
2. 공개 키 추가
cat ~/.ssh/github-actions.pub >> ~/.ssh/authorized_keys
- 공개 키 파일(github-actions.pub)의 내용을 서버의 authorized_keys 파일에 추가한다.
- authorized_keys 파일은 서버에 신뢰할 수 있는 공개 키를 저장하는 파일로, 여기 키를 추가하면 해당 키로 원격 접속이 가능해진다.
chmod 600 ~/.ssh/authorized_keys
- authorized_keys 파일의 권한을 600으로 변경한다.
- 이는 파일을 소유자만 읽고 쓸 수 있도록 설정해서 보안을 강화하는 것이다.
3. SSH 출력
cat ~/.ssh/github-actions
위 명령어로 생성된 비공개 SSH 키를 출력한다. GitHub Actions가 서버에 접근할 수 있도록 이 키를 GitHub Secrets에 저장해야 한다.
SSH 키 저장 주의사항
SSH 키는 전체 내용을 저장해야 한다.
출력 결과는 다음과 비슷하게 나타나는데,
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
이때, ----BEGIN ~ ---- 부터 ----END ... ----까지 모든 내용을 포함하여 저장해야 한다. 만약 키 내부 값만 저장하거나 일부를 누락하면, 다음과 같은 오류가 발생할 수 있다.
ssh.ParsePrivateKey: ssh: no key found
4. dockerhub login
docker login -u [id]
- -u [id] : DockerHub 계정 ID를 입력한다. 이후 비밀번호 입력을 요구한다.
리눅스 서버에서 직접 Docker 이미지를 생성하지 않고, GitHub Actions에서 이미지를 빌드한 뒤 DockerHub에 업로드한다. 서버는 이 이미지를 DockerHub에서 가져와 사용한다.
미리 로그인하는 이유
- Private Docker 이미지 사용 시, 서버가 이미지를 가져오기 위해 인증이 필요하다.
- 미리 로그인하면 DockerHub에서 이미지 가져오는 과정이 원활해진다.
5. GitHub Actions Secrets 추가
GitHub Actions에 저장해야 할 부분은 HOST (서버 도메인), USERNAME(접속할 유저명), SSH키, PORT와 DOCKER_USERNAME, DOCKER_TOKEN이 있다.
DOCKER_USERNAME과 DOCKER_TOKEN은 4번 Docker Hub 로그인 시 사용한 정보이다.
Docker Compose 수정
services:
nginx:
image: sjw7324/nginx:latest
container_name: nginx-proxy
ports:
- "80:80"
networks:
- shared_network
앞선 작업들에서는 build를 Compose에서 진행했지만, 지금은 GitHub Action에서 build를 진행하기 때문에 image 부분에는 불러올 DockerHub의 명칭으로 변경해주었다.
GitHub Actions 설정
1. 작업 명칭 설정
name: Docker Deploy CI/CD
run-name: Deploy to Docker Hub
- name : GitHub Actions의 Workflow 이름을 설정한다.
- run-name : 실행 시 표시될 작업 이름을 설정한다.
2. 실행 조건 설정
on:
push:
branches:
- main
- on : Workflow 실행 조건을 지정한다.
- push : push 이벤트는 특정 브랜치(main)로의 push 또는 merge 발생 시 Actions를 실행한다.
개발 작업은 develop 브랜치에서 진행하고, 배포 시점에 main 브랜치로 병합하여 자동으로 배포가 되도록 설계했다.
3. 작업 환경 설정
runs-on: ubuntu-latest
- runs-on : Github Actions를 실행할 환경을 지정한다.
- 여기서는 특별한 요구사항 없이 최신 우분투 환경을 사용한다.
4. 코드 불러오기
steps:
- name: Checkout Code
uses: actions/checkout@v3
- actions/checkout@v3 : GitHub의 공식 Checkout ACtion을 사용하여 최신 코드를 Workflow 실행 환경에 가지고 온다.
이 단계에서 불러온 최신 코드를 기반으로 Docker Image를 생성한다.
5. DockerHub 로그인
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- docker.login-action@v2 : DockerHub에 로그인하기 위한 공식 GitHub Action을 사용한다.
- username 및 password는 Secrets에 저장한 DockerHub 계정 정보를 사용해 인증한다.
6. Docker Image 빌드 및 업로드
- name: Build and Push Docker Image
run: |
docker build -t ${{ secrets.DOCKERHUB_USERNAME}}/nginx:latest .
docker push ${{ secrets.DOCKERHUB_USERNAME}}/nginx:latest
- docker build : Dockerfile을 기반으로 이미지를 빌드한다.
- -t : 태그를 설정한다. 여기서는 latest 태그로 지정했다.
- docker push : 빌드한 이미지를 DockerHub에 업로드한다.
이 단계에서 미리 작업한 Dockerfile을 기반으로 빌드한 이미지를 DockerHub에 업로드한다.
7. 배포 진행
- name: Deploy to Server with Docker Compose
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: ${{ secrets.SERVER_PORT }}
script: |
cd /home/${{ secrets.SERVER_USER }}
if [ ! -d "nginx/.git" ]; then
echo "Repository does not exist. Cloning the repository..."
git clone https://github.com/${{ github.repository }}.git nginx
cd nginx
git checkout main
else
echo "Repository exists. Pulling latest changes..."
cd nginx
git pull origin main
fi
if ! docker network inspect shared_network >/dev/null 2>&1; then
echo "Network 'shared_network' does not exist. Creating it..."
docker network create shared_network
fi
docker-compose pull
docker-compose down
docker-compose up -d
- appleboy/ssh-action@master : 서버에 SSH를 통해 명령을 실행할 수 있는 GitHub Action이다.
- host, username, key, port는 Secrets에서 설정한 서버 정보를 사용해서 SSH로 접속한다.
- script
- .git 폴더가 없다면 clone, 있다면 pull을 진행한다.
- docker network inspect를 통해 네트워크가 있는지 확인하고 없으면 새롭게 만들어준다.
- docker-compose pull : 최신 이미지를 DockerHub에서 가지고 온다.
- docker-compose down & docker-compose up -d : 기존 컨테이너를 종료하고 최신 이미지를 기반으로 새 컨테이너를 실행한다.
여기까지 Nginx를 기반으로 설명했지만 각각 Next.js와 Node.js 환경에 맞게 명칭을 변경해줘서 사용하면 된다.
'개발환경' 카테고리의 다른 글
[개발환경] React Native 개발환경 구성 - Window (2) | 2022.05.23 |
---|---|
[개발환경] TypeScript 세팅 (2) | 2022.04.14 |
[개발환경] 도커 환경 구성 - Window (1) | 2022.03.11 |
[개발환경] React 개발환경 구성 - Window (2) | 2022.03.07 |