diff --git a/Dockerfile b/Dockerfile index 32e0688d..aa2d09cf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,10 +15,13 @@ COPY . . RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ go build -trimpath -ldflags="-s -w" -o lti-api ./cmd/api -# Build SEED binary (pastikan cmd/seed ada) +# Build SEED binary RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ go build -trimpath -ldflags="-s -w" -o lti-seed ./cmd/seed +# Build migrate CLI (golang-migrate) +RUN GOBIN=/usr/local/bin go install -ldflags="-s -w" github.com/golang-migrate/migrate/v4/cmd/migrate@v4.18.3 + # ========================= # Runtime stage # ========================= @@ -31,6 +34,8 @@ WORKDIR /app COPY --from=builder /app/lti-api /app/lti-api COPY --from=builder /app/lti-seed /app/lti-seed +COPY --from=builder /usr/local/bin/migrate /app/migrate +COPY --from=builder /app/internal/database/migrations /app/migrations USER appuser EXPOSE 8081 diff --git a/k8s/jobs/README.md b/k8s/jobs/README.md new file mode 100644 index 00000000..4c121d5b --- /dev/null +++ b/k8s/jobs/README.md @@ -0,0 +1,38 @@ +# DB Jobs for dev-lti + +These manifests are intended for EKS + Argo CD deployment flow. + +## Files +- `migrate-dev-lti-presync.yaml`: Argo CD `PreSync` migration Job. +- `seed-dev-lti-manual.yaml`: manual seed Job. +- `fresh-dev-lti-manual.yaml`: manual reset + migrate Job (guarded with `ALLOW_DB_RESET`). + +## Important +- Update the image tag in all manifests to the same tag deployed by Argo for each release. +- Jobs currently read environment variables from secret `lti-env-dev`. +- Required DB env vars: `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`, optional `DB_SSLMODE`. + +## Manual run +Seed: + +```bash +kubectl delete job -n dev-lti lti-db-seed-manual --ignore-not-found +kubectl apply -f k8s/jobs/seed-dev-lti-manual.yaml +kubectl logs -n dev-lti job/lti-db-seed-manual -f +``` + +Fresh/reset (dev only): + +```bash +kubectl delete job -n dev-lti lti-db-fresh-manual --ignore-not-found +sed 's/value: "NO"/value: "YES"/' k8s/jobs/fresh-dev-lti-manual.yaml | kubectl apply -f - +kubectl logs -n dev-lti job/lti-db-fresh-manual -f +``` + +## Argo CD note +For `migrate-dev-lti-presync.yaml`, keep annotation: + +- `argocd.argoproj.io/hook: PreSync` +- `argocd.argoproj.io/hook-delete-policy: BeforeHookCreation,HookSucceeded` + +so migration runs before workload sync. diff --git a/k8s/jobs/fresh-dev-lti-manual.yaml b/k8s/jobs/fresh-dev-lti-manual.yaml new file mode 100644 index 00000000..cf7a754e --- /dev/null +++ b/k8s/jobs/fresh-dev-lti-manual.yaml @@ -0,0 +1,38 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: lti-db-fresh-manual + namespace: dev-lti +spec: + backoffLimit: 0 + ttlSecondsAfterFinished: 300 + template: + spec: + restartPolicy: Never + containers: + - name: fresh + image: 886436954922.dkr.ecr.ap-southeast-3.amazonaws.com/mbugroup/lti-api:dev-f8ca404b + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c"] + args: + - | + set -eu + if [ "${ALLOW_DB_RESET:-}" != "YES" ]; then + echo "Refusing to reset DB. Set ALLOW_DB_RESET=YES to continue." + exit 1 + fi + + DATABASE_URL="postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=${DB_SSLMODE:-disable}" + echo "Resetting schema public on ${DB_HOST}:${DB_PORT}/${DB_NAME}" + + psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -c "DROP SCHEMA IF EXISTS public CASCADE;" + psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -c "CREATE SCHEMA public;" + + echo "Running migrations after reset" + /app/migrate -path /app/migrations -database "$DATABASE_URL" up + env: + - name: ALLOW_DB_RESET + value: "NO" + envFrom: + - secretRef: + name: lti-env-dev diff --git a/k8s/jobs/migrate-dev-lti-presync.yaml b/k8s/jobs/migrate-dev-lti-presync.yaml new file mode 100644 index 00000000..e8cd4015 --- /dev/null +++ b/k8s/jobs/migrate-dev-lti-presync.yaml @@ -0,0 +1,28 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: lti-db-migrate + namespace: dev-lti + annotations: + argocd.argoproj.io/hook: PreSync + argocd.argoproj.io/hook-delete-policy: BeforeHookCreation,HookSucceeded +spec: + backoffLimit: 1 + ttlSecondsAfterFinished: 300 + template: + spec: + restartPolicy: Never + containers: + - name: migrate + image: 886436954922.dkr.ecr.ap-southeast-3.amazonaws.com/mbugroup/lti-api:dev-f8ca404b + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c"] + args: + - | + set -eu + DATABASE_URL="postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=${DB_SSLMODE:-disable}" + echo "Running migrations on ${DB_HOST}:${DB_PORT}/${DB_NAME}" + /app/migrate -path /app/migrations -database "$DATABASE_URL" up + envFrom: + - secretRef: + name: lti-env-dev diff --git a/k8s/jobs/seed-dev-lti-manual.yaml b/k8s/jobs/seed-dev-lti-manual.yaml new file mode 100644 index 00000000..72117e89 --- /dev/null +++ b/k8s/jobs/seed-dev-lti-manual.yaml @@ -0,0 +1,19 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: lti-db-seed-manual + namespace: dev-lti +spec: + backoffLimit: 1 + ttlSecondsAfterFinished: 300 + template: + spec: + restartPolicy: Never + containers: + - name: seed + image: 886436954922.dkr.ecr.ap-southeast-3.amazonaws.com/mbugroup/lti-api:dev-f8ca404b + imagePullPolicy: IfNotPresent + command: ["/app/lti-seed"] + envFrom: + - secretRef: + name: lti-env-dev