Mise & runtime secrets setup - #105
Conversation
Coverage diff
Base coverage artifact missing; only PR coverage is shown. 🧮 Per-package delta
|
| # bash is needed by the wrapper shims under ./scripts (with-mise.sh, | ||
| # with-secrets.sh) that root + per-app pnpm scripts route through. | ||
| # Alpine ships only busybox sh, which lacks the bashisms ([[ ]], arrays). | ||
| RUN apk add --no-cache bash && corepack enable |
There was a problem hiding this comment.
Not sure if this is worth doing or there is a better way...
There was a problem hiding this comment.
Shouldn't we completely get rid of corepack already and switch to mise in CI/CD also?
https://mise.jdx.dev/continuous-integration.html#github-actions
|
|
||
| When multiple apps each declare their own secrets, the driver layers them so the host process has all secrets in env by the time `docker compose up` runs. **Compose's `environment:` block is what enforces isolation between services** — each service forwards only the names it lists. So even though the host process briefly holds both frontend's and backend's secrets, the frontend container only sees `NEXTAUTH_SECRET`, the backend container only sees `DATABASE_PASSWORD`, and storybook sees nothing. | ||
|
|
||
| A subtle footgun worth knowing about: **don't share secret *names* between apps.** If `apps/frontend/.env.secret` and `apps/backend/.env.secret` both declare `API_KEY`, the layer that runs last wins for that name in the host process — and both services' `environment: - API_KEY` blocks will receive the same value. Use app-scoped names (`FRONTEND_API_KEY`, `BACKEND_API_KEY`) so each app's secret namespace stays disjoint. |
There was a problem hiding this comment.
I guess this might need more highlighting, maybe even runtime warnings?
|
|
||
| ## Daily usage | ||
|
|
||
| Day-to-day, just use the pnpm scripts. The root scripts route through [scripts/with-mise.sh](../scripts/with-mise.sh) — a tiny shim that prefixes `mise exec --` when mise is on PATH, so the pinned toolchain is used even from a shell that hasn't been activated: |
There was a problem hiding this comment.
Not sure if this is overkill...
| - **`*.local` files** — Developer-specific overrides and secrets, never committed to git. | ||
| - **`.env`** — Committed, non-secret host defaults for running the app on your local machine. | ||
| - **`.env.compose`** — Committed, non-secret Docker defaults for running the app in containers. | ||
| - **`.env.secret`** — Committed, but contains only **references** (e.g. `op://vault/item/field`), not resolved values. Read at task-run time by [scripts/with-secrets.sh](../scripts/with-secrets.sh). |
There was a problem hiding this comment.
Do we also need .env.secrets.local? Would be useful for switcing between envs?
| - `.env.production.local` | ||
| - `.env.test.local` | ||
| - `.env.compose.local` | ||
| - `.env.secret.local` (if anyone uses `op inject` to materialize resolved values locally) |
There was a problem hiding this comment.
Hmm, not sure if this works already... Maybe a better approach would be .env.secret.acpt, and then control with an env variable flag? e.g. pnpm dev -- acpt or something
|
|
||
| ### What if I don't have vault access yet? | ||
|
|
||
| If you're onboarding and don't yet have access to the project's 1Password vault (or equivalent), ask in the team channel to be added. As a short-term workaround you can export the required secrets manually in your shell before running `pnpm dev` — the wrapper's `none` fallback will pass them through if no provider is configured, or you can force it with `SECRETS_PROVIDER=none pnpm dev`. This is a stopgap — the wrapper + vault flow is the supported path. |
There was a problem hiding this comment.
Not sure if we should mention the workaround...
kamdubiel
left a comment
There was a problem hiding this comment.
Only read the code without docs
| !.env.compose | ||
| # Provider-reference manifest for scripts/with-secrets.sh — pointers only, | ||
| # never resolved values. See documentation/Environment variables.md. | ||
| !.env.secret |
There was a problem hiding this comment.
I don't see reason to do another type of env file.
.env and .env.compose should be templates (no commented out lines like you did), so they should even contain the secrets env, but with "REPLACE_ME" or "SECRET" values. On localhost you very often don't even need to use those secrets for 3rd party SaaS, and if you do, you can point your scripts to .env.local and .env.compose.local that are generated automatically on postinstall, are not commited, and can serve as the containers for the secret variables if needed
| # bash is needed by the wrapper shims under ./scripts (with-mise.sh, | ||
| # with-secrets.sh) that root + per-app pnpm scripts route through. | ||
| # Alpine ships only busybox sh, which lacks the bashisms ([[ ]], arrays). | ||
| RUN apk add --no-cache bash && corepack enable |
There was a problem hiding this comment.
Shouldn't we completely get rid of corepack already and switch to mise in CI/CD also?
https://mise.jdx.dev/continuous-integration.html#github-actions
| @@ -1,8 +1,11 @@ | |||
| FROM node:24.11.0-alpine AS base | |||
| FROM node:24.15.0-alpine AS base | |||
There was a problem hiding this comment.
If you're already having fun, make it 26.1.0 and get rid of corepack
|
|
||
| [tools] | ||
| node = "24.15.0" | ||
| pnpm = "10.33.0" |
There was a problem hiding this comment.
Add this for the crazy vibecoders, just in case:
python = "3.14.3"
jq = "1.8.1"
yq = "4.52.4"
rg = "15.1.0"
fd = "10.4.2"
| "engines": { | ||
| "node": "24.11.0" | ||
| "node": "24.15.0", | ||
| "pnpm": "10.33.0" |
|
|
||
| allowBuilds: | ||
| sharp@0.34.5: true | ||
| core-js: false |
There was a problem hiding this comment.
No global allow please just in case core-js maintainer will have another meltdown over night
|
|
||
| - **`.env.local`**: Local development overrides | ||
| - **`.env.compose`**: Docker Compose environment | ||
| - **`.env.local`**: Local development overrides (non-secret) |
There was a problem hiding this comment.
As I wrote - can have secrets but without values. Should serve as templates with all possible env variables
No description provided.