Skip to content

Production Environments

Alex Ball edited this page May 16, 2023 · 5 revisions

Environments

The site runs on Firebase and Kubernetes and is deployed using Github Actions. It uses several external services as well. The dev site is deployed automatically whenever we push to the main branch. The prod site is deployed whenever we push to the prod branch. Deployments should "just work" but if the site isn't updating, check the status of the deployment action. Kubernetes is currently deployed manually. See more details here

Each environment has its own Firebase project and Kubernetes cluster. In this way, resources and environments are isolated.

Firebase

Firebase services are deployed automatically using Github Actions. To deploy manually, run yarn deploy:backend:dev or yarn deploy:backend:prod.

Deploy to a new project

You can specify the project to deploy to by passing the --project flag to firebase deploy. Follow these steps before deploying to a new firebase environmet, without setting up typesense:

  1. Create a new firebase project through the firebase console.
  2. Create a .env.PROJECT_NAME file in functions folder with this content, to clear out the value:
TYPESENSE_API_KEY=
  1. Create a dummy typesense key so you can deploy the functions:
# From the repo root
yarn firebase --project=PROJECT_NAME functions:secrets:set TYPESENSE_API_KEY
# Enter some gibrish
  1. Deploy the backend by adapting the deploy:dev script in package.json:
# From the repo root
yarn firebase --project=PROJECT_NAME deploy --only firestore,functions,storage
  1. Enable CORS access for your bucket:
cd functions
gsutil cors set cors.json gs://PROJECT_NAME.appspot.com
  1. Configure your frontend to use your new environment by updating the devConfig to use the firebase config from the firebase console project settings, or specify it in the NEXT_PUBLIC_FIREBASE_CONFIG env variable.

One-offs

To perform a migration or run batch scripts, you can either create and deploy a cloud function, then call it manually, or run the code on your local machine with the appropriate credentials for the environment.

To run on your local machine, first acquire a credentials file to grant access to the project. Ask alexjball@ or create a new key for one of the service accounts. Then, use the firebase-admin tool to access the project and run scripts.

For example, to set the role for a particular user by email, run this:

yarn firebase-admin \
    -e dev \
    -c ~/path/to/credentials.json \
  run-script setRole \
    --email=me@alexjball.com \
    --role=admin

You can also deploy a cloud function and trigger it via pubsub, like backfillTestimonyCounts or checkSearchIndexVersion:

PROJECT=digital-testimony-dev

gcloud --project $PROJECT pubsub topics publish backfillTestimonyCounts --message='{"run": true}'

gcloud --project $PROJECT pubsub topics publish checkSearchIndexVersion --message='{"check": true}'

Typesense

The typesense server is deployed to a kubernetes cluster using the files in infra/k8s. To change deployment settings, modify the config files and re-deploy them.

Currently, the dev environment runs on my computer in a single-node k3s cluster, and the config files are written for that environment. It uses traefik for ingress.

Typesense API Keys

Clients authenticate with the typesense server using API keys. We have one main key for updating collections and one key that only allows searching for use in the browser.

The main key is stored in a kubernetes secret resource, which is encrypted and checked-in to the repo using git-secret.

Deployment Steps

  1. Deploy the Kubernetes components of the app using these instructions.
  2. Trigger a search index upgrade check. Post a pubsub message with the content {"check": true} to the checkSearchIndexVersion topic:
gcloud --project digital-testimony-dev pubsub topics publish checkSearchIndexVersion --message='{"check": true}'
  1. Generate a search-only API key for use in the browser:
yarn typesense-admin -e dev create-search-key