|
| 1 | +# Docker Deploy Starter |
| 2 | + |
| 3 | +Language-agnostic Docker + GitHub Actions CI/CD + VPS SSH deployment starter. |
| 4 | + |
| 5 | +## Project Structure |
| 6 | + |
| 7 | +``` |
| 8 | +app/ → Example app (replace with your own) |
| 9 | +Dockerfile → Example Node.js (swap for your language, see docs/DOCKERFILE_EXAMPLES.md) |
| 10 | +docker-compose.yml → Local dev + VPS deployment |
| 11 | +.env.example → Environment variables template |
| 12 | +VERSION → Single source of truth for version (1.0.0) |
| 13 | +scripts/bump-version.js → Version bumping (patch/minor/major) |
| 14 | +docs/ → Setup guides (VPS, GHCR, HTTPS, Dockerfile examples) |
| 15 | +``` |
| 16 | + |
| 17 | +## CI/CD Pipeline |
| 18 | + |
| 19 | +- **ci.yml**: Runs on push/PR to main. Hadolint lint + docker-compose validate + Docker build test + Trivy CVE scan (CRITICAL/HIGH). No secrets needed. |
| 20 | +- **cd.yml**: Manual trigger OR tag push (v*). Builds image (Buildx + GHA cache) → pushes to GHCR → deploys to VPS via SSH → cleans old images → creates GitHub Release. Concurrency controlled (no parallel deploys). |
| 21 | +- **setup.yml**: First push only. Auto-creates GitHub Issue with setup checklist. |
| 22 | + |
| 23 | +## Secrets (for CD) |
| 24 | + |
| 25 | +| Secret | Required | Purpose | |
| 26 | +|--------|----------|---------| |
| 27 | +| `VPS_HOST` | Yes | VPS IP or domain | |
| 28 | +| `VPS_USER` | Yes | SSH username | |
| 29 | +| `VPS_SSH_KEY` | Yes | SSH private key (full PEM content) | |
| 30 | +| `APP_PORT` | No | Defaults to 3000 | |
| 31 | +| `GITHUB_TOKEN` | Auto | Provided by GitHub Actions | |
| 32 | + |
| 33 | +## What to Modify |
| 34 | + |
| 35 | +- `app/` → Replace with your application code |
| 36 | +- `Dockerfile` → Swap for your language (copy from docs/DOCKERFILE_EXAMPLES.md) |
| 37 | +- `.env.example` → Add your app-specific environment variables |
| 38 | +- `docker-compose.yml` → Update ports, volumes, service name if needed |
| 39 | +- `VERSION` → Bump via `node scripts/bump-version.js patch|minor|major` |
| 40 | + |
| 41 | +## Do NOT Modify |
| 42 | + |
| 43 | +- `.github/workflows/ci.yml` → CI pipeline structure |
| 44 | + - **Why**: Hadolint → compose validate → build → Trivy scan 순서가 의도적. 빠른 검사부터 느린 검사 순서로 fail-fast. |
| 45 | +- `.github/workflows/cd.yml` → Deployment pipeline |
| 46 | + - **Why**: GHCR push → SSH deploy → cleanup → release 순서에 의존성이 있음. 순서 변경 시 미배포 이미지가 릴리즈되거나, 배포 전 이미지가 정리될 수 있음. |
| 47 | +- Version guard logic in cd.yml |
| 48 | + - **Why**: 같은 버전을 두 번 배포하면 GHCR 태그 충돌 + GitHub Release 중복 생성. 이 guard가 없으면 CI 통과해도 CD에서 조용히 깨짐. |
| 49 | +- Health check pattern in Dockerfile and docker-compose.yml |
| 50 | + - **Why**: `docker compose up -d --wait`가 health check 통과를 기다림. health check 없으면 컨테이너 시작 = 배포 성공으로 판단해서 깨진 앱이 배포될 수 있음. |
| 51 | +- Concurrency control in cd.yml |
| 52 | + - **Why**: 동시에 두 배포가 실행되면 SSH에서 race condition 발생. `cancel-in-progress: false`로 순서대로 실행. |
| 53 | + |
| 54 | +## Customization Examples |
| 55 | + |
| 56 | +- **Change port**: Set `APP_PORT` secret in GitHub + update `EXPOSE` in Dockerfile + update `.env` |
| 57 | +- **Add database**: Add service to docker-compose.yml, add DB env vars to .env.example |
| 58 | +- **Switch to Python/Go/Rust/Java**: Copy Dockerfile from docs/DOCKERFILE_EXAMPLES.md, replace app/ |
| 59 | +- **Add HTTPS**: Follow docs/HTTPS_SETUP.md (Caddy reverse proxy) |
0 commit comments