# 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)