6.8 KiB
Configuration
RenewCMS reads its configuration from environment variables. On startup it also loads a .env file from the working directory (or its parent) if one exists. Real environment variables take precedence over .env.
Copy .env.example to .env to get started. When a required variable is missing, the server refuses to start and names the variable.
Variables
Required
| Name | Description | Example |
|---|---|---|
PUBLIC_URL |
Public base URL of the site, including scheme and no trailing slash. Used for links in emails and in the startup log. | https://cms.example.com |
JWT_SECRET |
Secret used to sign the auth JWT. Use a long random value; changing it logs everyone out. | openssl rand -hex 32 |
SMTP_LOGIN |
SMTP username used to authenticate with the server. Some providers (e.g. Brevo) issue a login distinct from the sender address. | noreply@example.com |
SMTP_SENDER |
Sender address used in the From header. Must be an address/domain the SMTP provider allows that login to send as. |
noreply@example.com |
SMTP_PASSWORD |
SMTP password. | |
SMTP_HOST |
SMTP server host. | smtp.example.com |
SMTP_PORT |
SMTP server port. | 465 |
Optional
| Name | Default | Description |
|---|---|---|
ENVIRONMENT |
production |
production or development. In production the auth cookie is Secure, so it is only sent over HTTPS. development turns on HTTP request logging. |
PORT |
8080 |
Port the HTTP server listens on (all interfaces). |
DB_FILE |
./data/renewcms.db |
Path to the SQLite database file. Missing parent directories are created. The schema is migrated automatically at startup. |
UPLOAD_DIR |
./data/uploads |
Directory where uploaded images are stored. |
CORS_ALLOWED_ORIGINS |
(empty) | Semicolon-separated list of origins allowed to call the API. When empty, no CORS headers are sent. That is the right setting whenever the SPA is served by RenewCMS itself (production) or through the Vite proxy (development). |
AUTH_RATE_LIMIT_MAX_ATTEMPTS |
5 |
Maximum number of requests a single client IP may send to POST /v1/auth/login, POST /v1/auth/password-reset or the invite-accept pair (GET /v1/auth/invite and POST /v1/auth/invite/accept, sharing one counter) within the window, tracked independently per route. |
AUTH_RATE_LIMIT_WINDOW_SECONDS |
60 |
Length, in seconds, of the fixed rate-limit window for the routes above. |
TRUSTED_PROXIES |
(empty) | Semicolon-separated list of exact IP addresses (no CIDR) of reverse proxies allowed to supply the client IP via X-Real-IP for the rate limiting of the routes above. When a request's connection address is not in this list, any X-Real-IP or X-Forwarded-For header it sends is ignored and the connection address is used instead. See deployment.md. |
RENEWCMS_CONTAINER |
false |
Set to true (case-insensitive; any other value means false) when the app runs in a container. Settings then tells the owner to update by pulling a new image instead of offering browser updates, and can_apply is always false. The Dockerfile and docker-compose.yml set it to true. Update checks still work. |
UPDATE_FEED_URL |
https://git.floriansylvain.fr |
Base URL of the Gitea server that publishes RenewCMS releases. The Settings page asks {UPDATE_FEED_URL}/api/v1/repos/fsylvain/RenewCMS/releases when the owner checks for updates. The last result is kept in update-status.json, next to DB_FILE. |
Automatic media purge has no environment variable. Its schedule (on or off, interval, enabled_at, last_purge_at) lives in the purge settings row of the database, is changed from the Settings page or PATCH /v1/media/purge-settings, and is read again at every hourly tick.
Relative paths are resolved against the process's working directory. In production, use absolute paths (see deployment.md).
For example, WorkingDirectory=/var/lib/renewcms with DB_FILE=./data/renewcms.db puts the database in /var/lib/renewcms/data. Browser-update --data-dir must name that directory, because the app reads helper status and update records beside the database. It is not necessarily WorkingDirectory or ReadWritePaths. Do not change an existing DB_FILE merely to match the helper: that could open a different, empty database. See browser-update setup.
Adding a variable
- Read it in the code where it is needed (infrastructure or
api/, neverinternal/domain). - Register it in
cmd/server/main.go: add it torequiredEnvVarsif it is required, or toenvDefaultsif it has a default. - Add it to
.env.exampleand to the tables above.
Never hardcode a secret, and never commit .env.