Skip to content

Commit 5ecc786

Browse files
revert: 워크플로우 원상복구 (#174)
1 parent a766b41 commit 5ecc786

1 file changed

Lines changed: 60 additions & 219 deletions

File tree

Lines changed: 60 additions & 219 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Deploy to Dev EC2 (Docker Compose)
1+
name: Deploy to Dev EC2
22

33
on:
44
push:
@@ -7,240 +7,81 @@ on:
77

88
jobs:
99
deploy:
10+
name: Build and Deploy to EC2
1011
runs-on: ubuntu-latest
1112
environment: dev
12-
permissions:
13-
contents: read
14-
packages: write
15-
16-
env:
17-
CONTAINER_NAME: saerok-dev
18-
COMPOSE_FILE_REMOTE: docker-compose.dev.yml
1913

2014
steps:
21-
- name: 🧾 Checkout
22-
uses: actions/checkout@v4
23-
24-
# GHCR 레포(org/repo) 소문자 정규화 → outputs + env
25-
- name: 🔧 Normalize image repo
26-
id: normalize
27-
run: |
28-
echo "image_repo=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT"
29-
echo "IMAGE_REPO=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_ENV"
30-
31-
- name: 🔧 Set up Docker Buildx
32-
uses: docker/setup-buildx-action@v3
15+
- name: Checkout source code
16+
uses: actions/checkout@v3
3317

34-
- name: 🔐 Log in to GHCR
35-
uses: docker/login-action@v3
18+
- name: Set up JDK 21
19+
uses: actions/setup-java@v3
3620
with:
37-
registry: ghcr.io
38-
username: ${{ secrets.GHCR_USERNAME }}
39-
password: ${{ secrets.GHCR_TOKEN }}
21+
distribution: 'corretto'
22+
java-version: '21'
4023

41-
- name: 🏷️ Extract metadata (tags, labels)
42-
id: meta
43-
uses: docker/metadata-action@v5
44-
with:
45-
images: ${{ steps.normalize.outputs.image_repo }}
46-
tags: |
47-
type=raw,value=dev-latest
48-
type=sha,format=long,prefix=dev-,suffix=
24+
- name: Grant execute permission for Gradle
25+
run: chmod +x gradlew
4926

50-
- name: 📌 Show image tags
51-
run: |
52-
echo "::group::Image tags"
53-
echo "${{ steps.meta.outputs.tags }}" | tr ' ' '\n'
54-
echo "::endgroup::"
55-
{
56-
echo "### 🏷️ Image tags";
57-
echo '${{ steps.meta.outputs.tags }}' | tr ' ' '\n' | sed 's/^/- /';
58-
} >> $GITHUB_STEP_SUMMARY
27+
- name: Build with Gradle
28+
run: ./gradlew test bootJar
5929

60-
- name: 🏗️ Build and push image
61-
uses: docker/build-push-action@v6
30+
- name: Copy JAR to EC2
31+
uses: appleboy/scp-action@v0.1.7
6232
with:
63-
context: .
64-
file: ./Dockerfile
65-
push: true
66-
tags: ${{ steps.meta.outputs.tags }}
67-
labels: ${{ steps.meta.outputs.labels }}
68-
cache-from: type=registry,ref=${{ steps.normalize.outputs.image_repo }}:buildcache
69-
cache-to: type=registry,ref=${{ steps.normalize.outputs.image_repo }}:buildcache,mode=max
70-
71-
- name: ✅ Verify image pushed
72-
run: |
73-
echo "::notice::Pushed to $IMAGE_REPO (primary tag: dev-latest)"
74-
{
75-
echo "### ✅ Build & Push";
76-
echo "- Repo: \`$IMAGE_REPO\`";
77-
echo "- Primary tag: \`dev-latest\`";
78-
} >> $GITHUB_STEP_SUMMARY
33+
host: ${{ secrets.EC2_HOST }}
34+
username: ubuntu
35+
key: ${{ secrets.EC2_SSH_PRIVATE_KEY }}
36+
source: build/libs/*.jar
37+
target: ~/saerok/
38+
strip_components: '2'
7939

80-
- name: 🚀 Deploy on EC2 via SSH
40+
- name: Restart application on EC2
8141
uses: appleboy/ssh-action@v1
8242
with:
8343
host: ${{ secrets.EC2_HOST }}
8444
username: ubuntu
8545
key: ${{ secrets.EC2_SSH_PRIVATE_KEY }}
46+
debug: true
8647
script: |
8748
set -euxo pipefail
88-
# ======== bind workflow values into remote shell ========
89-
COMPOSE_FILE_REMOTE="${{ env.COMPOSE_FILE_REMOTE }}"
90-
CONTAINER_NAME="${{ env.CONTAINER_NAME }}"
91-
IMAGE_REPO="${{ steps.normalize.outputs.image_repo }}"
92-
export COMPOSE_FILE_REMOTE CONTAINER_NAME IMAGE_REPO
93-
# =======================================================
94-
95-
banner () { echo "::notice::$1"; }
96-
section () { echo "::group::$1"; }
97-
endsection () { echo "::endgroup::"; }
98-
99-
section "0) Ensure Docker & Compose"
100-
if ! command -v docker >/dev/null 2>&1; then
101-
banner "Installing Docker..."
102-
curl -fsSL https://get.docker.com | sh
103-
sudo usermod -aG docker $USER || true
104-
fi
105-
if ! docker compose version >/dev/null 2>&1; then
106-
banner "Installing docker compose plugin..."
107-
DOCKER_COMPOSE_VERSION="v2.29.7"
108-
sudo mkdir -p /usr/local/lib/docker/cli-plugins
109-
sudo curl -fsSL https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-linux-x86_64 \
110-
-o /usr/local/lib/docker/cli-plugins/docker-compose
111-
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
112-
fi
113-
docker --version
114-
docker compose version
115-
endsection
116-
117-
section "1) Prepare workspace"
118-
mkdir -p ~/saerok
49+
11950
cd ~/saerok
120-
pwd
121-
endsection
122-
123-
section "2) Docker login (GHCR pull)"
124-
echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u "${{ secrets.GHCR_USERNAME }}" --password-stdin
125-
endsection
126-
127-
section "3) Generate ${COMPOSE_FILE_REMOTE}"
128-
cat > "${COMPOSE_FILE_REMOTE}" <<'YAML'
129-
services:
130-
app:
131-
image: ${{ steps.normalize.outputs.image_repo }}:dev-latest
132-
container_name: saerok-dev
133-
restart: always
134-
ports:
135-
- "8080:8080"
136-
environment:
137-
SPRING_PROFILES_ACTIVE: "dev"
138-
DB_URL: "${{ secrets.DB_URL }}"
139-
DB_USERNAME: "${{ secrets.DB_USERNAME }}"
140-
DB_PASSWORD: "${{ secrets.DB_PASSWORD }}"
141-
IAM_ACCESS_KEY: "${{ secrets.IAM_ACCESS_KEY }}"
142-
IAM_SECRET_KEY: "${{ secrets.IAM_SECRET_KEY }}"
143-
UPLOAD_IMAGE_BUCKET_NAME: "${{ vars.UPLOAD_IMAGE_BUCKET_NAME }}"
144-
UPLOAD_IMAGE_DOMAIN: "${{ vars.UPLOAD_IMAGE_DOMAIN }}"
145-
DEX_IMAGE_BUCKET_NAME: "${{ vars.DEX_IMAGE_BUCKET_NAME }}"
146-
DEX_IMAGE_DOMAIN: "${{ vars.DEX_IMAGE_DOMAIN }}"
147-
APPLE_CLIENT_ID: "${{ secrets.APPLE_CLIENT_ID }}"
148-
APPLE_TEAM_ID: "${{ secrets.APPLE_TEAM_ID }}"
149-
APPLE_KEY_ID: "${{ secrets.APPLE_KEY_ID }}"
150-
APPLE_PRIVATE_KEY: "${{ secrets.APPLE_PRIVATE_KEY }}"
151-
JWT_SECRET: "${{ secrets.JWT_SECRET }}"
152-
KAKAO_ADMIN_KEY: "${{ secrets.KAKAO_ADMIN_KEY }}"
153-
KAKAO_CLIENT_ID: "${{ secrets.KAKAO_CLIENT_ID }}"
154-
KAKAO_REDIRECT_URI: "${{ secrets.KAKAO_REDIRECT_URI }}"
155-
KAKAO_CLIENT_SECRET: "${{ secrets.KAKAO_CLIENT_SECRET }}"
156-
KMS_KEY_ID: "${{ secrets.KMS_KEY_ID }}"
157-
FIREBASE_ADMIN_KEY: "${{ secrets.FIREBASE_ADMIN_KEY }}"
158-
healthcheck:
159-
test: ["CMD-SHELL", "curl -fsS http://localhost:8080/health >/dev/null || exit 1"]
160-
interval: 10s
161-
timeout: 3s
162-
retries: 15
163-
start_period: 60s
164-
YAML
165-
banner "Compose file written: ${COMPOSE_FILE_REMOTE}"
166-
docker compose -f "${COMPOSE_FILE_REMOTE}" config --services || true
167-
endsection
168-
169-
section "4) Pull & Up (recreate with port-fallback)"
170-
set +e
171-
docker compose -f "${COMPOSE_FILE_REMOTE}" pull
172-
docker compose -f "${COMPOSE_FILE_REMOTE}" up -d --force-recreate
173-
UP_RC=$?
174-
set -e
175-
176-
if [ $UP_RC -ne 0 ]; then
177-
echo "::warning::compose up failed (rc=$UP_RC). Checking port 8080..."
178-
ss -lntp || true
179-
if ss -lntp | grep -q ':8080 '; then
180-
echo "::warning::Port 8080 is busy. Trying to free it."
181-
if ! command -v fuser >/dev/null 2>&1; then
182-
sudo apt-get -qq update
183-
sudo DEBIAN_FRONTEND=noninteractive apt-get -y -qq install psmisc
184-
fi
185-
sudo fuser -k 8080/tcp || true
186-
sleep 2
187-
docker compose -f "${COMPOSE_FILE_REMOTE}" up -d --force-recreate
188-
else
189-
echo "::error::Compose up failed and port 8080 is not busy. Aborting."
190-
exit 1
191-
fi
192-
fi
193-
194-
docker compose -f "${COMPOSE_FILE_REMOTE}" ps
195-
endsection
196-
197-
section "5) Wait for health=healthy"
198-
set +e
199-
ATTEMPTS=40
200-
for i in $(seq 1 ${ATTEMPTS}); do
201-
STATUS=$(docker inspect -f '{{.State.Health.Status}}' "${CONTAINER_NAME}" 2>/dev/null || echo "unknown")
202-
echo "[$i/${ATTEMPTS}] health: $STATUS"
203-
if [ "$STATUS" = "healthy" ]; then
204-
banner "Container is healthy."
205-
OK=1
206-
break
207-
fi
208-
sleep 2
209-
done
210-
if [ "${OK:-0}" != "1" ]; then
211-
echo "::warning::Container did not reach healthy state in time."
212-
docker logs --tail=200 "${CONTAINER_NAME}" || true
213-
exit 1
214-
fi
215-
set -e
216-
endsection
217-
218-
section "6) Tail last logs"
219-
docker logs --tail=200 "${CONTAINER_NAME}" || true
220-
endsection
221-
222-
banner "✅ Deploy done"
223-
224-
- name: 🧾 Summary
225-
if: always()
226-
run: |
227-
{
228-
echo "## 🚀 Deploy Summary";
229-
echo "";
230-
echo "- Image repo: \`$IMAGE_REPO\`";
231-
echo "- Tags pushed:";
232-
echo '${{ steps.meta.outputs.tags }}' | tr ' ' '\n' | sed 's/^/ - /';
233-
echo "";
234-
echo "### Health";
235-
echo "- Target container: \`${{ env.CONTAINER_NAME }}\`";
236-
echo "- Health check: \`GET /health\`";
237-
echo "";
238-
echo "### Useful commands (on EC2)";
239-
echo "\`\`\`bash";
240-
echo "ssh ubuntu@${{ secrets.EC2_HOST }}";
241-
echo "cd ~/saerok";
242-
echo "docker compose -f ${COMPOSE_FILE_REMOTE} ps";
243-
echo "docker logs -f ${CONTAINER_NAME}";
244-
echo "curl -i localhost:8080/health";
245-
echo "\`\`\`";
246-
} >> $GITHUB_STEP_SUMMARY
51+
echo ">>> 현재 위치: $(pwd)"
52+
echo ">>> 파일:"
53+
ls -al
54+
55+
# JAR 확인
56+
JAR_NAME=$(ls -1t *.jar | head -n1)
57+
[ -n "$JAR_NAME" ] || { echo "❌ JAR 없음"; exit 2; }
58+
echo ">>> 선택된 JAR: $JAR_NAME"
59+
60+
# 기존 프로세스 종료
61+
pkill -f "$JAR_NAME" || true
62+
63+
# 백그라운드 실행
64+
DB_URL="${{ secrets.DB_URL }}" \
65+
DB_USERNAME="${{ secrets.DB_USERNAME }}" \
66+
DB_PASSWORD="${{ secrets.DB_PASSWORD }}" \
67+
IAM_ACCESS_KEY="${{ secrets.IAM_ACCESS_KEY }}" \
68+
IAM_SECRET_KEY="${{ secrets.IAM_SECRET_KEY }}" \
69+
UPLOAD_IMAGE_BUCKET_NAME="${{ vars.UPLOAD_IMAGE_BUCKET_NAME }}" \
70+
UPLOAD_IMAGE_DOMAIN="${{ vars.UPLOAD_IMAGE_DOMAIN }}" \
71+
DEX_IMAGE_BUCKET_NAME="${{ vars.DEX_IMAGE_BUCKET_NAME }}" \
72+
DEX_IMAGE_DOMAIN="${{ vars.DEX_IMAGE_DOMAIN }}" \
73+
APPLE_CLIENT_ID="${{ secrets.APPLE_CLIENT_ID }}" \
74+
APPLE_TEAM_ID="${{ secrets.APPLE_TEAM_ID }}" \
75+
APPLE_KEY_ID="${{ secrets.APPLE_KEY_ID }}" \
76+
APPLE_PRIVATE_KEY="${{ secrets.APPLE_PRIVATE_KEY }}" \
77+
JWT_SECRET="${{ secrets.JWT_SECRET }}" \
78+
KAKAO_ADMIN_KEY="${{ secrets.KAKAO_ADMIN_KEY }}" \
79+
KAKAO_CLIENT_ID="${{ secrets.KAKAO_CLIENT_ID }}" \
80+
KAKAO_REDIRECT_URI="${{ secrets.KAKAO_REDIRECT_URI }}" \
81+
KAKAO_CLIENT_SECRET="${{ secrets.KAKAO_CLIENT_SECRET }}" \
82+
KMS_KEY_ID="${{ secrets.KMS_KEY_ID }}" \
83+
FIREBASE_ADMIN_KEY="${{ secrets.FIREBASE_ADMIN_KEY }}" \
84+
nohup java -Duser.timezone=Asia/Seoul -jar $JAR_NAME --spring.profiles.active=dev > app.log 2>&1 &
85+
86+
echo "✅ 배포 완료"
87+

0 commit comments

Comments
 (0)