# Install with Docker

Install GoRunner on one Linux server, with automatic HTTPS.

## You need

- **A Linux server with Docker**: 64-bit, amd64 or arm64, with at least 2 CPU cores, 4 GB of memory and 40 GB of free disk. Docker with Compose 2.20 or newer: check it with `docker compose version`.
- **A domain name**: Such as `automations.example.com`. You point it at the server in step 1.
- **Access to GoRunner’s images**: A GitHub account of yours that GoRunner has given access to the images. Ask at gorunner.io/contact, where you also get your license, [free](https://docs.gorunner.io/self-host/free-license) or paid.

## 1. Point your domain at the server

Add a DNS `A` record for the name, pointing at the server’s address, and an `AAAA` record if it has IPv6. Open TCP ports 80 and 443 to it, and UDP 443 for HTTP/3 if you can.

You should see the command prints the server’s address. A new record can take a few minutes to appear.

**Using a proxy or load balancer of your own?**

Then GoRunner needs no ports 80 and 443: in step 4, choose **My own proxy, load balancer or ingress**. Your proxy holds the certificate and passes every path to GoRunner on a local port.

[Behind your own proxy](https://docs.gorunner.io/self-host/own-proxy) has the nginx lines the setup prints.

```bash
dig +short automations.example.com
```

```text
203.0.113.24
```

## 2. Sign in to the registry

On GitHub, make a classic token for the account GoRunner gave access to: **Settings › Developer settings › Personal access tokens › Tokens (classic)**, with only `read:packages` and an expiry date.

Sign in once per server with that account’s user name, and paste the token when it asks for a password. When the token ends, or may have leaked, delete it and make a new one.

**Download from a registry of your own?**

Copy the images into your own registry once, and the token stays off your servers. Sign in to that registry instead, use its address in place of `ghcr.io/ralve-org` in step 3, and give it to the setup:

```bash
./setup.sh --registry registry.example.com/ralve-org
```

The setup records it, so updates download from it too.

```bash
docker login ghcr.io -u <user name>
```

```text
Login Succeeded
```

## 3. Download the install bundle

The image writes its install bundle into an empty folder: `docker-compose.yml`, `setup.sh`, `deploy.sh`, `.env.example`, `README.md` and `VERSION`. Its folders are `caddy/` (updates replace it; don’t edit), `certs/` for certificates to trust, and `observability/`, an optional [Grafana kit](https://docs.gorunner.io/self-host/monitoring-tools). Keep this folder. Every later command runs in it.

If it says “unauthorized”, Docker isn’t signed in, or the sign-in can’t read this version. Run `docker login ghcr.io` again and check the version exists.

```bash
mkdir gorunner && cd gorunner
docker run --rm \
  ghcr.io/ralve-org/gorunner-selfhost:v2026.10.30 \
  install | tar -x
```

## 4. Run the setup

Answer each question and press Enter. A value in [brackets] is the default.

| It asks | What to answer |
| --- | --- |
| This server’s role | `1`, all: everything on this server. The others are for [several servers](https://docs.gorunner.io/self-host/several-servers). |
| The way in | `1`, Automatic HTTPS, then your domain. Or [your own proxy](https://docs.gorunner.io/self-host/own-proxy). |
| The first administrator | Your email, or Enter to skip |
| Sending email | Resend, an SMTP server, or [no mail](https://docs.gorunner.io/self-host/sign-in-without-email) |
| The database, Redis, file storage | `1`, Built in, for each. Or [your own](https://docs.gorunner.io/self-host/own-stores). |
| A license | Paste it, or Enter to load it later |

Then press Enter at **Go ahead?**. The setup writes your answers to `.env`, readable by you alone, and makes every password itself without showing it. It checks everything GoRunner depends on, then starts it.

If your servers reach the internet only through a proxy, see [A company proxy](https://docs.gorunner.io/self-host/company-proxy).

```bash
./setup.sh
```

```text
GoRunner setup — v2026.10.30
A few questions; press Enter to take the value in [brackets].

1. This server’s role.
    1) all: the dashboard, the API and the workers, on this server
    2) api: the dashboard and the API; workers run on other servers
    3) worker: runs workflows for an api server elsewhere
    api and worker need your own database, Redis and storage (or no storage).
  Choose [1]:
```

## 5. Create the admin account

The setup ends with the address and a setup code. Open the address, enter the code, and create the admin account.

Then load your license on the page you land on. Nothing runs until it is loaded.

You should see GoRunner’s **Overview**, with its **Getting started** list.

```text
GoRunner v2026.10.30 is running at https://automations.example.com

  Setup code: K7QM-4RZP
  Open https://automations.example.com and enter it to create the admin account.
  Lost it? docker compose exec api gorunner setup-code

Next:
  1. Create the admin account there. We email you a link and a code.
  2. Load your licence: the page you land on asks for it. Nothing runs until it is loaded.
     No licence yet? Ask the GoRunner team for one, free or paid: https://gorunner.io/contact
  3. The Overview’s Getting started list takes it from there: your organization’s name, two-factor sign-in, your team.
```

**Testing on a laptop first?**

Use Caddy’s own certificate and a `.localhost` name, on ports no other program uses. For testing only.

```bash
./setup.sh --tls internal --domain gorunner.localhost \
  --https-port 127.0.0.1:8443 --http-port 127.0.0.1:8080
```

Then open `https://gorunner.localhost:8443`: a `.localhost` name needs no DNS. Browsers warn about the certificate, and [programs refuse it](https://docs.gorunner.io/self-host/troubleshooting#a-test-install-certificate) until you point them at it.

**What if the check finds a problem?**

Each line starts with ✓ fine,! a warning, or ✗ a problem, and the line under a problem says what to change. GoRunner doesn’t start until every problem is fixed.

```text
✗ Database: 4 GoRunner processes with DB_MAX_CONNS=50 may open 202 connections; the server allows 197.
  Set DB_MAX_CONNS=47 in .env (or raise max_connections).
✓ Redis: 7.4.11, never deletes keys, saved to disk, wake-ups and sessions only. Runs, Storage and Queue data are in Postgres (Redis keeps a copy for rollback)
✓ Storage: none: step data stays in the database
✓ Mail: none. People sign in with a password
✓ Settings: role all, ENCRYPTION_KEY opens the stored keys
✓ Workflow steps: private networks blocked

1 problem to fix (45 ms). GoRunner will not work until it is fixed.
```

Fix it and run `./setup.sh` again. Sure it’s fine? `./setup.sh --skip-check` goes past it, except for a problem that would put stored data at risk. [The preflight check](https://docs.gorunner.io/self-host/preflight-check) lists every exit status.

**Answer without questions?**

Every question has a flag, so a script can run the setup in one go. [Setup flags](https://docs.gorunner.io/self-host/settings#setup-flags) lists them all.

```bash
./setup.sh -y --role all \
  --domain automations.example.com --mail none \
  --postgres bundled --redis bundled --storage bundled
docker compose exec -T api gorunner setup-code
```

The last command prints only the setup code.

## Next

- [First sign-in](https://docs.gorunner.io/self-host/first-sign-in): The admin account, two-factor and your license · 5 min
- [Update](https://docs.gorunner.io/self-host/update): Move to a new version with no gap · 5 min
- [Back up and restore](https://docs.gorunner.io/self-host/backups): The database, the files and the key · 10 min

Source: https://docs.gorunner.io/self-host/install-docker
