Skip to content

Configuration

You configure Umpteenth in a YAML file, config.yml, and override single options with environment variables. Umpteenth reads both at start, so every change needs a restart.

docker-compose.yml mounts config.yml from its own directory into the container at /app/config.yml, where Umpteenth looks for it. Options you leave out or leave empty keep their defaults, so a short file is enough:

config.yml
app:
url: https://umpteenth.example.com
encryption_key: "<output of openssl rand -base64 32>"

For a commented starting point, copy config.example.yml from the repository, which holds these options and a sample of each provider type. Create the file before the first start, or Docker creates an empty directory named config.yml in its place, and Umpteenth stops with app.encryption_key (APP_ENCRYPTION_KEY) is required.

Restart Umpteenth after an edit to the file:

Terminal window
docker compose restart umpteenth

To keep the file somewhere else in the container, point CONFIG_FILE or the --config flag at it. An unknown option or an invalid value stops Umpteenth at start with an error that names it.

Each option has an environment variable named after its path, in upper case with underscores for dots and hyphens, so server.trust_proxy is SERVER_TRUST_PROXY and auth.providers.pocket-id.allowed_groups is AUTH_PROVIDERS_POCKET_ID_ALLOWED_GROUPS. A variable wins over config.yml. Set variables in the environment: block of the service:

docker-compose.yml
services:
umpteenth:
environment:
LOG_LEVEL: debug
AUTH_PROVIDERS_POCKET_ID_ALLOWED_GROUPS: admins,ops

Apply a change to environment: with docker compose up -d, which recreates the container. docker compose restart keeps the old environment. An empty variable counts as unset and keeps the value from the file. Lists take commas, as in admins,ops, and durations take a unit, such as 90m or 12h.

Docker Compose uses a .env file next to docker-compose.yml only to fill ${...} placeholders in the compose file, and passes none of it to Umpteenth. To pass its variables on, add env_file: .env to the service.

Append _FILE to any variable to read its value from a file, the way Docker secrets work:

docker-compose.yml
services:
umpteenth:
environment:
APP_ENCRYPTION_KEY_FILE: /run/secrets/encryption_key
secrets:
- encryption_key
secrets:
encryption_key:
file: ./encryption_key.txt

Umpteenth trims whitespace around the content, so a trailing newline does no harm.

Two options set defaults for fields you can also change under Settings → General:

Option Field
sandbox.image Default image on the Sandbox defaults card
runs.retention_days Retention on the Spend and retention card

A workspace follows the option until one of its admins saves the card that holds the field. From then on the workspace keeps its own value, and edits to the option leave it alone.

Each row shows the option’s path in config.yml above its environment variable.

Option Default Description
app.url
APP_URL
http://localhost:8080 The URL you open Umpteenth at, which sign-in redirect URIs and links in notifications start with. With an https:// URL, Umpteenth marks its cookies Secure, see Reverse proxy.
app.encryption_key
APP_ENCRYPTION_KEY
none, required At least 16 bytes, such as the output of openssl rand -base64 32. Encrypts secrets, provider API keys and MCP logins, and signs sessions. Under a different key, Umpteenth can’t decrypt what it stored and everyone has to sign in again, so keep a copy with your backups.
app.data_dir
APP_DATA_DIR
data, which is /app/data in the container Holds the SQLite database and stored files, unless database.connection_string or file_storage.path point elsewhere.

Passkeys are on unless you turn them off, and each sign-in provider has the options below its ID, which Sign-in shows how to set up. An option marked for one type stops Umpteenth at start on a provider of the other type.

