Deploy basketball-api to k8s (Phase 1c) #18

Closed
opened 2026-03-09 23:40:10 +00:00 by forgejo_admin · 1 comment
Contributor

Lineage

plan-2026-03-08-tryout-prep → Phase 1 → Phase 1c

Repo

forgejo_admin/pal-e-services (tofu changes) + forgejo_admin/basketball-api (verify only)

User Story

As the platform admin,
I want basketball-api deployed and accessible at https://basketball.tail5b443a.ts.net,
So that registration links and coach onboarding links resolve and the email blast can go out today.

Context

basketball-api is built — registration form, coach onboarding, roster view, Stripe webhooks, photo upload, pal-e-auth, all merged to main. CI passes (Woodpecker + Postgres service container). k8s manifests exist in basketball-api/k8s/. But nothing is deployed. There is no live URL. This is the single blocker for every remaining deliverable.

Service onboarding SOP (service-onboarding-sop) is a 7-step checklist. Steps 3 (scaffold repo) and 4 (activate Woodpecker) are already done. Remaining work:

  1. Add to var.services in pal-e-services
  2. tofu apply
  3. Create secrets in new namespace
  4. Add Harbor robot creds to Woodpecker repo settings
  5. Push → pipeline → Harbor → ArgoCD → live

Postgres runs as a standalone Deployment with 1Gi PVC (not CNPG). Three Alembic migrations must run after first deploy (001 initial, 002 player fields, 003 coach model).

File Targets

pal-e-services:

  • k3s.tfvars — add basketball-api to var.services map

basketball-api (no code changes — verify only):

  • k8s/ — manifests already correct (deployment, postgres, service, kustomization)
  • .woodpecker.yaml — build-and-push step already exists

Acceptance Criteria

  • basketball-api added to var.services in pal-e-services:
    • forgejo_repo: "forgejo_admin/basketball-api"
    • image_repo: "basketball-api/api"
    • port: 8000
    • funnel: true
  • tofu apply succeeds — creates namespace, ArgoCD app, Harbor project, robot accounts, image pull secret
  • basketball-api-secrets created in basketball-api namespace:
    • postgres-password — generated strong password
    • stripe-webhook-secret — from ~/secrets/
    • stripe-api-key — from ~/secrets/
  • pal-e-auth-secrets created in basketball-api namespace:
    • jwt-secret-key — generated strong secret
    • google-client-id — from pal-e-auth config
    • google-client-secret — from pal-e-auth config
  • Harbor robot credentials added to Woodpecker repo settings (harbor_username, harbor_password from tofu output)
  • Push to main triggers pipeline → image built → pushed to Harbor
  • ArgoCD syncs → basketball-api + postgres pods running
  • Alembic migrations run against new Postgres: alembic upgrade head (3 migrations)
  • curl https://basketball.tail5b443a.ts.net/healthz → 200 OK
  • curl https://basketball.tail5b443a.ts.net/register → registration form HTML
  • curl https://basketball.tail5b443a.ts.net/docs → FastAPI OpenAPI page

Test Expectations

No code changes — this is infrastructure. Verification is the AC curl commands above.

