| name | deployment |
| description | CI/CD pipeline, Docker multi-stage build, GitHub Actions, and Cloud Run deployment for the Anachak platform. |
Deployment Skill
Covers the full CI/CD pipeline from local build to production deployment.
CI Pipeline (GitHub Actions)
File: .github/workflows/ci.yml
Jobs
| Job | Trigger | Purpose |
|---|
| check | push/PR to main | cargo fmt --check → clippy → build --release → test |
| test | after check | Start PostgreSQL service → build server → run Ruby integration tests |
| docker | after check | Build Docker image → push to GHCR (on push to main) |
Check Job
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo build --release
cargo test --release
Integration Test Job
- Spins up
postgres:16-alpine service container
- Creates
.env with CI secrets
- Starts the compiled server binary
- Waits for gRPC health check (30s timeout)
- Runs
ruby scripts/test_all.rb
Docker Job
- Multi-stage build
- Pushes to
ghcr.io/<repo> with tags: latest, main, <sha>
- BuildKit cache (GHA)
Dockerfile
# Stage 1: Builder
FROM rust:1.88-slim AS builder
# Install protobuf + SSL + pkg-config
# Copy manifests for dep caching
# Copy source + build --release
# Stage 2: Runtime
FROM debian:bookworm-slim
# Install ca-certificates + curl
# Non-root user (app)
# Copy binary from builder
# EXPOSE 50050 9090 9091
# CMD ["server"]
Build Optimizations
- Dep caching: copy
Cargo.toml/Cargo.lock first, dummy main.rs
- BuildKit cache mounts for cargo registry/git/target
- Slim runtime image (~80MB)
Environment Variables
Required (Backend)
DATABASE_URL, JWT_SECRET, JWT_ACCESS_EXPIRY_SECS, JWT_REFRESH_EXPIRY_SECS,
GRPC_HOST, GRPC_PORT, RESEND_API_KEY, EMAIL_FROM, EMAIL_FROM_NAME,
FRONTEND_URL, CORS_ORIGINS, METRICS_PORT, WS_PORT,
BAKONG_EMAIL, BAKONG_TOKEN, BAKONG_ACCOUNT_ID, BAKONG_MERCHANT_NAME,
BAKONG_MERCHANT_CITY, KHR_EXCHANGE_RATE, SUPER_ADMIN_EMAIL,
SUPER_ADMIN_USERNAME, SUPER_ADMIN_PASSWORD
Optional
PLASGATE_PRIVATE_KEY, PLASGATE_SECRET_KEY, TELEGRAM_BOT_TOKEN,
TELEGRAM_GATEWAY_TOKEN, GOOGLE_CLIENT_ID, ALERT_CHAT_ID, REDIS_URL
Frontend (.env)
VITE_API_URL=http://localhost:50050
VITE_GOOGLE_CLIENT_ID=xxx.apps.googleusercontent.com
Cloud Run Deployment
gcloud run deploy anachak \
--image ghcr.io/khemapos/anachak_rust:latest \
--region asia-southeast1 \
--platform managed \
--port 50050 \
--allow-unauthenticated \
--set-secrets "DATABASE_URL=DATABASE_URL:latest,JWT_SECRET=JWT_SECRET:latest,..."
K8s (Self-Hosted)
Kustomize manifests in k8s/ for self-hosted Kubernetes deployments.
Quick Deploy Workflow
cc # cargo check
ct # cargo test
ship "feat: X" # git add + commit + push → triggers CI