Files
step3/ENVIRONMENTS.md
T

4.8 KiB

UAT and production operations

Environment map

Environment Branch Web API Namespace Mongo database NodePorts
UAT main https://ustep3.ranaze.com https://us3q.ranaze.com step3-uat ranaze_step3_uat API 30088, web 30089
PRD production https://step3.ranaze.com https://s3q.ranaze.com step3-prd ranaze_step3_prd API 30090, web 30093

doctor.ranaze.com should issue an HTTP redirect to https://ustep3.ranaze.com. Traefik and Cloudflare configuration are external to this repository.

main is the UAT integration branch. Protect production, disable direct pushes, and promote releases through a reviewed pull request from main. Both deployment workflows build and deploy the exact branch commit with immutable SHA image tags.

Required Gitea secrets

The existing KUBECONFIG secret is shared. Configure these environment-specific secrets before enabling the new workflows:

  • UAT_MONGODB_CONNECTION_STRING and PRD_MONGODB_CONNECTION_STRING
  • UAT_AUTH_JWT_KEY and PRD_AUTH_JWT_KEY (different values)
  • UAT_INTERNAL_PURGE_SECRET and PRD_INTERNAL_PURGE_SECRET
  • UAT_STRIPE_SECRET_KEY and UAT_STRIPE_WEBHOOK_SECRET (Stripe sandbox)
  • PRD_STRIPE_SECRET_KEY and PRD_STRIPE_WEBHOOK_SECRET (Stripe live mode)

Use independent Stripe webhook endpoints for https://us3q.ranaze.com/api/donations/stripe-webhook and https://s3q.ranaze.com/api/donations/stripe-webhook. No Stripe publishable key is required for hosted Checkout.

Initial UAT database migration

Schedule a short maintenance window so writes cannot occur between the dump and cutover.

  1. Route the existing app to a maintenance response or scale the legacy API to zero.

  2. Back up the current database:

    mongodump --uri="$UAT_MONGODB_CONNECTION_STRING" --db=promiscuity --archive=promiscuity.archive --gzip
    
  3. Restore it under the explicit UAT name:

    mongorestore --uri="$UAT_MONGODB_CONNECTION_STRING" --archive=promiscuity.archive --gzip --nsFrom='promiscuity.*' --nsTo='ranaze_step3_uat.*'
    
  4. Compare collection/document counts between promiscuity and ranaze_step3_uat and retain the archive until acceptance testing is complete.

  5. The legacy services currently reserve NodePorts 30088 and 30089. Immediately before the first UAT deployment, release them:

    kubectl delete service step3-questions -n step3-questions
    kubectl delete service step3-web -n step3-web
    
  6. Deploy main, route ustep3 and us3q to the UAT NodePorts, verify login and study activity, then redirect doctor to UAT.

  7. After acceptance, remove the superseded step3-questions and step3-web namespaces. Do not remove them before retaining any logs needed for migration review.

The hostname change creates a new browser origin, so testers should expect to sign in again. Their accounts and activity remain in UAT.

Initial PRD launch

  1. Create and protect the production branch, then merge the tested main revision.

  2. Route step3.ranaze.com and s3q.ranaze.com to PRD NodePorts.

  3. Run Promote UAT content to PRD in dry-run mode and inspect the counts and hash.

  4. Run it again in apply mode with confirmation PROMOTE_TO_PRD.

  5. Verify ranaze_step3_prd contains published content and has no user/activity documents.

  6. Register the initial PRD account normally, then promote it manually:

    use ranaze_step3_prd
    db.Users.updateOne({Username: "SUPER"}, {$set: {Role: "SUPER"}})
    
  7. Configure and test the live Stripe webhook and Steam callback before announcing PRD.

Content promotion behavior

The manual workflow runs the deployed PRD API image as a short-lived pod. It copies only published questions, referenced media, current published CCS revisions, and the CCS order catalog. It never copies users, attempts, ratings, statistics, simulations, reports, feedback, notes, or donations.

Promotion is idempotent and does not delete or implicitly unpublish PRD content. Every applied promotion writes a ContentPromotions audit document. Corrective unpublishing remains an explicit SUPER/API or database operation.

Verification and rollback

Check both internal and public readiness after every rollout:

kubectl get pods -n step3-uat
kubectl get pods -n step3-prd
kubectl get --raw /api/v1/namespaces/step3-uat/services/step3-api:http/proxy/readyz
kubectl get --raw /api/v1/namespaces/step3-prd/services/step3-api:http/proxy/readyz
curl -fsS https://us3q.ranaze.com/api/runtime
curl -fsS https://s3q.ranaze.com/api/runtime

Rollback application code by setting each deployment back to a previously imported SHA-tagged image. Database promotion is non-destructive; restore the pre-cutover archive if the initial UAT migration itself must be reversed.