Configuration

The environment variables the server reads, and the settings that live in the app.

Spooldoc reads a few settings from the environment when it starts, and keeps the rest in the database under Settings, where they change without a restart. apps/web/.env.example lists the variables with comments; copy it to apps/web/.env.local for development, or put the same variables in the .env file next to compose.yaml for Docker.

Environment variables

VariableRequiredDefaultWhat it is
DATABASE_URLYesThe Postgres connection string. docker compose up -d db starts one at postgres://spooldoc:spooldoc@localhost:5433/spooldoc.
BETTER_AUTH_SECRETYesSigns the login sessions. At least 32 characters; openssl rand -base64 32 makes one.
SPOOLDOC_SECRET_KEYYesEncrypts the IBM i passwords of saved servers, the model keys, the Carbone Cloud key and Spooldoc's private key for Carbone (AES-256-GCM). 32 bytes in base64; openssl rand -base64 32 makes one. Keep it: with another key the saved passwords cannot be read and must be entered again.
PORTNo3000The port the server listens on.
APP_URLNoThe address users reach the app at, such as https://spooldoc.example.com. Origin checks accept it and the request's own host, and cookies are marked secure when it is https. Set it behind a reverse proxy.
SPOOLDOC_WATCHERNoonRun the queue watcher in this process. Turn it off on every instance but one; the watcher also takes database locks, so two instances never read the same data queue or run the same job at once.
SPOOLDOC_MIGRATENoonApply the database migrations when the server starts. With it off, run pnpm --filter @spooldoc/web db:migrate yourself.
SPOOLDOC_DEFAULT_CCSIDNoThe code page for spooled files that have no CHRID when the job CCSID is not supported, for example 273 or 37. Also the CCSID of queue descriptions when the system has no default CCSID.
SPOOLDOC_ALLOWED_HOSTSNoComma-separated hosts servers may use. When set, the server form shows a list instead of a free text field.
SPOOLDOC_LOG_LEVELNoinfoHow much the server logs: off, error, warn, info or debug. See Server log.

The server refuses to start with a missing or malformed required variable and says which one. The agent's model, its key and effort, and the Carbone connection are not environment variables: they are set in the app under Settings. So is masking, which was SPOOLDOC_MASK before; the server log says so when that variable is still set. See Carbone and Masking.

The Compose file passes two more variables from .env to the carbone service:

VariableWhat it is
CARBONE_AUTHENTICATION_PUBLIC_KEYSpooldoc's public key, as Settings shows it under Rendering: one line, with \n for each newline.
CARBONE_LICENSEA Carbone Enterprise license. Without it Carbone runs as the Community Edition.

Server log

The server writes its log to stdout, one JSON object per line, so docker compose logs or any log collector can read it. Each line has time, level and msg, and fields such as serverId, jobId, runId and error. Passwords and keys are taken out of error text before it is logged.

{"time":"2026-10-19T08:12:03.512Z","level":"warn","msg":"Real-time watching failed; the queues are polled meanwhile","serverId":"6f1c...","dataQueue":"SPOOLDOC/SPOOLDOC","error":"Connection reset","retryInSeconds":5}

At the default level, info, the log has what fails before a run exists: a server the watcher cannot reach, a queue list it cannot read, real-time watching that stopped and started again, a job whose active version cannot be read, runs a stopped server cut off, a failed cleanup, agent chats that fail, and the warnings and errors of the sign-in library. A problem that lasts is logged once, and again when it is gone. warn keeps only the problems.

Settings in the app

Under Settings, for the whole app:

SettingDefaultWhat it is
Poll interval30 secondsHow often the watcher lists a polled queue.
Safety check5 minutesHow often a real-time queue is listed anyway, in case a data queue entry was missed.
Keep runs for90 daysHow long runs are kept, 1 to 3650 days. See Retention.
AgentNoneThe provider, key, model and effort of the agent. See Agent. The section also shows the agent's usage this month and last month.

The Settings page: Rendering with Carbone connected, its URL and Spooldoc's public key, the Agent with its provider, model and effort, the usage this month and last month, and the other settingsThe Settings page: Rendering with Carbone connected, its URL and Spooldoc's public key, the Agent with its provider, model and effort, the usage this month and last month, and the other settings

Per server and per job

The libraries a server lists queues from are on the server; see Servers. The filters, trigger, formats, destination and finish action are on each job; see Jobs.