dev-pilots 표준 파이프라인 적용: deploy.yml + docker-compose (포트 3000)

- 공식 워크플로우(.gitea/workflows/deploy.yml) 그대로 사용 (repo secrets 주입)
- deploy/docker-compose.yml: Next.js 포트 3000으로 Traefik 라벨 변경
- 커스텀 배포 방식 제거

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
이 커밋은 다음에 포함됨:
kjs
2026-08-12 17:11:09 +09:00
co-authored by Claude Fable 5
부모 f695b583e4
커밋 5dd265605f
4개의 변경된 파일과 66개의 추가작업 그리고 69개의 파일을 삭제
-62
파일 보기
@@ -1,62 +0,0 @@
# Gitea Actions — 빌드 & 배포
#
# 동작:
# 1. main 브랜치 push 시 자동 실행
# 2. 러너가 호스트 docker 데몬으로 이미지 빌드 (레지스트리 불필요)
# 3. 같은 호스트에서 컨테이너 교체 → Traefik이 jskim.vexplor.com HTTPS 라우팅
#
# DATABASE_URL은 서버의 /home/three/jskim/.env (chmod 600)에서 읽는다.
# 저장소에는 어떤 비밀값도 커밋하지 않는다.
name: build-and-deploy
on:
push:
branches:
- main
workflow_dispatch:
env:
IMAGE: harbor.wace.me/dev-pilots/jskim:latest
CONTAINER_NAME: jskim
DOMAIN: jskim.vexplor.com
HOST_ENV_DIR: /home/three/jskim
jobs:
deploy:
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: docker CLI 준비
run: command -v docker || (apt-get update -qq && apt-get install -y -qq docker.io)
- name: 이미지 빌드
run: docker build -t "$IMAGE" .
- name: 컨테이너 교체
run: |
# 호스트의 env 파일을 호스트 docker 데몬 경유로 읽는다 (러너 컨테이너에는 미마운트)
DATABASE_URL=$(docker run --rm -v "$HOST_ENV_DIR":/cfg:ro alpine sh -c 'grep "^DATABASE_URL=" /cfg/.env | cut -d= -f2-')
if [ -z "$DATABASE_URL" ]; then echo "호스트 $HOST_ENV_DIR/.env 에 DATABASE_URL 없음"; exit 1; fi
docker rm -f "$CONTAINER_NAME" 2>/dev/null || true
docker run -d \
--name "$CONTAINER_NAME" \
--restart always \
--network web \
-e TZ=Asia/Seoul \
-e DATABASE_URL="$DATABASE_URL" \
--label "traefik.enable=true" \
--label "traefik.docker.network=web" \
--label "traefik.http.routers.jskim.rule=Host(\`$DOMAIN\`)" \
--label "traefik.http.routers.jskim.entrypoints=websecure" \
--label "traefik.http.routers.jskim.tls.certresolver=le" \
--label "traefik.http.services.jskim.loadbalancer.server.port=3000" \
"$IMAGE"
docker network connect pgnet "$CONTAINER_NAME"
- name: 헬스체크
run: |
sleep 10
docker exec "$CONTAINER_NAME" wget -qO- http://localhost:3000/api/health || (docker logs --tail 50 "$CONTAINER_NAME"; exit 1)
+35
파일 보기
@@ -0,0 +1,35 @@
name: build-and-deploy
on:
push:
branches: [main]
workflow_dispatch:
env:
HARBOR: harbor.wace.me
PROJECT: dev-pilots
APP: jskim
jobs:
deploy:
runs-on: ubuntu-24.04
steps:
- name: tools
run: |
apt-get update -qq
apt-get install -y ca-certificates curl git docker.io docker-compose-v2 >/dev/null 2>&1 || apt-get install -y ca-certificates curl git docker.io >/dev/null
- name: checkout
run: |
rm -rf src && git clone --depth 1 --branch "$GITHUB_REF_NAME" http://oauth2:${{ github.token }}@gitea:3000/${GITHUB_REPOSITORY}.git src
- name: build
run: |
cd src && docker build -t $HARBOR/$PROJECT/$APP:latest .
- name: push
env:
HUSER: ${{ secrets.HARBOR_USER }}
HSECRET: ${{ secrets.HARBOR_SECRET }}
run: |
echo "$HSECRET" | docker login $HARBOR -u "$HUSER" --password-stdin
docker push $HARBOR/$PROJECT/$APP:latest
- name: deploy
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
run: |
cd src && docker compose -f deploy/docker-compose.yml up -d --pull always --force-recreate
+8 -6
파일 보기
@@ -25,13 +25,14 @@ npm run dev
## 배포
`main` 브랜치에 push하면 Gitea Actions(`.gitea/workflows/build-and-deploy.yml`)가 자동으로:
dev-pilots 교육 파이프라인을 그대로 사용한다. `main` 브랜치에 push하면
Gitea Actions(`.gitea/workflows/deploy.yml`)가 자동으로:
1. 서버(THREEDEV)에서 Docker 이미지 빌드 (레지스트리 불필요)
2. 컨테이너 교체 (`web` + `pgnet` 네트워크, Traefik 라벨)
3. `/api/health` 헬스체크
1. Docker 이미지 빌드 → Harbor push (`harbor.wace.me/dev-pilots/jskim`)
2. `deploy/docker-compose.yml`로 컨테이너 교체 (`web` + `pgnet` 네트워크, Traefik 라벨, 포트 3000)
3. Traefik이 `jskim.vexplor.com` HTTPS 라우팅
운영 `DATABASE_URL`은 서버의 `/home/three/jskim/.env`(chmod 600)에서 읽는다.
운영 `DATABASE_URL`과 Harbor 인증(`HARBOR_USER`/`HARBOR_SECRET`)은 저장소 Secrets로 이미 등록되어 있다.
## 구조
@@ -42,5 +43,6 @@ src/
lib/db.ts # pg Pool (DATABASE_URL 사용)
scripts/db-tunnel.sh
Dockerfile # standalone 빌드, node:20-alpine
.gitea/workflows/ # CI/CD
deploy/docker-compose.yml # 배포 정의 (Traefik 라벨, 앱 포트)
.gitea/workflows/deploy.yml # CI/CD (dev-pilots 표준)
```
+22
파일 보기
@@ -0,0 +1,22 @@
services:
jskim:
image: harbor.wace.me/dev-pilots/jskim:latest
container_name: jskim
restart: always
environment:
TZ: Asia/Seoul
DATABASE_URL: ${DATABASE_URL:?set DATABASE_URL in repo secrets}
networks: [web, pgnet]
labels:
- traefik.enable=true
- traefik.http.routers.jskim.rule=Host(`jskim.vexplor.com`)
- traefik.http.routers.jskim.entrypoints=websecure
- traefik.http.routers.jskim.tls.certresolver=le
# Next.js standalone 서버 포트 (기존 nginx 플레이스홀더는 80이었음)
- traefik.http.services.jskim.loadbalancer.server.port=3000
- traefik.docker.network=web
networks:
web:
external: true
pgnet:
external: true