INSTALL

Running in one command.

Free, self-hosted, no signup. You will have a working control plane before you have decided whether you like it.

quickstart
cp .env.example .env && docker compose up -d

Three values to fill in first. The file tells you the commands to generate them.

PREREQUISITES

Docker + Compose v2

Docker Engine with the compose plugin. No source checkout, no Node, no toolchain.

4 GB RAM

For the control plane itself. Jobs run on your servers, not here, so it stays flat as the fleet grows.

A Linux host

Any distro. It needs outbound SSH to the machines you intend to manage, and nothing inbound but your browser.

INSTALL PATHS

Three ways through it.

Docker Compose
# 1 · fetch the two files — no account, no clone, no toolchain
mkdir talos && cd talos
curl -fsSL https://talosfleet.site/install-kit/docker-compose.yml -o docker-compose.yml
curl -fsSL https://talosfleet.site/install-kit/env.example -o .env
 
# 2 · configure — three values, the file tells you how to generate them
openssl rand -base64 24 # POSTGRES_PASSWORD
openssl rand -base64 32 # JWT_SECRET
openssl rand -base64 24 # ENCRYPTION_KEY
 
# 3 · start
docker compose up -d
 
✓ postgres healthy
✓ redis healthy
✓ backend [Mode] SELF_HOSTED (self-hosted)
✓ frontend listening
→ open http://localhost:3000 and create your account
·The images are public — no registry login and no access token to manage.
·The first account you create owns the install. Sign-up closes itself once that organization exists, so create yours before exposing the port.
·First start takes a minute or two: it applies the schema and loads the permission catalogue before the API accepts traffic.
·There is no API URL to configure. The browser talks to a relative /api and the frontend forwards to the backend inside the Docker network, so Talos works at whatever hostname you put in front of it.

YOUR FIRST FIVE MINUTES

From empty console to a streaming job.

01

Complete first-run setup

Open the frontend and create your administrator account and organization. Everything — servers, keys, jobs, audit — is scoped to that organization.

→ http://localhost:3000/setup
organization: acme-ops
✓ created · permission catalogue loaded
02

Add a server

Hostname, port, user. No agent to install — Talos connects over plain SSH.

host: 10.0.4.21 user: ops port: 22
→ testing reachability …
✓ reachable
03

Add an SSH key

Pasted once and encrypted at rest under your ENCRYPTION_KEY. It is decrypted in memory for the duration of a job and never written to a log line or a job payload.

key: talos_ed25519 (ed25519)
✓ encrypted at rest
✓ fingerprint SHA256:9tK…c1
04

Run discovery

Read-only inventory: OS, kernel, runtimes, running containers, database engines. It changes nothing on the host.

$ discover 10.0.4.21
→ ubuntu 24.04 · kernel 6.8.0
→ docker 27.3 · 6 containers
✓ discovery complete
05

Watch the first job stream

Every line arrives live. What you watch is exactly what lands in the audit ledger.

$ jobs follow 1
→ [00:00.2] connecting …
→ [00:03.1] gathering facts
✓ [00:08.4] job #1 succeeded

ENVIRONMENT VARIABLES

What you must set.

VARIABLEREQUIRED?WHAT IT DOES
POSTGRES_PASSWORDrequiredAny strong value. Used only inside the Docker network and never exposed.
JWT_SECRETrequiredSigns session tokens. The fallback is published in a public repository, so an install using it has forgeable logins.
ENCRYPTION_KEYrequiredEncrypts every stored credential. Cannot be changed once data exists — there is no recovery path.
FRONTEND_URLoptionalWhere users reach Talos in a browser. Used for links inside invitation and password-reset emails. Set it if you are not on localhost.
FRONTEND_PORT / BACKEND_PORToptionalHost ports, if 3000 and 3001 are already taken.
TALOS_VERSIONoptionalPin an image version instead of tracking latest. Recommended for production.
generate the three secrets
openssl rand -base64 24 # POSTGRES_PASSWORD
openssl rand -base64 32 # JWT_SECRET
openssl rand -base64 24 # ENCRYPTION_KEY
 
# Windows PowerShell, without openssl:
[Convert]::ToBase64String((1..32 | % { Get-Random -Max 256 }))

THIS IS DELIBERATE

Talos refuses to start with missing or default secrets. There is no fallback value and no warning-and-continue path. The check runs before anything opens a network connection, so a refused boot has written nothing. An instance holding your root SSH keys should never come up with a key an attacker can read out of a public repository.

BACK UP ENCRYPTION_KEY WITH YOUR DATABASE

It cannot be changed once data exists. Every SSH key, cloud credential and database password is encrypted with it, and there is no recovery path — a database backup without this key is unreadable.

UPGRADING

Pull, restart, done.

Migrations run automatically at startup and are idempotent, so an upgrade is safe to repeat and safe to interrupt. Take a database dump first anyway — and in production, pin TALOS_VERSION rather than tracking latest, or you upgrade whenever you happen to pull.

upgrade
docker compose exec postgres pg_dump -U talos talos > talos-$(date +%F).sql
docker compose pull && docker compose up -d
✓ migrations applied

TROUBLESHOOTING

When it does not come up.

The backend exits immediately with "Refusing to start".
JWT_SECRET or ENCRYPTION_KEY is missing, or still set to the published default. The check runs before anything opens a network connection, so nothing has been written yet — generate both with the openssl commands above and start again. This is deliberate: an instance holding root SSH keys should never come up with a signing key anyone can look up in a public repository.
I lost ENCRYPTION_KEY. Can I reset it?
No. Every SSH key, cloud credential and database password is encrypted with it and there is no recovery path — not for you and not for us. You would re-enter every credential by hand against a fresh install. This is the single thing on this page worth acting on before you have any data: back the key up somewhere separate from the database dump.
The UI loads but jobs never leave the queue.
The backend both produces and consumes the job queue in-process, so a stuck queue usually means it cannot reach Redis. Check REDIS_URL points at the compose service name rather than localhost — a stale localhost value makes the backend hang at boot, which shows up in a browser as a network error rather than an obvious failure.
Discovery fails with "permission denied (publickey)".
The private key in Talos does not match a public key in the target host’s authorized_keys, or the SSH user is wrong. Test the same key from your own shell first: ssh -i ~/.ssh/talos_ed25519 ops@host. If that fails, Talos will too.
Logs stream for a few seconds then stop.
Almost always a reverse proxy buffering the response. In nginx, set proxy_buffering off and a long proxy_read_timeout for the streaming path. The job itself is still running — only the stream died.

It's running. Now add your fleet.

Discovery is read-only, so the first server you connect cannot be broken by connecting it.

Read the security model