Option Default Description
auth.passkeys.enabled
AUTH_PASSKEYS_ENABLED
true Offers Sign in with a passkey on the login page, and lets whoever opens an instance without users create its first account. false leaves sign-in to the providers.
auth.providers.<id>.type
AUTH_PROVIDERS_<ID>_TYPE
none, required oidc for an OpenID Connect identity provider, or github for GitHub accounts.
auth.providers.<id>.name
AUTH_PROVIDERS_<ID>_NAME
none, required The label of the provider’s button, which reads Sign in with and the name.
auth.providers.<id>.icon
AUTH_PROVIDERS_<ID>_ICON
empty An image for the button, as an http:// or https:// URL or a data:image/ URI.
auth.providers.<id>.primary
AUTH_PROVIDERS_<ID>_PRIMARY
false Gives the provider the large button at the top of the login page. At most one provider can be primary.
auth.providers.<id>.client_id
AUTH_PROVIDERS_<ID>_CLIENT_ID
none, required The client ID of the OpenID Connect client or the GitHub OAuth app.
auth.providers.<id>.client_secret
AUTH_PROVIDERS_<ID>_CLIENT_SECRET
empty, required for github The client secret. A public OpenID Connect client works without one.
auth.providers.<id>.issuer
AUTH_PROVIDERS_<ID>_ISSUER
none, required for oidc oidc only. The issuer URL of the identity provider, which has to work from inside the container.
auth.providers.<id>.groups_claim
AUTH_PROVIDERS_<ID>_GROUPS_CLAIM
groups oidc only. The top-level claim of the ID token that lists the user’s groups as strings, such as roles.
auth.providers.<id>.allowed_groups
AUTH_PROVIDERS_<ID>_ALLOWED_GROUPS
empty oidc only. Groups whose members may sign in, spelled as in the groups claim, case included. Empty admits everyone the identity provider lets through.
auth.providers.<id>.admin_groups
AUTH_PROVIDERS_<ID>_ADMIN_GROUPS
empty oidc only. Groups whose members are instance admins.
auth.providers.<id>.allowed_users
AUTH_PROVIDERS_<ID>_ALLOWED_USERS
empty github only. GitHub usernames that may sign in. A github provider needs this list, allowed_organizations or an admin list.
auth.providers.<id>.allowed_organizations
AUTH_PROVIDERS_<ID>_ALLOWED_ORGANIZATIONS
empty github only. GitHub organizations whose active members may sign in.
auth.providers.<id>.admin_users
AUTH_PROVIDERS_<ID>_ADMIN_USERS
empty github only. GitHub usernames of instance admins.
auth.providers.<id>.admin_organizations
AUTH_PROVIDERS_<ID>_ADMIN_ORGANIZATIONS
empty github only. GitHub organizations whose active members are instance admins.
Option Default Description
workspaces.enabled
WORKSPACES_ENABLED
false Lets people create workspaces, invite others and switch between them. Off, everyone who signs in shares one workspace, see Workspaces.
Option Default Description
mcp.oauth_provider
MCP_OAUTH_PROVIDER
empty The ID of an oidc provider under auth.providers that MCP clients such as Claude Desktop sign in through, next to API tokens. Empty, they connect with API tokens only, see Connect an agent.
Option Default Description
server.host
SERVER_HOST
0.0.0.0 The interface both listeners bind to. Keep the default in a container.
server.port
SERVER_PORT
8080 The UI, the API and job webhooks.
server.broker_port
SERVER_BROKER_PORT
8081 The broker, which the ump CLI inside sandboxes calls, and the egress proxy of their outbound connections. Keep it unpublished.
server.trust_proxy
SERVER_TRUST_PROXY
false Takes the client address for the login rate limit from X-Forwarded-For. Turn it on only behind a reverse proxy.
Option Default Description
log.level
LOG_LEVEL
info debug, info, warn or error. At debug Umpteenth logs every API request, at info the failed ones.
log.json
LOG_JSON
false JSON lines instead of text.
Option Default Description
database.connection_string
DATABASE_CONNECTION_STRING
<app.data_dir>/umpteenth.db A SQLite file path, or a Postgres URL starting with postgres:// or postgresql://, such as postgres://umpteenth:secret@db:5432/umpteenth?sslmode=disable.
Option Default Description
file_storage.backend
FILE_STORAGE_BACKEND
filesystem The store for artifacts, long tool outputs and image build logs: filesystem, s3, or database for a table in the database.
file_storage.path
FILE_STORAGE_PATH
<app.data_dir>/blobs The directory of the filesystem backend.
file_storage.s3.endpoint
FILE_STORAGE_S3_ENDPOINT
empty, meaning AWS S3 A host with a port, such as s3.example.com:9000, or a URL, such as http://s3:8333.
file_storage.s3.bucket
FILE_STORAGE_S3_BUCKET
empty The bucket, which Umpteenth creates at start if it’s missing.
file_storage.s3.region
FILE_STORAGE_S3_REGION
empty The region of the bucket.
file_storage.s3.access_key_id
FILE_STORAGE_S3_ACCESS_KEY_ID
empty The access key.
file_storage.s3.secret_access_key
FILE_STORAGE_S3_SECRET_ACCESS_KEY
empty The secret key.
file_storage.s3.use_ssl
FILE_STORAGE_S3_USE_SSL
true TLS for an endpoint given as a host. An endpoint given as a URL takes TLS from its scheme.
Option Default Description
sandbox.adapter
SANDBOX_ADAPTER
docker docker, kubernetes for sandboxes as pods (see Install on Kubernetes), or none for a replica that executes no runs.
sandbox.image
SANDBOX_IMAGE
ghcr.io/stonith404/umpteenth-sandbox:latest The workspace default of Default image. Umpteenth pulls it at start if the engine lacks it.
sandbox.ca_certificates
SANDBOX_CA_CERTIFICATES
empty A PEM file of CA certificates that sandboxes trust, see CA certificates.
sandbox.allow_unrestricted_network
SANDBOX_ALLOW_UNRESTRICTED_NETWORK
true Offers jobs the Unrestricted network, which bypasses the egress proxy and reaches everything the host can, see Security.
sandbox.docker.runtime
SANDBOX_DOCKER_RUNTIME
runc The runtime of sandbox containers, runsc for gVisor.
sandbox.docker.dns
SANDBOX_DOCKER_DNS
empty, 8.8.8.8 and 8.8.4.4 under gVisor The resolvers of Unrestricted network sandboxes in place of Docker’s embedded DNS, which gVisor can’t reach. Set it only together with runsc.
sandbox.registry.repository
SANDBOX_REGISTRY_REPOSITORY
empty A registry path without a scheme, such as ghcr.io/acme/umpteenth-jobs, where replicas share the images of jobs with a Dockerfile. With Docker, Umpteenth never deletes tags there, so give it a cleanup policy. The kubernetes adapter needs it to build images, and deletes old builds where the registry allows it.
sandbox.registry.username
SANDBOX_REGISTRY_USERNAME
empty The user for pushes and pulls.
sandbox.registry.password
SANDBOX_REGISTRY_PASSWORD
empty The password or token of that user.

