Configuring Progress Watch via environment variables

Everything is an environment variable. There are no config files to edit and no encrypted credentials baked into the image, so the same container runs on a home NAS and in the cloud.

General

VariableDefaultWhat it does
SECRET_KEY_BASEThe only variable that is required in production. Generate one with openssl rand -hex 64 and keep it.
DATABASE_URLsqlite3:storage/production.sqlite3Where spaces and task structure live. The default file is what the Docker volume holds; point it at postgresql://… for a cloud deployment. Progress itself is never written here.
FORCE_SSLfalseSet true when something in front terminates TLS. It also drives assume_ssl, so leaving it off keeps the app usable over plain HTTP instead of redirecting to a certificate you do not have.
PORT3000The port Puma binds inside the container. docker-compose.yml publishes it on 7979, because a service you leave running for weeks should not hold the port your own dev servers want.
RAILS_LOG_LEVELinfoLogs go to stdout and nowhere else. This is how much of them.
RATE_LIMIT_PER_HOURHow many spaces and tasks one address may create per hour. Unset means no limit, which is the right answer for a server only you can reach. Reporting progress is never limited.

Behind a proxy, RATE_LIMIT_PER_HOUR is only as good as the address the app sees. Rails reads X-Forwarded-For and trusts it from private ranges, which is what a reverse proxy on the same host sends — but if the header does not arrive, every request looks like one client and the limit locks out everybody at once rather than nobody.

Redis

Redis holds two unrelated things: the current progress of every task, and the Sidekiq queue. They are two logical databases of one server by default, and either can be moved to its own instance.

VariableDefaultWhat it does
REDIS_URLredis://localhost:6379The server used for both roles, split into db 0 for progress and db 1 for the queue.
PROGRESS_REDIS_URLREDIS_URL, db 0Overrides the progress store alone.
SIDEKIQ_REDIS_URLREDIS_URL, db 1Overrides the queue alone.
PROGRESS_TTL_SECONDS86400How long a task keeps its progress without being written to. Every report refreshes it, so this is really how long an abandoned task stays on screen.
PROGRESS_KEY_PREFIXpw:progressKey prefix for the progress store, so it can share a database with something else.

Notifications

Both keys unset means the feature does not exist: no button on a space, and nothing stored about anyone. There is nothing to register with Apple or Google — whoever made the browser runs the push service. Generate a pair once and do not rotate it; existing subscriptions are bound to it and browsers are not told.

VariableDefaultWhat it does
VAPID_PUBLIC_KEYPublic half of the pair that signs every push. Handed to the browser when it subscribes.
VAPID_PRIVATE_KEYPrivate half. Never leaves the server.
VAPID_SUBJECTmailto:hello@progress.watchA contact address the push services can reach if something goes wrong. Nobody verifies it.
PUSH_CONTENTfullfull puts the task title in the notification, minimal sends "Task completed" and nothing identifying.

Process sizing

VariableDefaultWhat it does
RAILS_MAX_THREADS5Puma threads per process, and the size of both the database and the Redis connection pool.
WEB_CONCURRENCY0Puma worker processes. Zero runs a single process, which is the right answer on a small box.
SIDEKIQ_CONCURRENCY5Threads in the Sidekiq process. Sending notifications is the only job there is.