Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions .github/workflows/prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Deploy Prod to EC2
on:
push:
branches: [ "main" ]

permissions:
contents: read

concurrency:
group: prod-deploy
cancel-in-progress: false

jobs:
build-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: corretto
java-version: "21"
- uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: ${{ runner.os }}-gradle-
- name: Run tests
run: ./gradlew test --no-daemon

deploy:
needs: build-test
runs-on: [ self-hosted, real-prod ]
env: # 필요한 값들을 정의(키는 Secret 유지)
APP_DIR: /home/ubuntu/lv3-final-mission
BRANCH: main
REPO_URL: https://github.com/nourzoo/lv3-final-mission.git
INCLUDE_DB: "false" # prod DB 분리 운영이면 false
ENV_FILE: .env # 배포 시 사용할 env 파일
steps:
- name: Deploy (local on self-hosted)
shell: bash
run: |
set -euo pipefail
set -x
PS4='+ $(date "+%H:%M:%S") ' # 각 명령 앞에 타임스탬프

echo "[DBG] at $(date +%T)"; df -h; docker system df || true

APP_DIR="${APP_DIR:-/home/ubuntu/lv3-final-mission}"
BRANCH="${BRANCH:-main}"
REPO_URL="${REPO_URL:-https://github.com/nourzoo/lv3-final-mission.git}"
INCLUDE_DB="${INCLUDE_DB:-false}"
ENV_FILE_INPUT="${ENV_FILE:-.env}"

# 디렉터리 준비
sudo mkdir -p "${APP_DIR}"
sudo chown -R "$USER":"$USER" "${APP_DIR}"

# 초기 clone (없을 때만)
if [ ! -d "${APP_DIR}/.git" ]; then
if [ -z "${REPO_URL}" ]; then
echo "REPO_URL is required for initial clone" >&2
exit 1
fi
git clone "${REPO_URL}" "${APP_DIR}"
fi

cd "${APP_DIR}"
git fetch --all --prune
git checkout "${BRANCH}"
git pull --ff-only origin "${BRANCH}"

# 환경파일 확인
ENV_FILE_INPUT="${ENV_FILE:-.env}"
if [ ! -f "${ENV_FILE_INPUT}" ]; then
echo "${ENV_FILE_INPUT} not found on runner. Create it with prod secrets." >&2
exit 1
fi

# Compose 파일 결정
COMPOSE_ARGS="-f docker-compose.yml"
if [ "${INCLUDE_DB}" = "true" ] && [ -f "docker-compose.db.yml" ]; then
COMPOSE_ARGS="${COMPOSE_ARGS} -f docker-compose.db.yml"
fi

# 배포
docker compose ${COMPOSE_ARGS} --env-file "${ENV_FILE_INPUT}" up -d --build
docker image prune -f
33 changes: 33 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# --- Build stage ---
FROM amazoncorretto:21 AS build
WORKDIR /workspace

# Gradle 캐시 최적화: wrapper/gradle 관련 파일을 먼저 복사
COPY gradlew gradlew
COPY gradle gradle
COPY build.gradle settings.gradle ./
# 소스는 마지막에 복사 (캐시 활용)
RUN sed -i 's/\r$//' gradlew && chmod +x gradlew
COPY src src

# Gradle 8.14.3 보장 (wrapper 버전 확인)
# RUN ./gradlew wrapper --gradle-version 8.14.3 --no-daemon

# 빌드
RUN ./gradlew clean bootJar --no-daemon

# --- Run stage ---
FROM amazoncorretto:21-alpine

# 환경 변수 설정
# Dockerfile에는 JVM 옵션, 프로필 정도만 기본값으로
ENV TZ=Asia/Seoul
ENV JAVA_OPTS="-XX:MaxRAMPercentage=75 -XX:+UseG1GC"

WORKDIR /app

# 빌드 결과 복사
COPY --from=build /workspace/build/libs/*SNAPSHOT.jar /app/app.jar

# 실행
ENTRYPOINT ["sh","-c","java $JAVA_OPTS -jar /app/app.jar"]
Loading