Constraints

  • Follow service-onboarding-sop exactly — known path, don't improvise
  • Secrets must NOT be committed to any repo — create via kubectl from ~/secrets/
  • Postgres password must be strong (generated, not "basketball")
  • Woodpecker CI logs are broken platform-wide (upstream bug #4409) — verify pipeline via status badge, not log output

Checklist

  • var.services entry + tofu applied
  • Secrets created in namespace
  • Harbor creds in Woodpecker
  • Pipeline runs, image in Harbor
  • ArgoCD syncs, pods healthy
  • Migrations run
  • Healthz + register + docs accessible via funnel
  • project-westside-basketball
  • service-onboarding-sop
  • Plan critical path: this unblocks registration tokens → email blast (TODAY)
### Lineage `plan-2026-03-08-tryout-prep` → Phase 1 → Phase 1c ### Repo `forgejo_admin/pal-e-services` (tofu changes) + `forgejo_admin/basketball-api` (verify only) ### User Story As the platform admin, I want basketball-api deployed and accessible at https://basketball.tail5b443a.ts.net, So that registration links and coach onboarding links resolve and the email blast can go out today. ### Context basketball-api is built — registration form, coach onboarding, roster view, Stripe webhooks, photo upload, pal-e-auth, all merged to main. CI passes (Woodpecker + Postgres service container). k8s manifests exist in `basketball-api/k8s/`. But nothing is deployed. There is no live URL. This is the single blocker for every remaining deliverable. Service onboarding SOP (`service-onboarding-sop`) is a 7-step checklist. Steps 3 (scaffold repo) and 4 (activate Woodpecker) are already done. Remaining work: 1. Add to var.services in pal-e-services 2. tofu apply 3. Create secrets in new namespace 4. Add Harbor robot creds to Woodpecker repo settings 5. Push → pipeline → Harbor → ArgoCD → live Postgres runs as a standalone Deployment with 1Gi PVC (not CNPG). Three Alembic migrations must run after first deploy (001 initial, 002 player fields, 003 coach model). ### File Targets **pal-e-services:** - `k3s.tfvars` — add basketball-api to var.services map **basketball-api (no code changes — verify only):** - `k8s/` — manifests already correct (deployment, postgres, service, kustomization) - `.woodpecker.yaml` — build-and-push step already exists ### Acceptance Criteria - [ ] `basketball-api` added to `var.services` in pal-e-services: - forgejo_repo: `"forgejo_admin/basketball-api"` - image_repo: `"basketball-api/api"` - port: 8000 - funnel: true - [ ] `tofu apply` succeeds — creates namespace, ArgoCD app, Harbor project, robot accounts, image pull secret - [ ] `basketball-api-secrets` created in basketball-api namespace: - `postgres-password` — generated strong password - `stripe-webhook-secret` — from ~/secrets/ - `stripe-api-key` — from ~/secrets/ - [ ] `pal-e-auth-secrets` created in basketball-api namespace: - `jwt-secret-key` — generated strong secret - `google-client-id` — from pal-e-auth config - `google-client-secret` — from pal-e-auth config - [ ] Harbor robot credentials added to Woodpecker repo settings (`harbor_username`, `harbor_password` from tofu output) - [ ] Push to main triggers pipeline → image built → pushed to Harbor - [ ] ArgoCD syncs → basketball-api + postgres pods running - [ ] Alembic migrations run against new Postgres: `alembic upgrade head` (3 migrations) - [ ] `curl https://basketball.tail5b443a.ts.net/healthz` → 200 OK - [ ] `curl https://basketball.tail5b443a.ts.net/register` → registration form HTML - [ ] `curl https://basketball.tail5b443a.ts.net/docs` → FastAPI OpenAPI page ### Test Expectations No code changes — this is infrastructure. Verification is the AC curl commands above. ### Constraints - Follow service-onboarding-sop exactly — known path, don't improvise - Secrets must NOT be committed to any repo — create via kubectl from ~/secrets/ - Postgres password must be strong (generated, not "basketball") - Woodpecker CI logs are broken platform-wide (upstream bug #4409) — verify pipeline via status badge, not log output ### Checklist - [ ] var.services entry + tofu applied - [ ] Secrets created in namespace - [ ] Harbor creds in Woodpecker - [ ] Pipeline runs, image in Harbor - [ ] ArgoCD syncs, pods healthy - [ ] Migrations run - [ ] Healthz + register + docs accessible via funnel ### Related - `project-westside-basketball` - `service-onboarding-sop` - Plan critical path: this unblocks registration tokens → email blast (TODAY)
Author
Contributor

Phase 1c: Already deployed

Investigation found the infrastructure was already set up 13 days ago:

  • Namespace, ArgoCD app, Harbor project, secrets, Tailscale funnel — all in place
  • Image was stale at f8e21df (5 commits behind HEAD) due to platform-wide Image Updater auth bug

What was done

  1. Diagnosed Image Updater registry auth mismatch — filed bug-image-updater-registry-auth in pal-e-docs
  2. Manual image bump to b0fc60f (commit 0eea78d)
  3. ArgoCD synced, new pod running, migrations auto-applied (001-003)

Verification

  • https://basketball-api.tail5b443a.ts.net/healthz{"status":"ok"}
  • https://basketball-api.tail5b443a.ts.net/register → Registration form renders
  • https://basketball-api.tail5b443a.ts.net/docs → Swagger UI loads

Note: Hostname is basketball-api.tail5b443a.ts.net (not basketball.tail5b443a.ts.net as originally planned — service name becomes the subdomain).

Remaining concern

Image Updater is broken platform-wide. Future pushes to main won't auto-deploy. Manual image bumps needed until the platform bug is fixed.

## Phase 1c: Already deployed Investigation found the infrastructure was already set up 13 days ago: - Namespace, ArgoCD app, Harbor project, secrets, Tailscale funnel — all in place - Image was stale at `f8e21df` (5 commits behind HEAD) due to platform-wide Image Updater auth bug ### What was done 1. Diagnosed Image Updater registry auth mismatch — filed `bug-image-updater-registry-auth` in pal-e-docs 2. Manual image bump to `b0fc60f` (commit `0eea78d`) 3. ArgoCD synced, new pod running, migrations auto-applied (001-003) ### Verification - `https://basketball-api.tail5b443a.ts.net/healthz` → `{"status":"ok"}` - `https://basketball-api.tail5b443a.ts.net/register` → Registration form renders - `https://basketball-api.tail5b443a.ts.net/docs` → Swagger UI loads **Note**: Hostname is `basketball-api.tail5b443a.ts.net` (not `basketball.tail5b443a.ts.net` as originally planned — service name becomes the subdomain). ### Remaining concern Image Updater is broken platform-wide. Future pushes to main won't auto-deploy. Manual image bumps needed until the platform bug is fixed.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/basketball-api#18
No description provided.