Umpteenth connects to Docker through the standard Docker client variables such as DOCKER_HOST, and through the socket at /var/run/docker.sock without them.

The kubernetes adapter has options of its own under sandbox.kubernetes, which the Helm chart sets from its values.

Option Default Description
runs.max_concurrent
RUNS_MAX_CONCURRENT
3 Runs executing at once on this replica. More runs wait as queued.
runs.retention_days
RUNS_RETENTION_DAYS
90 The workspace default of Retention. Every night Umpteenth deletes the events and files of runs that finished longer ago than that, and keeps the run records.
Option Default Description
network.allow_private_targets
NETWORK_ALLOW_PRIVATE_TARGETS
true Lets Umpteenth itself call model providers, HTTP MCP servers and notification webhooks at private or local addresses. Sandboxes follow their job’s network setting instead, see Security.
network.blocked_targets
NETWORK_BLOCKED_TARGETS
empty IP addresses and CIDR ranges that neither Umpteenth’s own calls nor the egress proxy of sandboxes connect to, such as the host’s own public address. They stay blocked with network.allow_private_targets and Allow private network, see Security.
Option Default Description
models.catalog_refresh_interval
MODELS_CATALOG_REFRESH_INTERVAL
12h The interval at which Umpteenth downloads the models.dev catalog and syncs every provider’s model list, see Models and costs. 0 turns the refresh off, and any other value must be at least 5m.

Several replicas share the work through Postgres, and the Helm chart sets these options for you. Outside Kubernetes, run the replicas on Postgres with file_storage.backend set to s3 or database, behind a load balancer that checks /healthz. Give them the same config.yml, including app.encryption_key, and open the UDP port between them.

Option Default Description
ha.replica_id
HA_REPLICA_ID
the hostname A fixed name, different on each replica, which labels the sandboxes it creates.
ha.actors.host
HA_ACTORS_HOST
127.0.0.1 The address other replicas reach this replica at. With the default, a second replica refuses to start.
ha.actors.port
HA_ACTORS_PORT
7571 The UDP port of the connections between replicas.
ha.actors.bind_address
HA_ACTORS_BIND_ADDRESS
every interface on Postgres, unless ha.actors.host is a loopback address, and ha.actors.host otherwise The interface the connections between replicas listen on.

Behind a TLS-intercepting proxy, such as Zscaler, mount the proxy’s CA certificate into the container and point two variables at it:

docker-compose.yml
services:
umpteenth:
environment:
SSL_CERT_DIR: /etc/ssl/certs:/etc/umpteenth/ca
SANDBOX_CA_CERTIFICATES: /etc/umpteenth/ca/ca.crt
volumes:
- ./ca.crt:/etc/umpteenth/ca/ca.crt:ro

Umpteenth then trusts it for its own calls and adds it to the trust store of every sandbox, with SSL_CERT_FILE, REQUESTS_CA_BUNDLE and NODE_EXTRA_CA_CERTS set for tools that bring their own. With the Helm chart, put the certificate in caCertificates.pem instead, and the chart sets both variables and has image builds trust it too. The steps of a job’s Dockerfile run without it.