EC2에 자바 설치/폴더 생성
# 릴리스 보관 폴더(버전별 JAR 저장)
sudo mkdir -p /opt/plus/releases
sudo chown -R ubuntu:ubuntu /opt/plus
# (선택) 그레이스풀 셧다운 여유
echo -e "[Service]\\nTimeoutStopSec=30" | sudo tee /etc/systemd/system/todo-management.service.d/timeout.conf >/dev/null
sudo systemctl daemon-reload
GitHub Secrets 등록
EC2_HOST : EC2 퍼블릭 IP/도메인
EC2_SSH_KEY : ubuntu 계정의 SSH 개인키(-----BEGIN ~ END----- 포함)
EC2_USER : ubuntu
깃허브 워크플로 추가 (.github/workflows/deploy.yml)
name: CI-CD to EC2 (systemd)
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- name: Build jar
run: ./gradlew clean bootJar -x test
- name: Rename jar with commit sha + date
run: |
FILE=$(ls build/libs/*.jar | head -n1)
SHA=${GITHUB_SHA::8}
TS=$(date -u +'%Y%m%d-%H%M%S')
NEW="app-${TS}-${SHA}.jar"
mv "$FILE" "build/libs/$NEW"
echo "ARTIFACT=$NEW" >> $GITHUB_ENV
- name: Detect runner public IP
id: ip
run: echo "MY_IP=$(curl -s <https://checkip.amazonaws.com>)/32" >> $GITHUB_OUTPUT
- uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Open SSH for this runner
run: |
aws ec2 authorize-security-group-ingress \\
--group-id sg-0893adff359fd7994 \\
--ip-permissions "IpProtocol=tcp,FromPort=22,ToPort=22,IpRanges=[{CidrIp='${{ steps.ip.outputs.MY_IP }}',Description='gha-temporary'}]"
- name: Upload jar to EC2
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
source: "build/libs/${{ env.ARTIFACT }}"
target: "/opt/plus/releases/"
strip_components: 2
- name: Switch symlink & restart service
uses: appleboy/ssh-action@v1.2.0
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
set -e
JAR="/opt/plus/releases/${{ env.ARTIFACT }}"
echo "Switch to $JAR"
ln -sfn "$JAR" /opt/plus/app.jar
sudo systemctl restart todo-management.service
sudo systemctl status todo-management.service --no-pager --full || true
- name: Close SSH rule
if: always()
run: |
aws ec2 revoke-security-group-ingress \\
--group-id sg-0893adff359fd7994 \\
--ip-permissions "IpProtocol=tcp,FromPort=22,ToPort=22,IpRanges=[{CidrIp='${{ steps.ip.outputs.MY_IP }}'}]"
롤백
ls -lt /opt/plus/releases/*.jar
# 원하는 버전으로 링크 교체 후 재시작
ln -sfn /opt/plus/releases/your-prev.jar /opt/plus/app.jar
sudo systemctl restart todo-management.service
트러블 슈팅
문제: 개인 IP 이외 ssh 접근 제한
해결: 배포 시 IP를 받아와서 일회성 접근 권한 부여 후 권한 삭제
문제: 배포 버전마다 파일명이 동일한 문제
해결: 커밋 SHA 및 타임스탬프를 활용하여 파일명 생성