-
Notifications
You must be signed in to change notification settings - Fork 15
Portal environment variables
The portal is built to be self-hostable by different customers, so its configuration has to be quite flexible to support various infrastructures and cloud providers. This is achieved with a set of (mostly required) environment variables, which need to configured properly to deploy (or locally run) an instance of the portal.
Warning
Some of these environment variables contain secrets (examples below are redacted) which should not be shared with anyone in plain text or hard-coded in any Git repository. For sharing these secrets in chat, use some password manager (e.g. 1Password) or OneTimeSecret. To access them in code, use environment variables (optionally in .env
files - should be in .gitignore
). To access them in CI/CD pipeline definitions, use the recommended secrets manager, for example:
The front-end need this value to know where it's corresponding GraphQL API is hosted for back-end communication.
This variable is used by the NGINX-based Docker image for the portal front-end (europe-docker.pkg.dev/code-pushup/portal/portal-ui
). It's used to overwrite the SPA's assets/config.json
file when the container starts.
If you're not using the Docker image to serve the front-end, then replacing the apiUrl
property in assets/config.json
has the same effect. The front-end fetches the config.json
when bootstrapping the application, before sending any API requests.
BTW: The API URL also appears in the code-pushup.config.ts
in the upload.apiUrl
property.
Examples:
-
API_URL=http://localhost:4000
- API served locally -
API_URL=https://api.code-pushup.example.com/graphql
- API instance deployed under customer's own domain -
API_URL=https://code-pushup-portal-api-clpk79mnpa-ew.a.run.app/graphql
- API deployed to Cloud Run (without custom domain)
These variables need to be configured to run the API Docker image (europe-docker.pkg.dev/code-pushup/portal/portal-api
) or serve the API locally from source.
The back-end needs to know where it's corresponding front-end is hosted, in order to create accurate links to uploaded reports (among other things).
This should be the root URL where users visit the portal (prefer a custom domain if there is one), without any specific paths used within the app (no /login
or /portal/...
suffixes).
Examples:
-
PORTAL_URL=http://localhost:4200
- front-end served locally (default Angular port) -
PORTAL_URL=http://localhost:8000
- front-end served locally (another port) -
PORTAL_URL=https://app.code-pushup.dev
- front-end hosted by Code PushUp -
PORTAL_URL=https://code-pushup.example.com
- front-end deployed under customer's own domain -
PORTAL_URL=https://code-pushup-portal-ui-xafg57nogg-ew.a.run.app
- front-end deployed to Cloud Run (without custom domain)
The API needs to know which MongoDB database to connect to, so it expects the MONGODB_URI
environment variable to contain a MongoDB connecting string (including user and password if needed). The API also needs to know if it can use transactions (more robust report uploads), which is defined by the MONGODB_IS_REPLICA_SET
boolean variable.
The values depend on how you're running MongoDB:
-
MongoDB Atlas is a fully-managed cloud-hosted database with automated scaling and backups, so it the easiest way to deploy and manage MongoDB. Clusters can be deployed to AWS, GCP or Azure and billing may also be managed in another cloud provider using AWS Marketplace, Azure Marketplace or GCP Marketplace.
- The connection string can be found in the Atlas UI by clicking Connect. It is in the format
mongodb+srv://<username>:<password>@<clusterName>.mongodb.net/
(optionally with query params like?retryWrites=true&w=majority
). - Atlas uses replica sets, so transactions are supported.
- The connection string can be found in the Atlas UI by clicking Connect. It is in the format
- The official MongoDB Docker image is useful for running a MongoDB instance locally using Docker, e.g. for testing or demos.
- The connection string is
mongodb://localhost:27017
(if using the default port). - No replica sets, so transaction's aren't supported.
- The connection string is
- ... some other options which might be considered in certain use cases: MongoDB Community Edition, MongoDB Enterprise Advanced, Azure Cosmos DB for MongoDB, Amazon DocumentDB
Example for MongoDB Atlas:
MONGODB_URI='mongodb+srv://admin:█████████@code-pushup.7wmil.mongodb.net/?retryWrites=true' # password redacted
MONGODB_IS_REPLICA_SET=true
Example for mongo
image from Docker Hub:
MONGODB_URI=mongodb://localhost:27017
MONGODB_IS_REPLICA_SET=false
Note
Skip this section if you don't need to integrate any GitHub repositories in your portal instance.
The portal API needs to fetch repository content (branches, commits, etc.) from the Git provider where the project's source code is hosted. For projects hosted on GitHub, read-only access to the GitHub API is needed.
The portal authenticates as a GitHub App. Therefore it requires the app's ID (GITHUB_APP_ID
) and private key (GITHUB_APP_PRIVATE_KEY
). Both of these can be found/created in the GitHub App's general settings page. The private key variable should contain the multi-line text content of the .pem
file.
For self-hosting customers a GitHub App should be created in their organization and given Repository permissions for Contents and Metadata with Read-only access.
Warning
The GitHub App must be installed in every repository which is integrated in the portal. Otherwise the portal will fail to load the project.
Example:
GITHUB_APP_ID=172938
GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n████████████████\n-----END RSA PRIVATE KEY-----\n" # redacted
Note
Skip this section if you don't need to integrate any GitLab projects in your portal instance.
The portal API needs to fetch repository content (branches, commits, etc.) from the Git provider where the project's source code is hosted. For projects hosted on GitLab, read-only access to the GitLab API is needed.
The GITLAB_TOKEN
variable should contain an access token with read_api
and read_repository
scopes. It can be a personal access token, group access token, etc. - more info in GitLab Token overview docs. For private projects, the minimum required role for group/project tokens is Reporter
(more info in Permissions and roles - Repository docs).
Warning
The user/group who owns the access token must have access to all GitLab projects integrated in the portal.
For customers with self-hosted GitLab, it is also necessary to specify the domain in the GITLAB_HOST
environment variable. If left unspecified, the host is assumed to be https://gitlab.com
.
Example with personal access token:
GITLAB_TOKEN=glpat-██████████ # redacted
Example for self-hosted GitLab:
GITLAB_TOKEN=glpat-██████████ # redacted
GITLAB_HOST=https://gitlab.example.com
The portal's sign-in flow includes sending an email with a magic link, so an SMTP connection is needed in order to send these emails. Configuration details will depend on which email provider the customer wants to use.
The underlying implementation is in Nodemailer, so refer to SMTP transport docs for what configuration options are available. Environment variables with EMAIL_
-prefix are converted into the options object argument to the createTransport
function. The EMAIL_
-prefix is stripped, UPPER_CASE
is converted to camelCase
and __
is used to separate nested keys - e.g. EMAIL_AUTH__USER
environment variable sets the auth.user
property.
An additional EMAIL_SENDER
environment variable is supported to set the address emails are sent from. Otherwise, the EMAIL_AUTH__USER
environment variable is used as the sender address.
Example for GMail in Google Workspace using service account with domain-wide delegation (in case of problems, set OAuth2 scope to https://mail.google.com/
instead of https://www.googleapis.com/auth/gmail.send
):
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=465
EMAIL_SECURE=true
EMAIL_AUTH__TYPE=OAuth2
EMAIL_AUTH__USER=john.doe@example.com # some email from Google Workspace
EMAIL_AUTH__SERVICE_CLIENT=123456789... # "client_id" of service account
EMAIL_AUTH__PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n████████████████" # "private_key" from service account's .json key, redacted
Example for GMail using App Password:
EMAIL_SERVICE=gmail
EMAIL_AUTH__USER=code.pushup@example.com
EMAIL_AUTH__PASS=████████████████ # 16-character password, redacted
Example for SendGrid with domain authentication or single-sender verification:
EMAIL_SENDER=code.pushup@example.com # authorized single-sender or domain
EMAIL_HOST=smtp.sendgrid.net
EMAIL_PORT=587
EMAIL_AUTH__USER=apikey
EMAIL_AUTH__PASS='SG.████████████████████████████████' # API key from SendGrid with "Mail Send" access
The portal's authentication flow requires an HMAC secret. It can be any 256-bit key generated by some CSPRNG. It should be unique for each portal instance.
If you have Node installed, then simply execute node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
in your terminal and copy the printed value.
Example:
HMAC_SECRET=████████████████████████████████ # 64 hex characters, redacted