Settings (.env)
Every setting GoRunner reads from .env, with its default.
This page is for self-hosted installations. On GoRunner Cloud, GoRunner runs this for you.
The setup writes the ones you need. Change the others only when a page tells you to.
To change your answers (role, address, mail, stores, license), run ./setup.sh again. For anything else, edit .env, then apply it with the version you run: ./deploy.sh "$(cat VERSION)".
PUBLIC_URL=https://automations.example.com
ENCRYPTION_KEY=… # made by the setup: keep a copy
GORUNNER_ROLE=allWrite .env by hand?
- Copy
.env.exampleto.envand runchmod 600 .env. - Set
PUBLIC_URL,ENCRYPTION_KEY(openssl rand -hex 32) andGORUNNER_ROLE, and the lines for your way in, mail and stores. - Set
COMPOSE_PROFILES: the role, each built-in store, andcaddyonly with automatic HTTPS, such asall,postgres,redis,storage,caddy. Give each built-in store its passwords (POSTGRES_PASSWORD,REDIS_PASSWORD,S3_ACCESS_KEY,S3_SECRET_KEY) withopenssl rand -hex 24. - Run
docker compose run --rm check, thendocker compose up -d, thendocker compose exec api gorunner setup-code.
| Name | Default | What it does |
|---|---|---|
| Required3 | ||
| Set by the setup | The full address people open, such as MoreThe links in emails and invitations are built from it. Set by the setup. | |
| Set by the setup | Opens every password, API key and connection GoRunner stores: 64 hexadecimal characters ( Danger Lose it, or change it, and nothing GoRunner stored can be read again. GoRunner refuses to start with any other key. Keep a copy of MoreThe setup makes it once and never shows or replaces it. GoRunner records a check value of it. Every server of one installation has the same one. | |
all |
More
| |
| Generated by the setup: keep safe, never change4 | ||
| Set by the setup | The built-in database's password. | |
| Set by the setup | The built-in queue's password. | |
| Set by the setup | The keys of the built-in object storage (S3). | |
| Set by the setup | The keys of the built-in object storage (S3). | |
| Your address and the way in10 | ||
| — | How people reach GoRunner. More
| |
| — | Only with your own proxy: where it reaches GoRunner, More
| |
| — | Who may tell GoRunner the caller's address. MoreWith automatic HTTPS, leave it unset: GoRunner then trusts Caddy alone. With your own proxy, the setup writes it: | |
| — | The name people open, such as MoreSet by the setup. | |
acme |
More
| |
| Off | on: every page tells browsers to use https for this address for a year (Strict-Transport-Security: max-age=31536000, this name only, not its subdomains). The setup writes on when it gets a certificate from Let’s Encrypt. | |
80 | The server ports Caddy listens on. MoreDefault | |
443 | The server ports Caddy listens on. MoreDefault | |
| — | Only when a proxy of yours stands in front of Caddy: that proxy's own address or range. MoreEmpty trusts no proxy. For a proxy on this server, with Caddy's ports on | |
| — | The private networks GoRunner keeps for Caddy, as three numbers such as MoreThe setup picks a range that nothing on this server uses. Change it only if you need that range for something else, then run | |
| Mail7 | ||
| — | A Resend API key. Used when set. | |
| — | Any SMTP server, used when there is no Resend key. MorePort | |
587 | Any SMTP server, used when there is no Resend key. MorePort | |
| — | Any SMTP server, used when there is no Resend key. MorePort | |
| — | Any SMTP server, used when there is no Resend key. MorePort | |
| — | How the connection is encrypted. More
| |
| — | The sender, such as MoreYour mail service must be allowed to send for its domain. | |
| Sign-in5 | ||
| — | Optional. Set it, and only this address can create the first admin account, even with the setup code. MoreIt does nothing once the installation has its admin. | |
| — |
| |
| — |
Warning Set to MoreLeave it unless you really want anyone who can reach the address to create an account. | |
| — |
MoreFor a deployment that writes the address later, from a secret store. | |
| — | Not set by default, which keeps it closed. Warning It opens the operator console at MoreYour own root secret for the operator console at | |
| License1 | ||
| — | Not needed: load the license in the dashboard instead, or paste it when the setup asks. | |
| Database10 | ||
| — |
More
| |
| — | Your own database, as separate fields. MorePort | |
| — | Your own database, as separate fields. MorePort | |
| — | Your own database, as separate fields. MorePort | |
| — | Your own database, as separate fields. MorePort | |
| — | Your own database, as separate fields. MorePort | |
| — |
MoreEmpty: | |
| — | The certificate authority to check the database's certificate with, as a file in | |
| — | Your own database as one address instead, such as MoreIt wins over the separate fields. | |
500 | The built-in database's connection limit. MoreThe setup writes | |
| Redis8 | ||
| — |
| |
| — | Your own Redis, as separate fields. MorePort | |
| — | Your own Redis, as separate fields. MorePort | |
| — | Your own Redis, as separate fields. MorePort | |
| — | Your own Redis, as separate fields. MorePort | |
| — | Your own Redis, as separate fields. MorePort | |
| — |
| |
| — | Your own Redis as one address instead, such as MoreIt wins over the separate fields. | |
| File storage10 | ||
| — |
More
| |
| — | Your bucket: the store's address (such as | |
gorunner | Your bucket: the store's address (such as | |
us-east-1 | Your bucket: the store's address (such as | |
| — |
| |
0 | Step data larger than this many KB goes to storage; smaller stays in the database. More
| |
15 | How long one storage call may take (15 seconds), and how often it is tried (4). | |
4 | How long one storage call may take (15 seconds), and how often it is tried (4). | |
| — |
| |
| — |
| |
| Workers and capacity13 | ||
1 | How many worker containers run on this server. MoreMore workers is the safer way to grow than one large one. | |
4 | How many runs one worker runs at once. | |
2 | How many Test step and connection tests from the editor one worker serves at once. More
| |
2 | How many Keel conversations one worker serves at once. More
| |
4 | How many notifications to your server one worker sends at once. More
| |
2g | The memory one worker may use. MoreRaise it together with | |
300s | How long a worker may finish its runs during an update before it is stopped. | |
1g | The memory each of the app's two copies may use. MoreThe app always runs as two copies on one address, so an update or a crash of one is never seen. | |
50 | The most database connections each GoRunner process keeps. The setup and the update size it from the check; empty means 50. | |
5 | How many database connections the check keeps free beside GoRunner's own, for MoreAt least 5. The pool size it recommends leaves them; one that uses them is a warning, never a refusal. On Kubernetes, | |
5 | The fewest each process keeps open. | |
| None | A soft memory goal for every GoRunner process, below the memory limits above, such as | |
UTC | The time zone of the processes' logs, and of the time a password lockout ends. MoreEach workflow's schedule has its own. | |
| Where workflow steps may connect1 | ||
| — | Empty (the default): no private address. More
| |
| Company proxy4 | ||
| — | The proxy for everything GoRunner calls outside, such as | |
| — | The proxy for everything GoRunner calls outside, such as | |
| — | Names reached directly, separated by commas. MoreGoRunner adds its own. | |
| — |
| |
| Data5 | ||
90 | Runs that finished longer ago than this are deleted every hour, with their data. MoreEach workflow keeps its newest finished run in each environment, however old. Runs still waiting or running are never deleted. | |
0 | Audit log rows older than this many days are deleted every hour. More
| |
0 | Credential use GoRunner itself recorded (a run, a schedule or a poll using a connection) older than this many days is deleted every hour. MoreEach connection keeps its latest use, and the rest of the log stays. Empty or | |
true |
| |
16 MB | The largest input or output one step may hold. | |
| Limits14 | ||
1200 | Requests a minute to the API for one caller: an API token, a signed-in session or an embed session, else one address. MoreEach app process counts on its own. One address may also send four times this, whatever token or session it uses. | |
3000 | Requests a minute from one address to webhooks, and to a connection sign-in’s launch and return pages. | |
120 | Requests a minute from one address to AI app sign-in: discovery, register, authorize and token. | |
3000 | Requests a minute for one embed API key, counted across every app process. | |
300 | Requests a minute for one embedded account, counted across every app process. | |
20 | Login codes a minute for one person of one embedded account, so one page reloading in a loop stops at that person. | |
4 | Renewals a minute for one embed session and the sessions renewed from it. | |
12 | How long the embed may keep renewing its own session after a login code, from 1 to 24 hours. MoreThen it asks your server for a new code. | |
| None | Other websites allowed to call the API from a browser, separated by commas. MoreThe embed has its own list. | |
10000 | How many runs of one organization may wait in line for a free slot. MorePast it, new ones are refused with 429 | |
1000 | How many runs of one workflow may wait in line, so one flooded webhook cannot fill its organization's room. MorePast it, that workflow's new runs are refused with 429 | |
600 | Requests a minute for one embed API key to the AI app sign-in requests (oauth-requests/*), counted across every app process, in their own window apart from EMBED_API_RATE_LIMIT. A Docker install passes it to the app from v2026.10.31; before, only the default applied. | |
256 | Memory one Code step or {{ }} expression may use, in MB (256; 64 to 16384). | |
256 | Request bodies and whole payload reads one API holds at once, in MB (0: no limit). MorePast it, a request waits 2 seconds, then answers | |
| Monitoring32 | ||
info | How much the log says: debug, info, warn or error. | |
text | text, or json for a log collector. | |
| Not set | Your OpenTelemetry tool's address and key: metrics, traces and logs. | |
| Not set | Your OpenTelemetry tool's address and key: metrics, traces and logs. | |
gorunner-api, gorunner-worker | The name GoRunner appears under in your tool. | |
| Every trace | Keep fewer traces on a busy installation. | |
| Every trace | Keep fewer traces on a busy installation. | |
| Off | A | |
| Off | A | |
| Not set | Crashes and errors to your Sentry project. | |
| Off |
| |
| Off | With automatic HTTPS, MoreNever a query string, a header, or more than the first 8 characters of a webhook's token. Docker Compose only: the Helm chart runs no Caddy. | |
| Not set |
More
| |
http/ | http/protobuf (default) or grpc. | |
| — | One signal elsewhere: a full address (used as given) and its own headers. | |
| — | One signal elsewhere: a full address (used as given) and its own headers. | |
| — | One signal elsewhere: a full address (used as given) and its own headers. | |
| — | One signal elsewhere: a full address (used as given) and its own headers. | |
| — | One signal elsewhere: a full address (used as given) and its own headers. | |
| — | One signal elsewhere: a full address (used as given) and its own headers. | |
otlp | none turns one signal off (default otlp). | |
otlp | none turns one signal off (default otlp). | |
otlp | none turns one signal off (default otlp). | |
| — | Extra resource attributes, key=value,key=value, such as team=platform. | |
60000 | How often metrics are pushed, in milliseconds. | |
false | true: OpenTelemetry never starts, whatever else is set. | |
false | Database and Redis calls as spans (they multiply trace volume), and a traceparent header on the HTTP calls steps make. | |
false | Database and Redis calls as spans (they multiply trace volume), and a traceparent header on the HTTP calls steps make. | |
:9464 | A /metrics page for Prometheus on every API and worker container (port 9464 on this network, not published). | |
false | Add workflow_id to the run and step metrics (one series per workflow: costly). | |
production | Crashes and errors (the server's, and the dashboard's relayed through it) to Sentry. | |
true | false: drop the dashboard's browser error reports instead of logging them. | |
| Connections4 | ||
| — | Not needed: set up the Google sign-in app under Platform › Settings › OAuth apps instead, which takes its place. | |
| — | Not needed: set up the Google sign-in app under Platform › Settings › OAuth apps instead, which takes its place. | |
| — | Off. Notification addresses and your own OAuth apps' token addresses must be https on the public internet. More
| |
| — | Empty. MoreLeave it empty unless the GoRunner team asks. | |
| Version and project7 | ||
| — | The installed version. More
| |
ghcr. | Where the images come from, such as MoreSet only when not the default, | |
| — | What runs on this server: the role, one name for each built-in store ( MoreThe setup and the update write it, so that | |
| — | Written by the setup and the update (the relay's tag by the update only) for two small containers that must never restart during an update: the one that holds the app's address open, and the one in front of the object storage. MoreEach keeps the version it was created with. | |
net. | The kernel setting of the container that holds the app’s address open. The update writes it. | |
| — | Written by the setup and the update (the relay's tag by the update only) for two small containers that must never restart during an update: the one that holds the app's address open, and the one in front of the object storage. MoreEach keeps the version it was created with. | |
| — | The prefix of the container and volume names. MoreSet only when not | |
| Other9 | ||
| — | off: a worker takes runs while it has slots, whatever its memory and sandbox say. | |
| — | The sandbox around Code steps and expressions. MoreEmpty: its seal is applied where the kernel allows it. | |
| — | 1: hand every script every earlier step, instead of only the ones it reads. | |
4096 | Synchronous callers (webhooks, forms, ?wait=) one API waits for at once, one organization's share of them (default an eighth), and the MB of their answers it builds at once. | |
512 | Synchronous callers (webhooks, forms, ?wait=) one API waits for at once, one organization's share of them (default an eighth), and the MB of their answers it builds at once. | |
128 | Synchronous callers (webhooks, forms, ?wait=) one API waits for at once, one organization's share of them (default an eighth), and the MB of their answers it builds at once. | |
0 | The client IP address on audit rows older than this many days is removed hourly; the rows stay. | |
on | AI apps that sign in with OAuth (ChatGPT, Claude, VS Code, Cursor…): their discovery documents, /oauth/register, /oauth/token and /oauth/revoke answer any website (CORS *, no cookies), so an app running in a browser can sign in. | |
| — | More app callbacks AI apps may register: whole URIs, comma-separated, no query, for an app whose callback GoRunner does not know (https, loopback, Cursor's and Raycast's need nothing here). | |
Setup flags
Every question of the setup is also a flag, so ./setup.sh can run without questions (-y). On an existing installation, only what you pass changes. Give a secret as - to read it from standard input, so it never shows in the server’s process list. ./setup.sh --help prints this list.
This server
| Flag | Writes | What it does |
|---|---|---|
--role all|api|worker | GORUNNER_ROLE | all: GoRunner on this one server (the default). Several servers: api on the main one (the dashboard and the API), worker on the others (they run the workflows). Several servers need your own database, Redis and storage (or --storage none) |
--encryption-key KEY | ENCRYPTION_KEY | the key every server of one installation shares (64 hex characters): required for role api and worker, the same on each (make it once: openssl rand -hex 32). Role all makes one. Never changed once .env has it. The installation records a check value of its key, and a server with any other key is refused by the check and does not start |
The way in
| Flag | Writes | What it does |
|---|---|---|
--domain NAME | GORUNNER_DOMAIN | automatic HTTPS: the address people will open, e.g. automations.example.com |
--behind-proxy URL | your own proxy: the https address it serves; GoRunner listens on --app-port for it | |
--public-url URL | PUBLIC_URL | a worker server: the address people open (the links in emails) |
--app-port [IP:]PORT | GORUNNER_APP_BIND | your own proxy: where it reaches GoRunner (127.0.0.1:8080). Use a private address the proxy can reach when it runs on another machine |
--trusted-proxies RANGES | the addresses your proxy connects from, as addresses or CIDRs. Your own proxy: with --app-port on 127.0.0.1 a proxy on this server is trusted already (the word gateway: Docker's published port delivers from there), so this adds only proxies in front of it; on another address it is required (your proxy's own address). Never private_ranges, which would trust every container on this server. With Caddy: the proxies in front of Caddy, if any. Written as APP_TRUSTED_PROXIES (your own proxy) or GORUNNER_TRUSTED_PROXIES (Caddy) | |
--tls acme|internal | GORUNNER_TLS | acme: a Let's Encrypt certificate (default) internal: Caddy's own CA — for testing on this machine only |
--http-port [IP:]PORT | PUBLIC_HTTP_PORT | Caddy's host port for HTTP (80) |
--https-port [IP:]PORT | PUBLIC_HTTPS_PORT | Caddy's host port for HTTPS (443) |
| Flag | Writes | What it does |
|---|---|---|
--mail resend|smtp|none | which one (--resend-key and --smtp-host imply it) | |
--resend-key KEY | RESEND_API_KEY | send mail through Resend… |
--smtp-host HOST | SMTP_HOST | …or through any SMTP server |
--smtp-port PORT | SMTP_PORT | 587 by default |
--smtp-secure MODE | SMTP_SECURE | starttls, tls (port 465) or none; by default tls on 465, else starttls |
--smtp-user USER | SMTP_USER | |
--smtp-password PASS | SMTP_PASSWORD | |
--mail-from ADDRESS | MAIL_FROM | the sender, on a domain your mail service may send for |
The stores
| Flag | Writes | What it does |
|---|---|---|
--postgres bundled|external | GORUNNER_POSTGRES | |
--database-url URL | DATABASE_URL | postgresql://user:password@host:5432/gorunner?sslmode=require |
--postgres-host HOST | POSTGRES_HOST | |
--postgres-port PORT | POSTGRES_PORT | 5432 |
--postgres-db NAME | POSTGRES_DB | gorunner |
--postgres-user USER | POSTGRES_USER | |
--postgres-password PASS | POSTGRES_PASSWORD | |
--postgres-sslmode MODE | POSTGRES_SSLMODE | disable, require (default), verify-ca or verify-full |
--postgres-ca-file / | POSTGRES_CA_FILE | a .pem file you put in ./certs, for verify-ca/-full |
--redis bundled|external | GORUNNER_REDIS | |
--redis-url URL | REDIS_URL | redis://user:password@host:6379/0 (rediss:// for TLS) |
--redis-host HOST | REDIS_HOST | |
--redis-port PORT | REDIS_PORT | 6379 |
--redis-db N | REDIS_DB | 0 |
--redis-user USER | REDIS_USER | |
--redis-password PASS | REDIS_PASSWORD | |
--redis-tls true|false | REDIS_TLS | |
--storage bundled|external|none | GORUNNER_STORAGE | none: every step's data stays in the database |
--s3-endpoint URL | S3_ENDPOINT | AWS: https://s3.<region>.amazonaws.com |
--s3-bucket NAME | S3_BUCKET | gorunner |
--s3-region REGION | S3_REGION | us-east-1 |
--s3-access-key KEY | S3_ACCESS_KEY | empty on AWS when the server has a role |
--s3-secret-key KEY | S3_SECRET_KEY | |
--s3-path-style true|false | S3_ | true for MinIO |
--confirm-store-change | move an existing installation between a built-in store and your own. The other one does not hold this installation's data: move the data first |
Also
| Flag | Writes | What it does |
|---|---|---|
--license-key KEY | LICENSE_KEY | a license you already have (or load it in the dashboard later) |
--admin-email ADDRESS | GORUNNER_ | only this address can be the first admin (optional) |
--https-proxy URL | HTTPS_PROXY | a company proxy for everything GoRunner calls outside (this shell’s own variables are not read). Extra certificates to trust go in ./certs as .pem files |
--http-proxy URL | HTTP_PROXY | a company proxy for everything GoRunner calls outside (this shell’s own variables are not read). Extra certificates to trust go in ./certs as .pem files |
--no-proxy LIST | NO_PROXY | a company proxy for everything GoRunner calls outside (this shell’s own variables are not read). Extra certificates to trust go in ./certs as .pem files |
--proxy-connect name|ip | EGRESS_ | what the proxy is asked to connect to for addresses workflows and partners chose: the site's name (default; proxies that allow sites by name need it) or the address GoRunner checked (no DNS rebinding at the proxy; such proxies refuse it) |
--registry PREFIX | GORUNNER_REGISTRY | where the images come from |
--project NAME | COMPOSE_ | compose project name (gorunner), for two installs on one server |
--skip-check | start even when the check finds a problem (only when you are sure); never when it finds a risk to data | |
--no-start | write .env and stop | |
-y, --non-interactive | never ask: take the answers from flags, the environment and .env |
Update flags
./deploy.sh takes these, and the same variables. The variables also work with a deploy.sh from v2026.10.0 to v2026.10.2, which doesn’t know the flags: GORUNNER_SKIP_CHECK=1 ./deploy.sh v2026.10.30. See Update.
| Flag | Same as | What it does |
|---|---|---|
--skip-check | GORUNNER_ | Goes on when the new version’s check finds problems. Never past a risk to stored data (exit 4). |
--confirm-store-change | GORUNNER_ | Says you changed the database, Redis or storage settings in .env on purpose. |
--replace-gate | GORUNNER_ | Moves the API’s gate to the new image too. The address closes for a few seconds, so pick a quiet moment. |