Environment variables
Set variables on the process that reads them. A static host environment does not create a writing server. Ordinary editor configuration is read at process start; restart it deliberately after changing these values and verify actual Security/listener state.
Long variable names are separate headings so comparable defaults remain readable on phones. Examples below contain no credentials and are not production deployment certification.
Process map
| Process | Settings it reads |
|---|---|
| Editor | Listener, hosts, body, users, sessions, cookie, proxies |
| Account commands | Users file |
| Builder | Data selectors and progress events |
| Local preview | Preview port |
| Static reader | Generated files, not server environment |
The editor has fixed installed-engine content/static/dist paths in ordinary CLI. Builder --content/--out do not move them. No general PORT, editor data-root, TLS-certificate or content-directory environment selector is supplied at this pin.
MARKSTACK_EDITOR_PORT
Default 3001. Editor uses decimal parseInt(value, 10) || 3001, not preview’s stricter integer parser. Missing, empty, nonnumeric or zero value falls back. Numeric-prefix text such as 3100junk parses to 3100. Negative/out-of-range values are not deliberately normalized by this expression; listener can fail. Use an explicit integer 1-65535 and verify binding/Host allow-list after restart. Port 0 does not request ephemeral allocation here.
MARKSTACK_EDITOR_HOST
Default 127.0.0.1 when unset/empty. This is the listening interface, not accepted browser Host or a TLS setting. A broader bind can expose the writer to the network. Choose deliberate loopback/private binding, external gate and no direct bypass. Changing it requires restart; validate actual listener from both expected and disallowed network contexts.
MARKSTACK_EDITOR_ALLOWED_HOSTS
Default empty additional list. Comma-separated entries are trimmed/lowercased; blank entries removed. Built-in accepted Host values are localhost, IPv4 loopback and bracketed IPv6 loopback with configured editor port.
Additional entries are exact Host header values, including nonstandard port when browser sends it. No scheme/path, wildcard or CIDR match is implemented. This does not bind DNS, add TLS or authorize reader access. Origin, when supplied, must have the same parsed host as Host; POST requires JSON. Incorrect proxy-preserved Host can yield Host not allowed even with working credentials.
MARKSTACK_EDITOR_MAX_BODY
Default 2097152 bytes (2 MiB). Same parseInt then truthy fallback pattern as editor port. It bounds collected request body, not a per-page route quota, upload contract or maximum whole-site size. Invalid/zero values can fall back; negative values are not a sensible limit. Use positive reviewed byte count. Exceeded body yields request failure; verify intended size rather than retrying larger text indefinitely.
MARKSTACK_USERS_FILE
Default engine .markstack/users.json. Editor and create/reset account commands read this path. Relative paths depend on process working directory; use deliberate absolute path for supervised service. Builder also uses its resolved parent as data fallback, not to read passwords into output.
Editor derives links/settings/icons/history and publish marker beside users file. Keep accounts private, outside repository/publishable roots and aligned across server/account commands. Changing this variable can select an empty/different account set; restarting against wrong path is not account recovery. MARKSTACK_DATA_DIR does not move the editor users file.
MARKSTACK_SESSION_IDLE_MINUTES
Default 480 minutes (8 hours). Parsed with parseInt and truthy fallback. The session store requires positive resulting milliseconds, so negative duration causes initialization failure rather than a useful signed-in state. Idle expiry compares elapsed time since last session access. Requests that access session can refresh idle; administrative session summaries do not.
MARKSTACK_SESSION_MAX_MINUTES
Default 10080 minutes (7 days). Same parsing and positive-store requirement. Absolute expiry is measured from session creation, independently of idle refresh. Cookie Max-Age follows this configured maximum. No parser check requires maximum to exceed idle; set a coherent policy and verify actual expiration behavior.
Sessions are in memory. Restart ends them regardless of cookie lifetime. Changing durations requires new process; it is not editing persisted session rows.
MARKSTACK_EDITOR_COOKIE_SECURE
Enabled only by exact string 1; unset, true, yes or 0 leave secure mode off. Enabled mode uses __Host-ms_session, Secure, HttpOnly, SameSite=Strict, Path=/ and no Domain. Local insecure mode uses ms_session; cookie helper clears the alternate mode’s name.
Enable only with working HTTPS. Plain HTTP can prevent browser accepting/sending secure cookie, producing sign-in loops. This setting does not create HTTPS or certificate. Check real response cookie attributes privately without copying token values into support output.
MARKSTACK_TRUSTED_PROXIES
Default empty: forwarded address ignored. Comma-separated entries are trimmed; mapped IPv4 prefix is removed and addresses lowercased. Literal loopback expands to 127.0.0.1 and ::1. Other entries are exact normalized strings, not subnet/CIDR ranges.
Forwarded address is used only when socket peer is in this list. Server walks X-Forwarded-For right to left, skipping trusted entries and taking first other value. This affects login-limiter client identity; it is not a TLS, Host or authentication override. Trust only actual controlled proxy peers and check spoofed/untrusted forwarding denial. Configuring arbitrary clients as trusted undermines that boundary.
MARKSTACK_DATA_DIR
Builder-only data selector. Precedence is --data, then this nonempty variable, then parent of resolved users file, then engine .markstack. Relative value is resolved from working directory. Selects saved settings, header links and cached icons used by reader generation, not permission-filtered pages.
Ordinary editor ignores it as a data-root override: editor runtime derives from users file. Editor publication explicitly snapshots runtime and passes builder --data; do not infer a build environment variable redirects its account/runtime store.
MARKSTACK_PREVIEW_PORT
Default 3000. Preview uses Number(value || 3000) then requires integer 1-65535. Empty string uses default; whitespace can convert to zero and fail. Numeric-prefix junk and fractions fail. Preview binds loopback and serves engine dist only. It does not affect editor port or earlier custom builder output.
MARKSTACK_BUILD_EVENTS
Builder emits machine progress lines only when exact value is 1. Lines begin @@MS followed by JSON events for total/page/stage progress. Ordinary readable logs continue. Editor child sets this for publication progress; it is not a remote telemetry or hosting integration. Do not treat its log label “pages” as only article count when discussing search entries.
Safe syntax example
Unix local development, after confirming installed project and unused port:
MARKSTACK_EDITOR_HOST=127.0.0.1 MARKSTACK_EDITOR_PORT=3101 npm run editor
PowerShell local development:
$env:MARKSTACK_EDITOR_HOST = '127.0.0.1'
$env:MARKSTACK_EDITOR_PORT = '3101'
npm.cmd run editor
These set loopback/plain-local mode, not a production HTTPS service. Account commands still need the same selected users file. Windows service supervision/permissions require separate operational verification.
Verify after change
| Layer | Check |
|---|---|
| Process | Intended restart/environment/working directory |
| Listener | Actual interface/port, no unintended exposure |
| Host | Exact intended value accepted, wrong value denied |
| Account | Intended private runtime/account set |
| Session | Reported durations and actual behavior |
| Cookie | HTTPS/mode works with intended browser |
| Proxy | Trusted peer handling; spoofing denied |
| Builder | Correct effective data and output |
Defaults and parsers describe implementation, not safe production policy. Private team editor and Security and privacy own infrastructure gates. Commands separates builder/preview/account syntax.