oCMS reads environment variables and a site-specific .env file. Start with the file created by ocms init my-site, keep its generated keys, and change only the settings your installation needs. This guide covers a prebuilt installation; the deployment guide adds the service and HTTPS proxy.
1. Finish the first local run
Follow the platform quick start, then open localhost:8080/admin/. On a freshly seeded site, the bootstrap login is admin@example.com with password changeme1234. Change both immediately in the account settings while the installation is still private. Remove sample accounts you do not need.
Stop the foreground process with Ctrl+C. Edit my-site/.env and set OCMS_DO_SEED=false for subsequent starts. Keep the existing OCMS_SESSION_SECRET and OCMS_MFA_KEY. Restart from the site directory:
cd my-site
../ocms serve
The Download quick start runs in a subshell: after stopping it, your terminal returns to the directory where you started the download commands. Adjust cd my-site to the directory you actually created. Continue with the editor's guide to prepare content.
2. Know which configuration wins
- Process environment: variables exported in your shell, container or service take precedence over values in the file.
- Selected file: oCMS normally reads
./.envfrom its working directory. SetOCMS_ENV_FILEto select a different file. A selected file that is missing, unreadable or invalid prevents startup. - Defaults and saved settings: unspecified settings use application defaults or saved site settings where supported.
Paths in the file are relative to the process's working directory, not automatically to the file's directory. Use absolute paths when the service's working directory differs from your interactive terminal.
For example, run from the site directory while selecting its file explicitly:
cd /srv/ocms/my-site
OCMS_ENV_FILE=/srv/ocms/my-site/.env /opt/ocms/ocms serve
Changing .env takes effect after restarting the process. If a value appears to be ignored, check the service definition and exported shell variables before editing the file again. Do not print or share the complete process environment; it can contain credentials.
3. Adjust local settings without replacing keys
This is a partial example to merge into the generated file, not a replacement .env. It binds a development site to IPv4 loopback:
# Keep the generated OCMS_SESSION_SECRET and OCMS_MFA_KEY above.
OCMS_ENV=development
OCMS_SERVER_HOST=127.0.0.1
OCMS_SERVER_PORT=8080
OCMS_SITE_URL=http://localhost:8080
OCMS_DO_SEED=false
OCMS_DB_PATH=./data/ocms.db
OCMS_UPLOADS_DIR=./uploads
OCMS_CUSTOM_DIR=./custom
OCMS_LOG_LEVEL=info
OCMS_SITE_URL is the public origin used for absolute site links. Use a scheme and host, with a port when needed; do not append a page path, query, credentials or fragment. When changing the listener to port 8081, change the local site URL to http://localhost:8081 too.
OCMS_ENV=development is for local work. It is not a way to resolve a production startup error.
4. Keep data and theme paths clear
OCMS_DB_PATH- The SQLite database file. The application user needs write access to both the file and its containing directory so SQLite can create WAL and shared-memory files.
OCMS_UPLOADS_DIR- Uploaded media and generated image variants. Include this directory in the site's backups.
OCMS_CUSTOM_DIR- Custom theme files. Custom Go modules must already be compiled into the binary; placing module source here does not load it.
OCMS_ACTIVE_THEME- An explicit value overrides the saved admin selection at startup. Remove the override from both the file and the process environment if you want Admin → Themes to control the theme across restarts. See the theme gallery.
Run separate sites with separate database paths, upload directories, configuration files and listening ports. Avoid pointing a test installation at the production files.
5. Prepare production deliberately
Keep the generated secrets stable. The session secret must be at least 32 bytes; the MFA key must also be at least 32 bytes and different from it. For an older installation missing a key, generate the missing value with openssl rand -base64 32 and save it privately. Do not regenerate an existing MFA key: enrolled authenticator secrets depend on it.
For the same-host reverse proxy in the deployment guide, merge these settings into the existing file, replacing the domain:
OCMS_ENV=production
OCMS_DO_SEED=false
OCMS_SITE_URL=https://cms.example.com
OCMS_SERVER_HOST=127.0.0.1
OCMS_SERVER_PORT=8080
OCMS_TRUSTED_PROXIES=127.0.0.1/32
OCMS_API_ALLOWED_CIDRS=127.0.0.1/32
OCMS_REQUIRE_MFA=true
This example permits protected API-key requests from loopback only. Add the actual automation-client CIDRs when needed; do not use a catch-all range to silence a startup check. The API cookbook covers key scopes and source restrictions.
These lines alone are not a complete production setup. Before changing environments, replace bootstrap credentials, deactivate the Developer module and unused import/integration modules, and configure hCaptcha for active public forms. Active webhooks, Embed or Migrator may require additional allowlists and secrets. Follow the production preparation checklist and keep the production safeguards enabled.
Restrict access to the file, for example chmod 600 .env when it is owned by the service user. Back up the original keys with the database using the backup walkthrough. Use account security for enrollment and recovery.
6. Verify a change
- Keep a private copy of the working configuration before editing.
- Restart the correct site from its normal working directory and read the first startup error. A missing file, invalid key or integration-policy failure needs correcting before another restart.
- Check
/health, a known page, an uploaded image and the active theme. - Check generated links use the intended public domain and HTTPS, then sign in and complete MFA where required.
curl --fail --silent --show-error http://127.0.0.1:8080/health
Use the configuration reference (GitHub Wiki) for less common settings. For a version change, follow the upgrade walkthrough rather than replacing the site's configuration with a fresh example.