Skip to content

Server CLI & environment

Flags and environment variables for the default server invocation — painapple [flags] (or explicitly painapple serve [flags], or python -m painapple_code [flags] from a repo checkout).

painapple help (or a leading -h/--help) prints a curated command overview — serve, setup, docker, list — with the most common flags; painapple serve --help prints the full flag reference below. painapple list shows every instance on the machine: running local server processes plus configured Docker sandboxes.

Saved defaults — painapple setup

painapple setup is an interactive wizard (same widgets and step machine as painapple docker setup) that saves host-mode serve defaults — workspace, bind address, port, TLS mode, instance name, accent — to ~/.painapple-code/serve.yaml. A bare painapple then starts with those values; any explicit flag still overrides its saved default. Three quick sections plus a review screen; nothing is written until you confirm.

# ~/.painapple-code/serve.yaml — written by `painapple setup`, editable by hand
workspace: /home/me/code
host: 127.0.0.1
port: 8765
tls: auto
instance_name: HOME
accent: green

Recognized keys: workspace, workspace_root, host, port, tls, instance_name, accent — each maps 1:1 onto the flag of the same name below. Unknown keys or invalid values are skipped with a warning in the server log; the wizard's "Directory I launch from" workspace choice simply omits the workspace key so a bare painapple keeps using the current directory. The file lives under PAINAPPLE_CODE_HOME (default ~/.painapple-code). Precedence: built-in default < serve.yaml < explicit flag — so systemd units and the Docker entrypoint, which pass everything explicitly, are unaffected.

Container mode lives elsewhere

The painapple docker … subcommand group runs the bridge in Docker/Podman instead of directly on the host — see the Docker CLI reference.

Flags

Defaults shown are the built-ins — values saved by painapple setup replace them; explicit flags override both.

Server — where it listens and what it works on

Flag Default Description
--host 127.0.0.1 Host interface to bind — 127.0.0.1 = this machine only, 0.0.0.0 = every interface (reachable on your LAN)
--port 8765 Port to bind to
--workspace . Workspace directory — the directory Claude operates in. Mapped to /workspace inside Docker. (--cwd is an alias.)
--workspace-root --workspace Directory scanned for sibling project folders surfaced on the welcome screen (the "Unvisited" chips)
--instance-name Instance label for the PWA icon and UI (e.g. DEV, STABLE)
--accent Accent color: a preset name (see below) or a hex value like #f87171

Network security

Flag Default Description
--tls auto TLS mode: auto, on, or off (see below)
--tls-cert <config-dir>/cert.pem TLS certificate path (auto-generated if missing)
--tls-key <config-dir>/key.pem TLS key path (auto-generated if missing)

Advanced

Flag Default Description
--default-provider claude-sdk Provider for new sessions (existing sessions keep their recorded provider)
--enable-eruda off Enable the Eruda mobile-devtools quick action (loads from a CDN)
-v, --version Print version and exit

Multi-instance — isolate state when several servers share one user

Flag Default Description
--shadow-db ~/.painapple-code/shadow.duckdb DuckDB path for the shadow turn store
--log-dir ~/.painapple-code/logs/ Log directory
--state-suffix Per-tier suffix for UI-state files (tab-state, shortcuts, presets, favorites, global config) so co-located instances don't share them. --state-suffix dev gives tab-state-dev.json; a leading - is added automatically. Project and session history stays shared.
--auth-config-file ~/.config/painapple-code/config.yaml Auth config file path

TLS behavior

  • --tls auto (the default) enables TLS only when binding to a non-loopback host. On 127.0.0.1, ::1, or localhost the server stays plain HTTP.
  • --tls on forces TLS; --tls off disables it even on non-loopback binds (the server logs a loud warning — your auth token and chat contents travel the LAN unencrypted).
  • When TLS is enabled, a self-signed certificate is auto-generated at <config-dir>/cert.pem / key.pem (next to the auth config file). There is no OS trust-store install; browsers show a one-time certificate warning.

Non-loopback binds

Binding to a non-loopback host also makes the server trust X-Forwarded-Proto from any client (forwarded_allow_ips is *). For real exposure, put the bridge behind a reverse proxy that sets that header itself — see Read this first.

Environment variables

Variable Purpose
PAINAPPLE_CODE_HOME Override the data directory (default ~/.painapple-code). Set to /data in the Docker image.
PAINAPPLE_CODE_CONFIG Override the config directory (default ~/.config/painapple-code) — where config.yaml and the auto-generated TLS cert/key live.
BRIDGE_ALLOWED_ORIGINS Comma-separated CORS allow-list. Defaults to localhost / 127.0.0.1 on ports 8765, 8800, and 8880. Set this when serving from a public hostname.
PAINAPPLE_REVEAL_CMD Exact "reveal password" command shown verbatim on the login page. Launchers (the Docker wrapper) set this because they know the host-side container name and engine; unset, the page falls back to a per-environment guess.
PAINAPPLE_IN_CONTAINER Set to 1 inside the official image. Gates the filesystem probes that distinguish Docker from Podman for the login page's environment detection — never set this on a bare-metal host.

Accent color presets

--accent accepts any of these preset names, or an arbitrary hex color (--accent '#e11d48'):

Preset Hex
blue #58a6ff
green #22c55e
red #f87171
orange #fb923c
purple #c084fc
cyan #06b6d4
gray (or grey) #9ca3af
yellow #facc15
pink #f472b6
teal #14b8a6
indigo #818cf8
lime #a3e635

Running multiple instances

Use --instance-name, --accent, --state-suffix, --shadow-db, and --log-dir together to run several tiers side by side under one user without them stepping on each other:

painapple --port 8880 --instance-name DEV --accent red \
  --state-suffix dev \
  --shadow-db ~/.painapple-code/shadow-dev.duckdb \
  --log-dir ~/.painapple-code/logs-dev

Each instance needs its own shadow DB — DuckDB is single-writer.

painapple list shows everything running on the machine — every local server process (with its port, PID, and workspace) and every configured Docker sandbox.

Known limitations

This is an MVP; some corners are honestly rough:

  1. Windowing system — works, but doesn't support multiple instances of the same widget and could use a rethink.
  2. Code editor — currently a notepad with syntax highlighting. The plan is a review-driven workflow rather than a VSCode-grade editor; the markdown inline editor is the exception and works well for plan and doc tweaks.
  3. GUI for OS-level features — the git widget and file explorer exist, but the embedded terminal is often the better tool for grep / sed / find / du, so these widgets haven't been a priority.