-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path.env.example
More file actions
137 lines (110 loc) · 5.29 KB
/
.env.example
File metadata and controls
137 lines (110 loc) · 5.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# TimeTrackerAPI — environment configuration template.
#
# Copy to `.env` and fill in real values for local development. In production,
# set these via your process manager (systemd, pm2) or container runtime —
# do not commit a populated `.env`.
#
# `.env` is gitignored; this `.env.example` file is the canonical reference.
# ---- Mode ----
# Set to `production` to enable strict startup checks (most importantly:
# the server refuses to boot when DB_PASSWORD is empty instead of warning
# and continuing). Leave unset / `development` for local + test runs that
# don't need a real database. The Dockerfile and docker-compose.yml api
# service both default this to `production` automatically.
# NODE_ENV=production
# ---- HTTP server ----
# Port the API listens on. Use a non-privileged port (>1024) so the process
# can run as a non-root user. Front the service with nginx/Caddy if you
# need to terminate on :443.
PORT=3000
# Address to bind. 0.0.0.0 listens on all interfaces (container default).
# Use 127.0.0.1 to restrict to localhost.
HOST=0.0.0.0
# Comma-separated list of allowed CORS origins. Leave unset to disable
# cross-origin requests entirely (recommended unless your frontend lives
# on a different host).
#
# Examples:
# CORS_ORIGIN=http://localhost:4200
# CORS_ORIGIN=https://app.example.com,https://admin.example.com
CORS_ORIGIN=
# ---- TLS reverse proxy (optional, docker-compose.tls.yml) ----
# Domain Caddy provisions a Let's Encrypt cert for. Set to your real
# FQDN in production, or 'localhost' for a self-signed cert (Caddy's
# built-in CA — your browser will warn, but the wiring is identical
# for HSTS / cookie-secure testing).
#
# Required if you bring up docker-compose.tls.yml; ignored otherwise.
# TLS_DOMAIN=node.timetrackerapi.com
# Email forwarded to Let's Encrypt for cert-expiry notices. Optional
# but recommended in production.
# TLS_EMAIL=ops@example.com
# ---- PostgreSQL ----
DB_HOST=localhost
DB_PORT=5432
DB_NAME=timetracker
DB_USER=timetracker
# Set a real password here. The configured database user must have access
# to the `dbo` schema. Do NOT commit a populated `.env`.
#
# REQUIRED in production: if NODE_ENV=production and DB_PASSWORD is empty,
# the server refuses to start (exits 1) rather than coming up with broken
# DB connectivity. Dev/test runs warn and keep going.
DB_PASSWORD=changeme
# ---- Logging ----
# pino log level. One of: trace|debug|info|warn|error|fatal|silent.
# Default 'info' is fine for production; turn up to 'debug' when chasing
# a bug, down to 'warn' if log volume is a budget concern.
# LOG_LEVEL=info
# Set to '1' to switch the JSON output to a human-readable pretty
# format via pino-pretty. Useful in development; leave unset in
# production so log aggregators get the structured JSON they expect.
# LOG_PRETTY=
# Set to '1' to route Sequelize query logs through pino at debug
# level (visible when LOG_LEVEL=debug, silent otherwise). Default
# unset: Sequelize query logging is OFF entirely, because the
# default `console.log` Sequelize uses would otherwise dump SQL +
# bound parameters (including secrets like authKey values) to
# stdout, bypassing pino's redact paths. Turn this on for targeted
# query-shape debugging only; turn it off again when done.
# DB_LOG_QUERIES=
# ---- Rate limiting ----
# Per-key request budget for /v1/* in the window below. Defaults to 100.
# Set to 0 to disable rate limiting entirely (useful for load tests).
# RATE_LIMIT_MAX=100
# Rolling window in milliseconds. Defaults to 15 minutes (900000).
# RATE_LIMIT_WINDOW_MS=900000
# ---- Body size + headers ----
# Maximum request body size (express.json limit). Defaults to '100kb'.
# Accepts the same forms as bytes (e.g. '512kb', '1mb'). Bumping this
# is rarely needed — the largest legitimate body in the schema is a
# TimeEntry create with a 10000-char teDescription.
# JSON_BODY_LIMIT=100kb
# Set to '1' to re-enable helmet's Content-Security-Policy. Disabled by
# default because this is a JSON API and a misconfigured CSP would
# break Swagger UI at /docs.
# HELMET_CSP=
# ---- Reverse-proxy / observability ----
# When set, the server trusts X-Forwarded-* headers from a reverse
# proxy so rate-limit / log-IP / etc. resolve to the real client IP.
# Accepts 'true' (trust any proxy) or a hop count (e.g. '1' for one
# reverse proxy in front). Default false — never trust XFF from a
# non-proxied client.
# TRUST_PROXY=true
# Canonical base URL the API is reachable at, used to build absolute
# URLs in the RFC 5988 Link header (next/prev/first/last pagination
# refs). Pin this in production so a client sending `Host: evil.com`
# can't get evil.com echoed back into the Link header and influence
# how its own paginating client walks the result set. Unset = derive
# from `req.protocol` + `req.get('host')` (the express default,
# which is safe when an upstream proxy filters Host).
# PUBLIC_BASE_URL=https://api.example.com
# Optional bearer token gating /metrics. Unset = open scrape (the
# usual private-network deployment pattern). When set, the
# Prometheus scrape must include `Authorization: Bearer <token>`.
# METRICS_BEARER_TOKEN=
# How long the graceful-shutdown drain may run before we force-exit
# with code 1. Default 25_000 (25 seconds) — long enough for in-flight
# requests to finish, short enough that systemd / k8s don't SIGKILL
# us first.
# SHUTDOWN_TIMEOUT_MS=25000