Configure the server
config.json— the primary and most flexible source.- Environment variables — every option has one, which is what you want in containers and Kubernetes.
- The online configurator — semaphoreui.com/install generates a starting file in the browser.
The naming rule is mechanical: a config key access_key_encryption is the environment variable SEMAPHORE_ACCESS_KEY_ENCRYPTION; a nested key ha.redis.addr is SEMAPHORE_HA_REDIS_ADDR.
Generate a configuration file#
The interactive setup writes a config.json, runs the database migrations and creates the first admin user:
semaphore setupFor a runner, the equivalent is:
semaphore runner setupA working example#
{
"dialect": "mysql",
"mysql": {
"host": "127.0.0.1:3306",
"user": "semaphore",
"pass": "***",
"name": "semaphore"
},
"git_client": "go_git",
"auth": {
"totp": {
"enabled": true,
"allow_recovery": true
}
},
"use_remote_runner": true,
"runner_registration_token": "73fs***",
"tmp_path": "/tmp/semaphore",
"cookie_hash": "96Nt***",
"cookie_encryption": "x0bs***",
"access_key_encryption": "j1ia***",
"max_tasks_per_template": 3,
"schedule": {
"timezone": "UTC"
},
"log": {
"events": {
"enabled": true,
"path": "./events.log"
}
},
"process": {
"chroot": "/opt/semaphore/sandbox"
}
}Start the server with it:
semaphore server --config ./config.jsonSettings worth getting right first#
| Setting | Environment variable | Why it matters |
|---|---|---|
access_key_encryption |
SEMAPHORE_ACCESS_KEY_ENCRYPTION |
Encrypts every credential in the Key Store. Generate with head -c32 /dev/urandom | base64. Lose it and you lose your secrets. |
cookie_hash, cookie_encryption |
SEMAPHORE_COOKIE_HASH, SEMAPHORE_COOKIE_ENCRYPTION |
Protect session cookies. Generated by semaphore setup. |
dialect + database block |
SEMAPHORE_DB_DIALECT, SEMAPHORE_DB_* |
sqlite, mysql or postgres. SQLite and BoltDB cannot be used for high availability. |
port, interface |
SEMAPHORE_PORT, SEMAPHORE_INTERFACE |
Where the web UI listens. Default :3000, all interfaces. |
web_host |
SEMAPHORE_WEB_ROOT |
The public URL of the instance. Set it whenever Semaphore sits behind a reverse proxy or issues OIDC redirects. |
tmp_path |
SEMAPHORE_TMP_PATH |
Where repositories are cloned and generated files land. Default /tmp/semaphore. |
git_client |
SEMAPHORE_GIT_CLIENT |
cmd_git (default) or go_git. |
max_tasks_per_template |
SEMAPHORE_MAX_TASKS_PER_TEMPLATE |
Task log retention per template. Unlimited by default — set it before your database grows unbounded. |
schedule.timezone |
SEMAPHORE_SCHEDULE_TIMEZONE |
Schedules run in UTC unless you say otherwise. Use an IANA name, e.g. America/New_York. |
use_remote_runner, runner_registration_token |
SEMAPHORE_USE_REMOTE_RUNNER, SEMAPHORE_RUNNER_REGISTRATION_TOKEN |
Required before any runner can register. |
subscription.key |
SEMAPHORE_SUBSCRIPTION_KEY |
Activates Pro or Enterprise without touching the UI. See License activation. |
The complete option table — several hundred keys — is maintained upstream at semaphoreui.com/docs/admin-guide/configuration.
Keeping secrets out of the environment#
Any sensitive option can be read from a file instead of an environment variable by appending _FILE to the variable name. This is the pattern to use with Docker secrets, Kubernetes secrets and systemd credentials:
SEMAPHORE_ADMIN_PASSWORD_FILE=/run/secrets/semaphore_admin_pw
SEMAPHORE_SUBSCRIPTION_KEY_FILE=/run/secrets/semaphore-license-keyWhen a value is supplied this way, Semaphore reads the file at startup — so rotating the secret needs a restart.
Application environment for your tools#
The configuration above is Semaphore's own. What Ansible, Terraform or your scripts see at runtime comes from Variable Groups, set per project rather than per server. See Inventory and variables.
Public URL behind a reverse proxy#
If Semaphore runs behind NGINX, Apache or Caddy, set the public URL explicitly so generated links and OIDC redirect URIs point at the proxy rather than at localhost:3000. The proxy itself must forward WebSocket upgrades on /api/ws, or live task logs will not stream — there is a working NGINX block in High availability.
Next steps#
- Security — TLS, isolation and hardening.
- Authentication — LDAP and OIDC single sign-on.
- Logs and metrics — audit logging, syslog, SIEM and Prometheus.