Uniform stock management for healthcare linen rooms: the coordinator app, the phone counter and the staff app, for your own server. Built from 794bab5 on 2026-09-16. Licensed under the Functional Source License (FSL-1.1-ALv2).
Settings go in .env in the checkout. docker-compose.yml passes the whole file to the app container, then sets five values itself, and those win over .env:
Variable
Set by compose to
DATABASE_URL
The bundled db service, using POSTGRES_PASSWORD
EDITION
community
PHOTO_DIR
/data/photos
PORT
3000
HOSTNAME
0.0.0.0
Variables starting NEXT_PUBLIC_ are compiled into the app when the image is built. The build does not read .env: compose passes only NEXT_PUBLIC_SITE_URL and NEXT_PUBLIC_TURNSTILE_SITEKEY into it. Any other NEXT_PUBLIC_ variable in .env has no effect on a Docker install. A change to either of those two needs docker compose up -d --build; any other change needs docker compose up -d.
The repository's .env.example lists the variables the Community edition reads. The tables below also list the ones only threadcount.tech uses, marked hosted only, so you know they can stay blank.
Required
Variable
Default
What it does
SESSION_SECRET
change-me
Signs every session cookie. The server refuses to start with the placeholder or with none. Make one with openssl rand -base64 48.
POSTGRES_PASSWORD
none
The bundled database's password. Compose refuses to start without it.
NEXT_PUBLIC_SITE_URL
http://localhost:3000
The address people open. Every link in an email is built from it. Build-time.
EDITION
none
community. Turns off plans, the staff ceiling, the demo and reporting to ThreadCount, and makes Turnstile optional.
DATABASE_URL
set by compose
The Postgres connection. Required outside compose.
Mail server. Mail is on only when this, SMTP_USER and SMTP_PASS are all set.
SMTP_PORT
587
465 connects with TLS from the start.
SMTP_USER
none
Mail server login
SMTP_PASS
none
Mail server password
SMTP_FROM
SMTP_USER
The From line
CONTACT_TO
none
Hosted only. Where the website's contact form is delivered.
Notifications
Variable
Default
What it does
TC_FCM_KEY_FILE
none
Path to a Firebase service-account key file, kept outside the checkout. With none, no notifications are sent and the staff app's Account screen says so. See notifications.
Switches and the server
Variable
Default
What it does
SIGNUPS_DISABLED
open
1 hides facility sign-up and refuses the sign-up endpoint.
APP_PORT
3000
The port on the server the app is published on. Compose reads it; the container always listens on 3000.
PHOTO_DIR
set by compose
Where signatures and photos are written. Back it up with the database.
TURNSTILE_SECRET
none
Cloudflare Turnstile on sign-in, sign-up and password reset. Enforced only when set.
NEXT_PUBLIC_TURNSTILE_SITEKEY
none
Turnstile's site key. Build-time. Set both or neither.
TURNSTILE_OPTIONAL
none
1 lets production run without Turnstile. For local tests; a Community instance does not need it.
DB_POOL_MAX
the driver's default
Local development only. 1 makes every database call wait for the one before. Never set it on a server.
Documents, errors, statistics and chat
These are all NEXT_PUBLIC_ variables, so as the first section explains, they have no effect on a Docker install today.
Variable
Default
What it does
NEXT_PUBLIC_TERMS_URL
none
Your terms page, linked from the staff sign-in and account screens. With none, no link shows.
NEXT_PUBLIC_PRIVACY_URL
none
Your privacy notice, linked the same way
NEXT_PUBLIC_GLITCHTIP_DSN
none
Your own GlitchTip or other Sentry-protocol address for error reports. With none, nothing is reported.
NEXT_PUBLIC_RELEASE
none
A label stamped on error reports; also shown as version at /api/app-info when there is no COMMUNITY_VERSION file
NEXT_PUBLIC_UMAMI_SRC
none
Your own Umami tracker script. With none, no statistics are sent.
NEXT_PUBLIC_UMAMI_SITE_ID
none
Umami site id
NEXT_PUBLIC_UMAMI_APP_ID
none
Umami id for the app
NEXT_PUBLIC_CHATWOOT_URL
none
Your own Chatwoot. With this and the token set, a chat widget shows in the coordinator app.
NEXT_PUBLIC_CHATWOOT_TOKEN
none
Chatwoot website token
Hosted only
Nothing in the Community edition reads these. Leave them blank.