Skip to content

Configuration

Complete environment-variable reference for Portwing, grouped by category.

All configuration is done through environment variables — no config file is required. Variables with no default must be set explicitly; unmarked defaults are applied automatically at startup.

For auth-method selection and key-enrollment flows, see Authentication. For mode-specific setup (Standard vs. Edge), see Connection Modes.


Connection

VariableDefaultDescription
PORT3000TCP port the HTTP server listens on.
BIND_ADDRESSStandard: 0.0.0.0; Edge: 127.0.0.1IP address the HTTP/operations listener binds to. Edge mode defaults to loopback because its operations routes have no inbound authentication; explicitly use a broader address only on an isolated monitoring network.
DRYDOCK_URLWebSocket URL for Edge mode (e.g. wss://drydock.example.com). When set, Portwing operates in Edge mode and connects outbound to Drydock. A plaintext http:///ws:// scheme is rejected at startup unless ALLOW_INSECURE_EDGE_URL=true.
ALLOW_INSECURE_EDGE_URLfalseDangerous opt-in to connect Edge mode to a plaintext http:///ws:// DRYDOCK_URL. The controller's identity is otherwise verified by TLS alone, so this is for trusted local testing only.
TLS_CERTPath to server TLS certificate (Standard mode). Must be set together with TLS_KEY; partial configuration is a startup error.
TLS_KEYPath to server TLS private key (Standard mode). Must be set together with TLS_CERT; partial configuration is a startup error.
CA_CERTPath to a custom CA certificate used when verifying the Drydock server in Edge mode.
TLS_SKIP_VERIFYfalseDisable TLS certificate verification on the outbound Edge connection. Testing only.
TRUSTED_PROXIESComma-separated list of CIDRs (e.g. 10.0.0.0/8,172.16.0.0/12) for reverse proxies whose X-Forwarded-For header Portwing will trust for real-IP resolution. When unset, forwarding headers are ignored entirely.

TRUSTED_PROXIES affects rate-limiting and IP-based access controls. An over-broad CIDR (e.g. 0.0.0.0/0) lets any client spoof its source IP, bypassing those controls. Set only the CIDRs of your actual proxy infrastructure.

Authentication variables

The following variables govern how Portwing authenticates incoming requests. TOKEN and TOKEN_HASH are mutually exclusive — setting both causes startup to fail.

VariableDefaultDescription
TOKENPlaintext shared-secret token. Acceptable for local dev; prefer TOKEN_HASH in production.
TOKEN_FILEPath to a file whose trimmed contents are used as the token. Overrides TOKEN.
TOKEN_HASHArgon2id hash of the token (generate with portwing hash-token). Preferred over plaintext.
TOKEN_HASH_FILEPath to a file containing the Argon2id hash. Overrides TOKEN_HASH.
AUTHORIZED_KEYSPath to an Ed25519 authorized_keys file for per-client asymmetric authentication (Model B). AUTHORIZED_KEYS_FILE is an alias for this variable.
AUTHORIZED_KEYS_FILEAlias for AUTHORIZED_KEYS.
MAX_CLOCK_SKEW_SECONDS60Maximum tolerated clock difference (seconds) between client and agent when validating Ed25519 request timestamps. Range: 1..4611686018 seconds.
NONCE_LRU_SIZE10000Capacity of the in-memory nonce cache used for replay protection.
ENROLLMENT_TOKENOne-shot bootstrap token for Model C key enrollment; consumed on first use.
ENROLLMENT_TOKEN_FILEPath to a file containing the enrollment token.
PRIVATE_KEY_FILEPath to an Ed25519 private key (PEM PKCS#8) used to sign the agent's Edge-mode hello message.
ALLOW_UNAUTHENTICATEDfalseExplicit development-only opt-in to start Standard mode without a credential. Safe by default only on a loopback BIND_ADDRESS.
ALLOW_UNAUTHENTICATED_REMOTEfalseAdditional dangerous opt-in required when an unauthenticated listener binds a non-loopback address.

TOKEN stores the secret in plaintext in the process environment. Use TOKEN_HASH (Argon2id) for any environment accessible to more than one person, or where secret scanning tools may read process state.

Standard mode fails closed when none of TOKEN, TOKEN_HASH, or AUTHORIZED_KEYS is configured. ALLOW_UNAUTHENTICATED=true is intended for local development only. Portwing requires the additional ALLOW_UNAUTHENTICATED_REMOTE=true acknowledgement before it will expose an unauthenticated listener on a non-loopback address.


Docker

VariableDefaultDescription
DOCKER_SOCKETAuto-detectPath to the Docker Unix socket. Portwing checks /var/run/docker.sock, ~/.docker/run/docker.sock, ~/.orbstack/run/docker.sock, and /run/docker.sock in that order; falls back to /var/run/docker.sock if none exist.
STACKS_DIR/data/stacksDirectory where Compose stack files are stored and managed.

Portwing talks to the Docker daemon over the Unix socket only — there is no DOCKER_HOST TCP transport.


Agent Identity

VariableDefaultDescription
AGENT_IDUUID v4 (generated)Stable unique identifier for this agent instance. Set explicitly to preserve identity across restarts.
AGENT_NAMESystem hostnameHuman-readable label shown in Drydock and audit logs. Falls back to portwing if the hostname cannot be read.

Operational

Duration settings require integer seconds. Empty values use the defaults; malformed or out-of-range values stop startup and name the setting. The upper bound also cannot exceed the platform's integer maximum (2147483647 on 32-bit builds).

VariableDefaultDescription
LOG_LEVELinfoLog verbosity. Accepted values: debug, info, warn, error.
HEARTBEAT_INTERVAL30Seconds between WebSocket ping frames in Edge mode. The read deadline is max(2 * HEARTBEAT_INTERVAL, 60) seconds. Range: 1..4611686018 seconds.
WELCOME_TIMEOUT30Seconds to wait for the Drydock welcome message after the WebSocket handshake in Edge mode. Range: 1..4611686018 seconds.
REQUEST_TIMEOUT30Timeout in seconds for individual Docker API calls; 0 disables the timeout. Range: 0..4611686018 seconds.
RECONNECT_DELAY1Initial reconnect backoff delay in seconds; 0 retries immediately (doubles on each failure, capped at MAX_RECONNECT_DELAY, with ±25% jitter). Range: 0..4611686018 seconds.
MAX_RECONNECT_DELAY60Maximum reconnect backoff delay in seconds. Range: 0..4611686018 seconds.
SKIP_DF_COLLECTIONfalseSet to true (or 1/yes) to disable disk-usage metric collection. Useful when the host filesystem is inaccessible or collection is slow.
MAX_STREAM_SESSIONS100Standard mode only: maximum concurrent streaming Docker proxy responses. A non-positive value disables the bound. Edge mode enforces the same 100-session limit, but it is fixed and not configurable.
MAX_EXEC_SESSIONS100Standard mode only: maximum concurrent hijacked exec/attach sessions. A non-positive value disables the bound. Edge mode enforces the same 100-session limit, but it is fixed and not configurable.
AUDIT_LOGOptional persistent audit destination: stdout, stderr, or an absolute file path. When unset, only the sink is disabled; AUDIT_BUFFER_SIZE still controls in-memory retention.
AUDIT_BUFFER_SIZE256Number of audit records retained in the in-memory ring buffer for pull-based retrieval at GET /_portwing/audit. Set to 0 to disable the buffer. Independent of AUDIT_LOG. Retained display fields are copied and capped at 4096 bytes for path, stack, and container; 64 bytes for method; and 256 bytes for actor, operation, exec_id, and key_id. Oversized fields end with [truncated] within that cap, preserving UTF-8 character boundaries. These limits apply only to in-memory audit retention, not incoming requests or the persistent audit sink.

Adapter

VariableDefaultDescription
ADAPTERdrydockWire protocol adapter. drydock enables the Drydock-compatible SSE/REST surface; generic exposes a standalone REST+SSE API without Drydock-specific extensions.

Drydock Compatibility

These variables mirror Drydock agent configuration names for deployments managed by a Drydock controller.

VariableDefaultDescription
DD_AGENT_SECRETDrydock agent secret token. Read before TOKEN is applied; TOKEN takes precedence if both are set.
DD_AGENT_SECRET_FILEFile containing the Drydock agent secret token.
DD_POLL_INTERVAL300Container inventory refresh interval in seconds (Drydock-compatible polling mode). Range: 1..4611686018 seconds.