가장 먼저 준비되어야 할 계정과 서버입니다.
EC2 서버에 접속하여 배포에 필요한 환경을 만듭니다.
# Install Docker
sudo apt update
sudo apt install docker.io -y
# ubuntu 유저에게 Docker 실행 권한 부여 (sudo 없이 쓰기 위해)
sudo usermod -aG docker ubuntu
# 설정 적용을 위해 쉘 로그아웃 하고 다시 SSH 접속
exit
Docker 컨테이너가 읽어야 할 보안 설정파일(properties or yml)은 서버에 직접 심어둡니다.
(보안상의 이유로 운영 설정파일은 github에 올리지 않기 때문에 직접 설정합니다.)
# 프로젝트 폴더 생성
mkdir -p ~/app/<project-name>
# 설정 파일 생성 및 내용 붙여넣기 (DB 비밀번호, JWT secret 등)
vi ~/app/<project-name>/src/main/resources/application-prod.properties
Github 저장소의 Settings > Secrets and variables > Actions에 아래 변수들을 등록합니다.
| Secret 이름 | 내용 |
|---|---|
| DOCKER_USERNAME | Docker Hub 아이디(이메일 아님) |
| DOCKER_PASSWORD | Docker Hub Access Token(비밀번호 대신 권장) |
| EC2_HOST | EC2 Public IP 주소(또는 도메인) |
| EC2_USERNAME | ubuntu |
| EC2_SSH_KEY | EC2접속용 .pem 키 내용 전체(-----BEGIN-----포함) |
이제 프로젝트(IntelliJ 등)에서 3개의 파일을 만들거나 수정합니다.
서버 환경을 이미지로 정의하는 파일입니다.
FROM eclipse-temurin:17-jdk
ARG JAR_FILE=build/libs/life-manager-1.0.0.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-Duser.timezone=Asia/Seoul", "-Dspring.profiles.active=prod", "-jar", "/app.jar"]
서버에서 실제로 컨테이너를 갈아끼우는 스크립트입니다.
#!/bin/bash
# Docker 이미지 이름(본인 ID로 수정 필수)
DOCKER_APP_NAME="<your-docker-id>/<project-name>"
echo "===== Docker 배포 시작 ====="
# 기존 컨테이너가 있다면 중지 및 삭제
if ["$(docker ps -a -q -f name=<container-name>)"]; then
echo "Stopping and removing existing container..."
docker stop <container-name>
docker rm <container-name>
fi
# 기존 이미지 삭제 (용량 확보, 에러 무시)
echo "Removing old image..."
docker rmi $DOCKER_APP_NAME:latest 2>/dev/null || true
# 새 이미지 다운로드
echo "Pulling new image..."
docker pull $DOCKER_APP_NAME:latest
# 새 컨테이너 실행(Volumne mount 포함)
echo "Running container..."
docker run -d -p 9000:9000 \
--name <container-name> \
-v /home/ubuntu/app/<project-name>/src/main/resources/application-prod.properties:/config/application-prod.properties \
$DOCKER_APP_NAME:latest
# 불필요한 이미지 정리
docker image prune -f
echo "===== Docker 배포 완료 ====="
.github/workflows/deploy.ymlGitHub Actions가 수행할 작업 지시입니다.
name: Deploy to EC2 with Docker
'on':
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: "17"
distribution: "temurin"
- name: Build with Gradle
run: |
chmod +x gradlew
./gradlew clean build -x test
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push Docker Image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/<project-name>:latest
- name: Deploy to EC2
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
scripts: |
cd /home/ubuntu/app/<project-name>
git pull origin main
chmod +x deploy.sh
./deploy.sh
모든 준비가 끝났습니다.
git add, git commit, git push origin main을 입력합니다.application-prod.properties를 -v옵션으로 반드시 연결(마운트)해줘야 합니다.deploy.yml의 script 부분에 git pull이 있어야, deploy.sh의 변경사항(포트 변경 등)이 서버에 반영됩니다.deploy.sh와 deploy.yml에 적힌 이미지 태그(ID/repo:latest)가 정확히 일치해야 합니다.