-
Notifications
You must be signed in to change notification settings - Fork 464
Add Varlock for managing config + secrets #1062
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- replaces dotenv with varlock - convert .env.example into .env.schema - ensure env is still loaded correctly - add additional env vars found in codebase to schema clean up schema
- remove extra getEnv() + global ENV logic - use ENV from varlock/env instead of process.env - remove extra coercion/validation - add MODE to schema (we should merge this with NODE_ENV)
| @@ -1,29 +0,0 @@ | |||
| LITEFS_DIR="/litefs/data" | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been converted into .env.schema
| @@ -0,0 +1,102 @@ | |||
| # This env file uses @env-spec - see https://varlock.dev/env-spec for more info | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This schema could be much more thorough, adding more descriptions / links, better validation logic, adding new vars to replace MODE checks.
Huge benefits, and is less overwhelming since the user only needs to set items that differ, rather than copy/pasting all items.
Also note that it is much more legible with code highlighting provided by our VSCode Plugin.
| # @type=enum(development, production, test) | ||
| NODE_ENV=development | ||
| # @type=enum(development, production, test) | ||
| MODE=$NODE_ENV |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved this into the schema itself, and has a default value set, so additional ?? 'development' can be removed in a few places. Ideally we'd remove one of these since there is a mix of checks using one or the other throughout the codebase. Personally we recommend not relying on NODE_ENV.
|
|
||
| 1. Fork repo | ||
| 2. clone the repo | ||
| 3. Copy `.env.example` into `.env` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No longer necessary. Now users only need to manage values that are different than the defaults in .env.schema.
| # change any of these values unless you want to hit real environments. | ||
| cp .env.example .env | ||
| # set anything unless you want to hit real environments. | ||
| touch .env.local |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that .env will also be loaded, so using .env.local instead is not strictly necessary, but is fairly common and helps clarify that it is for local overrides.
| "build": "run-s build:*", | ||
| "build:remix": "react-router build", | ||
| "build:server": "tsx ./other/build-server.ts", | ||
| "dev": "cross-env NODE_ENV=development MOCKS=true node ./server/dev-server.js", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NODE_ENV will now always default to development. MOCKS defaults to true for dev/test and false for prod. Can be overridden explicitly.
| command: process.env.CI ? 'npm run start:mocks' : 'npm run dev', | ||
| port: Number(PORT), | ||
| command: ENV.CI ? 'npm run start:mocks' : 'npm run dev', | ||
| port: ENV.PORT, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PORT is already a number, and already defaults to 3000 :)
| @@ -0,0 +1,9 @@ | |||
| // This file will be introduced soon in prisma upgrade PR | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding this file helps feed DATABASE_URL to prisma. Feels awkward now but will be here anyway once prisma upgrade lands.
| const SENTRY_ENABLED = IS_PROD && process.env.SENTRY_DSN | ||
| const IS_PROD = ENV.MODE === 'production' | ||
| const IS_DEV = ENV.MODE === 'development' | ||
| const SENTRY_ENABLED = IS_PROD && ENV.SENTRY_DSN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good example of something we can migrate into the schema itself. This way the default still relies on a env/mode check, but can be overridden explicitly individually.
| } | ||
|
|
||
| const passthroughGitHub = | ||
| !process.env.GITHUB_CLIENT_ID?.startsWith('MOCK_') && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also something to probably just add an explicit env item for, rather than using dummy values with a prefix.
kentcdodds
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this! I think some folks may really like this, but I'm not prepared to make this the default for the epic stack. Would you be interested in making an example?

This PR adds Varlock to help manage configuration and secrets, converting the
.env.examplefile into a.env.schemawhich contains additional schema information about all configuration in the system. This will improve developer onboarding into the epic stack, as well as ongoing DX as devs add more config into their apps. It adds additional guardrails around configuration in general, and notably adds additional protection for sensitive secrets.Why do this?
.env.schema).env.exampleand.env, which means it will never get out of syncTest Plan
Screenshots
varlock loadshowing loaded and validated envImproved IntelliSense

Leak detection example

Log redaction example

Example of failing env validation

To-Do Before Merging
If this looks good, the main thing remaining before this can be merged is:
Next Steps
However additional steps could be taken to further improve things. These could happen in subsequent PRs, and not all are necessary.
.env.dockerthat is imported explicitly, or rely on MODE = production