Environment Variables
Configuration reference for environment variables across Local, Development, Test, and Production.
Environment matrix
SYS_ENV |
Nitro preset | Data store | Typical trigger |
|---|---|---|---|
local |
node-server |
SQLite (DATABASE_URL=file:./data/local.sqlite) |
Developer machine |
development |
node-server |
PostgreSQL | Docker Compose / PR build on development |
test |
aws_lambda |
DynamoDB | Push to main (SAM, after CI) |
production |
aws_lambda |
DynamoDB | GitHub Release published or manual workflow_dispatch |
Legacy SYS_ENV=remote is treated as development (.output/development and Postgres store selection). All four envs write {workspaceRoot}/.output/<sysEnv> via scripts/nitro-output-dir.mjs.
CI/CD triggers, Docker/SAM commands, and GitHub Environment secrets: docs/cicd.md.
Example templates (no secrets):
.env.example— local defaults.env.development.example.env.test.example.env.production.example
SYS_ENV
- Purpose: Selects Nitro preset, build output layout, and MessageStore adapter
- Type: String
-
Values: localdevelopmenttestproduction(alias:remote→development) - Default:
local
SYS_ENV=local npm run build
SYS_ENV=test npm run build # aws_lambda preset
Nav env chip (showEnvIndicator)
- Purpose: Quiet primary-nav label for the current
SYS_ENV(runtimeConfig.public.sysEnv) - Visibility: Nuxt build-mode layers (
$development/$test→ on;$production→ off), notSYS_ENV. ANODE_ENV=productionbuild hides the chip even whenSYS_ENVisdevelopmentortest. - Public key:
runtimeConfig.public.showEnvIndicator(base defaultfalse; layers override) - UI: Quiet chip at the end of
AppPrimaryNavactions (after contact), viaresolveEnvIndicator(aria-label:Environment: <sysEnv>). Primary links are Work / About / Gallery / Writing / Code only.
Database / AWS (private runtimeConfig)
These map to Nuxt runtimeConfig private keys (databaseUrl, dynamoTable, dynamoPostsTable, awsRegion). Prefer NUXT_* prefixes for runtime overrides (firstNonEmptyEnv in core/web/resolve-process-env.ts prefers NUXT_* over plain names).
Adapter selection and per-env key matrix: docs/web/data-stores.md.
DATABASE_URL
- Purpose: SQLite file URL (local) or Postgres connection string (development)
- Local example:
file:./data/local.sqlite - Development example:
postgres://portfolio:portfolio@postgres:5432/portfolio - Runtime override: Prefer
NUXT_DATABASE_URLin Docker/Lambda so Nuxt replaces baked-emptyruntimeConfig.databaseUrl. PlainDATABASE_URLis also honored by store adapters after empty-string normalization. - Note: Nuxt may bake
databaseUrl: ''at build time whenDATABASE_URLis unset. Empty strings are treated as unset so process env can supply the real connection string.
DYNAMO_TABLE
- Purpose: DynamoDB table name for contact messages (test / production)
- Example (logical base):
Messages - Runtime note: SAM sets the physical name (
portfolio-test-Messages/portfolio-prod-Messages) on Lambda via!Ref. Env examples use the logical base forparameter_overrides/ docs only.
DYNAMO_POSTS_TABLE
- Purpose: DynamoDB table name for blog posts (test / production)
- Example (logical base):
Posts - Aliases:
NUXT_DYNAMO_POSTS_TABLE - Runtime note: Same as
DYNAMO_TABLE— Lambda receives the stack-prefixed name from SAM outputs/!Ref.
AWS_REGION
- Purpose: AWS region for DynamoDB client (canonical default for this repo:
us-west-2) - Example:
us-west-2 - Runtime override: Prefer
NUXT_AWS_REGION(SAM sets this;AWS_REGIONis reserved/injected by Lambda). Empty bakedruntimeConfig.awsRegionfalls through toAWS_REGION/NUXT_AWS_REGION/us-west-2.
ADMIN_TOKEN / NUXT_ADMIN_TOKEN
- Purpose: Shared secret for Docker-only admin APIs (
Authorization: Bearer …) on@tgmc/admin - Behavior: When unset/empty, admin routes return
401(fail closed). Not used by the public@tgmc/webapp. - Local usage: set in
.env/.env.development/.env.test, runnpm run docker:*:admin, openhttp://127.0.0.1:4400/admin, paste the token (stored insessionStorage). - Example:
ADMIN_TOKEN=change-me-local - See: admin.md
CORS_ALLOW_ORIGIN
- Purpose: HTTP API CORS
AllowOriginfor SAM stacks (parameterCorsAllowOrigin) - Type: String
- Default:
*(local/test convenience) - Production:
https://likwidmack.com— must matchSITE_URL/NUXT_PUBLIC_SITE_URL(GitHub Environment varCORS_ALLOW_ORIGIN→ SAMCorsAllowOrigin). No trailing slash. Leaving*widens blast radius if a browser client ever sendsAuthorization.
CDN Configuration
NUXT_APP_CDN_URL
- Purpose: Base URL for CDN / static asset origin (S3 HTTPS or CloudFront)
- Type: String (absolute
http://orhttps://origin only) - Default: Empty (no CDN rewrite; Lambda package does not include
.output/public) - Example:
https://portfolio-test-assets-ACCOUNT.s3.us-west-2.amazonaws.com - Usage: Set before building so Nuxt
app.cdnURLrewrites hashed assets. CD derives the S3 URL when the GitHub var is unset. - Invalid locally: do not set relative values such as
./or bare hosts — those are ignored and must never be used asvite.base(they break absolute routes like/admin/blog).
NUXT_APP_CDN_URL=https://cdn.example.com npm run build
Node Environment
NODE_ENV
- Purpose: Node.js environment mode
- Type: String
- Values:
development,production - Default: Set by npm scripts
- Usage: Affects optimization and debug features
NODE_ENV=production npm run build
Canonical runtime for CI/CD/Docker/SAM is Node.js 24 (see docs/cicd.md).
Deployment
DEPLOYMENT
- Purpose: Deployment target configuration
- Type: String
- Values:
client,server(legacy docs may mentionremote) - Default:
client - Usage: Determines build output and runtime behavior
DEPLOYMENT=server npm run build
Development Server
HOST
- Purpose: Public hostname identity for local / Docker (bind address is often
0.0.0.0viaDOCKER_BIND_HOST) - Type: String
- Local default:
tgmc-portfolio.local(.env.example) - Docker development default:
tgmc-portfolio.test(.env.development.example) - Do not use
*.dev: the.devTLD is HSTS-preloaded; browsers refuse self-signed certificate exceptions - Example:
HOST=tgmc-portfolio.test
PORT
- Purpose: Server port number
- Type: Number
- Default:
4200 - Example:
3000
HOST=0.0.0.0 PORT=4200 npm run dev
Map tgmc-portfolio.local / tgmc-portfolio.test → 127.0.0.1 in the hosts file when using those names.
Nx Cloud
NX_CLOUD_ACCESS_TOKEN
- Purpose: Authenticates Nx CLI to Nx Cloud for remote build/test/lint cache
- Type: String (secret)
- Workspace:
nx.json→nxCloudId - Local: Optional — set in
.env(or shell) sonx/npm run devcan read/write the remote cache - CI: Required — GitHub repository secret
NX_CLOUD_ACCESS_TOKEN(see docs/cicd.md)
Create a token in Nx Cloud → your workspace → Access Tokens. Do not commit real tokens to .env.example.
# Local (after copying token into .env or exporting)
export NX_CLOUD_ACCESS_TOKEN=your-token
npm run test
# GitHub Actions (one-time)
gh secret set NX_CLOUD_ACCESS_TOKEN --body "your-token"
HTTPS
HTTPS
- Purpose: Enable HTTPS/SSL
- Type: Boolean (1/0)
- Default: 0
- Usage: Requires SSL certificates in
bin/ssl/
HTTPS=1 npm run dev
SSL_CERT
- Purpose: Custom SSL certificate path
- Type: String
- Default:
bin/ssl/localhost.crt(viacore/web/bin/ssl/)
SSL_KEY
- Purpose: Custom SSL key path
- Type: String
- Default:
bin/ssl/localhost.key
HTTPS=1 SSL_CERT=/path/to/cert.crt SSL_KEY=/path/to/key.key npm run dev
Common Combinations
Local (SQLite)
Copy .env.example to .env (defaults: SYS_ENV=local, DATABASE_URL=file:./data/local.sqlite). The SQLite file lives under data/ (gitignored).
npm run db:migrate:local
SYS_ENV=local DATABASE_URL=file:./data/local.sqlite npm run dev
Public blog: /blog. Admin (Docker only): npm run docker:admin → http://127.0.0.1:4400/admin.
Development (Postgres / Docker)
SYS_ENV=development DATABASE_URL=postgres://portfolio:portfolio@localhost:5432/portfolio npm run start
Test / Production build (Lambda)
SYS_ENV=test NODE_ENV=production DEPLOYMENT=server npm run build
SYS_ENV=production NODE_ENV=production DEPLOYMENT=server npm run build
Development (With CDN)
NUXT_APP_CDN_URL=https://cdn.example.com npm run dev
HTTPS Development
npm run start:ssl:4200
Related Files
.env.example/.env.*.example— environment templatesnuxt.config.ts— Nitro preset + runtimeConfig wiringserver/db/— MessageStore / BlogPostStore adapters selected bySYS_ENVpackage.json— npm scripts