Spitfire

Version: 0.21.0This documentation is for Spitfire 0.21.0.

Installation, updates and backups

This page covers installing Spitfire on Docker, Kubernetes or Windows (Docker Desktop), creating the first admin, updating, rolling back, backing up and uninstalling. Installing runners in remote locations is a separate topic: Runners and locations.

What it is for

The installer (install.sh, on Windows install.ps1) does all of this with one command:

  • Downloads the release's installer bundle (install.sh, uninstall.sh, Compose/Kubernetes files; no source code) from spitfire.tr/download, checks its SHA-256 and unpacks it into ~/spitfire.
  • Pulls the image from Docker Hub: algebransoft/spitfire:<VERSION> (public, amd64 + arm64). Go and Node are not needed.
  • Starts Postgres, the controller (web UI + API) and the runners.
  • Generates the secrets (SPITFIRE_SECRET_KEY, SPITFIRE_JWT_SECRET, the setup code…) once and keeps them as they are on every later run.
  • Prints the UI address and the setup code for the first admin at the end.

Running the same command again is an update.

When to use it

  • At the first installation.
  • When a new release is out (the blue "Spitfire X is out" banner in the UI).
  • To change the controller's port, the number of runners or the proxy (run it again with the option).
  • When an update went wrong (--rollback).
  • When support asks for a support bundle and the UI does not open (--support-bundle).

Requirements

Installation Needs
Docker (Linux/macOS) Docker Engine (Linux) or Docker Desktop (macOS), the Docker Compose v2 plugin, curl. The installing user must reach the Docker daemon (on Linux: be in the docker group).
Kubernetes The above plus kubectl and an active context. Nodes pull the image from Docker Hub (internet access needed; otherwise --build --registry).
Windows Docker Desktop, Windows PowerShell 5.1 or PowerShell 7, tar.exe (ships with Windows 10 1803 and later).
Remote runner server Only Docker; on Linux without Docker a systemd service, on Windows without Docker a Windows service. See Runners.

When the installer finds something missing it stops with a HATA: (error) line followed by a Çözüm: (fix) line; read that first.

Installing with Docker

  1. Check that Docker runs: docker info must return without an error.

  2. Run the install command:

    bash
    curl -fsSL https://spitfire.tr/install.sh | bash -s -- docker

    This installs Postgres + controller + 2 runners on one machine. For another release write SPITFIRE_VERSION=0.5.3, for another folder SPITFIRE_DIR=/opt/spitfire (both before bash):

    bash
    curl -fsSL https://spitfire.tr/install.sh | SPITFIRE_DIR=/opt/spitfire bash -s -- docker
  3. The installation ends with the line Kurulum tamamlandı. Tarayıcıda açın: http://... ("Installation complete. Open in your browser"). Copy the Kurulum kodu: XXXX-XXXX-XXXX (setup code) line right below it.

  4. Open the address in your browser and continue with First sign-in and setup code.

Default ports: UI and API 8470, gRPC (TLS) for remote runners 8471. To change them:

bash
~/spitfire/install.sh docker --port 8480 --grpc-port 8481 --runners 4

Installing on Kubernetes

  1. Check that you are on the right cluster with kubectl config current-context.

  2. Run the install command:

    bash
    curl -fsSL https://spitfire.tr/install.sh | bash -s -- kubernetes

    The default namespace is spitfire, the context is the current one. Change them with --namespace NS and --context C.

  3. By default the UI opens on NodePort 30470 (change with --node-port N; --service-type LoadBalancer or ClusterIP are also possible). If this machine cannot open the UI through the NodePort, the installer starts a kubectl port-forward in the background (deploy/kubernetes/.port-forward.pid).

  4. Copy the setup code from the output and open the address.

Security settings of the Kubernetes installation: pods run as non-root with a read-only root filesystem, no capabilities and the RuntimeDefault seccomp profile. NetworkPolicies (where the CNI enforces them) let only the controller reach Postgres and only this installation's runners reach the plaintext runner port (8475). Stopping the controller stops active runs and stores their results first (up to 30 s; the pod gets 45 s).

Common Kubernetes options:

Option Meaning
--namespace NS, --context C Target (default spitfire, current-context)
--service-type T NodePort (default), LoadBalancer, ClusterIP
--node-port N UI NodePort (default 30470)
--storage-class SC, --storage-size S Postgres PVC (default: the cluster default, 5Gi)
--local-port N Local port for the port-forward fallback
--runners N Number of always-on runners
--on-demand-runners N Runners started as pods during a run (see Runners)
--build --registry REG Builds the image from source and pushes it to your registry
Note

An image built with --build is loaded directly into kind, minikube, k3d and Docker Desktop; other clusters need --build --registry REG. --build only works in the source tree; the bundle from spitfire.tr carries no source code.

Installing on Windows

  1. Start Docker Desktop.

  2. In PowerShell:

    powershell
    irm https://spitfire.tr/install.ps1 | iex

    This installs in docker mode; the bundle is unpacked into %USERPROFILE%\spitfire (change it with $env:SPITFIRE_DIR, pick a release with $env:SPITFIRE_VERSION).

  3. To pass options, call the script as a scriptblock:

    powershell
    & ([scriptblock]::Create((irm https://spitfire.tr/install.ps1))) docker -Port 8480 -GrpcPort 8481 -Runners 4

The install.ps1 options mean the same as those of install.sh: -Runners N, -Location NAME, -Version V, -Image IMAGE, -AdminEmail/-AdminPassword, -Port N, -GrpcPort N, -GrpcPublicAddr H:P, -NoBackup, -Rollback, -SupportBundle, -Yes, -Help.

To install only a runner on a Windows server without Docker, use the command on the Windows tab of the key dialog on the Runners page: Runners.

Installer options

~/spitfire/install.sh --help lists them all. The most used:

Option Meaning
--port 8480 --grpc-port 8481 Docker: UI and runner ports (default 8470/8471)
--runners N Number of local runners (default 2)
--location NAME Location of the local runners (default local; a-z 0-9 - _ .)
--grpc-public-addr HOST:PORT The address runners in other locations dial (shown in the UI's command; on Docker the LAN IP by default)
--version V Pull another release from Docker Hub
--image IMAGE Use a specific ready-made image
--admin-email E --admin-password P Create the first admin during installation (password at least 8 characters)
--no-backup Do not back up the database when updating
--rollback [DUMP] Roll the last update back
--support-bundle Installs nothing; prepares a support bundle (zip)
-y, --yes Do not ask for confirmation

First sign-in and setup code

On the first visit the UI shows the Create the first admin screen. It appears only once, while there are no users at all.

The Create the first admin screen: Setup code, Name, Email, Password and Confirm password fieldsThe Create the first admin screen: Setup code, Name, Email, Password and Confirm password fields

  1. Paste the XXXX-XXXX-XXXX code printed at the end of the installation into Setup code.
  2. Enter Name, Email and Password (at least 8 characters), and repeat it in Confirm password.
  3. Click Create admin and sign in.

The new account is the installation admin: installation settings such as the license, users, SSO and system events belong to this role only. The code stops working once the first admin exists.

Lost the code? (It stays valid until the first admin exists and is never regenerated.)

  • Docker: grep SPITFIRE_SETUP_CODE ~/spitfire/deploy/docker/.env

  • Kubernetes: kubectl -n spitfire get secret spitfire-secrets -o jsonpath='{.data.SPITFIRE_SETUP_CODE}' | base64 -d

  • The setup_code= line in the controller log:

    bash
    docker compose -p spitfire -f deploy/docker/docker-compose.yml logs controller | grep -i setup
    kubectl -n spitfire logs deploy/spitfire-controller | grep -i setup
  • Running the install command again shows it again (the code does not change).

To create the first admin during installation without the code: install.sh docker --admin-email admin@example.com --admin-password '...' (Windows: -AdminEmail/-AdminPassword).

Warning

Do not share the setup code with anyone but the person installing. Whoever uses it first becomes the installation's admin.

After signing in, the next step is usually the license: License.

Updating

How you notice a new release

Once a day the controller asks spitfire.tr whether there is a newer release (it sends only its own version). If there is, admins see the Spitfire X is out banner at the top of every page:

  • What's new and how to update opens the release notes and the update command for this installation (separately for Linux/macOS Docker, Windows PowerShell, Kubernetes and runner servers in other locations).
  • Hide for this release closes the banner for that release. A Security update banner (red) cannot be hidden; it shows again on every visit.

The Version and updates card on the License page shows the installed version, the installation type, the last check's result, the Outbound proxy and the Update command; Check now checks without waiting.

The Version and updates card on the License page: installed version, installation type, update check and the Check now buttonThe Version and updates card on the License page: installed version, installation type, update check and the Check now button

Updating step by step

  1. Make sure no run is in progress (the update restarts the controller).

  2. On the server the controller is installed on, run the same command as at installation:

    bash
    curl -fsSL https://spitfire.tr/install.sh | bash -s -- docker
    curl -fsSL https://spitfire.tr/install.sh | bash -s -- kubernetes --context C --namespace NS

    On Windows: irm https://spitfire.tr/install.ps1 | iex.

  3. The script unpacks the latest bundle into the same folder and pulls the image. Generated keys (deploy/docker/.env or the spitfire-secrets Secret) and data are kept.

  4. If the version changes, the database is first dumped to ~/spitfire/backups/*.dump (the newest 5 are kept; --no-backup skips it).

  5. Update the runners in other locations too: Runners → Updating runners. The Runners page marks runners on another release than the controller with a yellow older release tag.

Rolling back

If an update goes wrong:

bash
~/spitfire/install.sh docker --rollback          # Kubernetes: install.sh kubernetes --rollback

On Windows .\install.ps1 -Rollback. The script first dumps the current database, restores the newest dump under backups/ (or the file you give: --rollback backups/<file>.dump) and returns to the release that took that dump. Changes made after the dump are lost. Without a terminal it needs --yes.

Installing behind a proxy

Behind a corporate HTTPS proxy, run the install command with HTTPS_PROXY (and if needed HTTP_PROXY, NO_PROXY) set:

bash
export HTTPS_PROXY=http://proxy.example.com:3128
export NO_PROXY=.example.local
curl -fsSL https://spitfire.tr/install.sh | bash -s -- docker

The script passes these values on to the controller (Docker: deploy/docker/.env; Kubernetes: the spitfire-proxy Secret). The controller makes the update check, webhooks and SSO calls through this proxy. The installation's own names (localhost, postgres, controller…) are added to NO_PROXY automatically. Add the names of an SSO provider or webhook targets on your internal network to NO_PROXY yourself. If a later run gives no proxy, the earlier setting is kept.

On an installation without internet access, turn the update check off: SPITFIRE_UPDATE_CHECK=off on the controller, and follow the release notes on spitfire.tr/surum-notlari. If you use your own mirror, give it with SPITFIRE_UPDATE_FEED; the mirror must also carry releases.json.sig.

Backups and SPITFIRE_SECRET_KEY

Spitfire's data lives in Postgres; connection secrets are encrypted with SPITFIRE_SECRET_KEY. Back up both:

  1. Keys: on Docker the ~/spitfire/deploy/docker/.env file, on Kubernetes the spitfire-secrets Secret. Copy it to a safe place (such as a password vault).
  2. Database: updates take ~/spitfire/backups/*.dump automatically when the version changes; restore them with pg_restore. For regular backups, add this folder or the Postgres volume to your own backup system.
Warning

If SPITFIRE_SECRET_KEY is lost, stored connection secrets (database, Kafka… passwords) cannot be read; you have to enter them all again. The TLS identity the controller presents to runners is also stored encrypted with this key.

Ports and network

Port For Who must reach it
8470 (Docker; NodePort 30470 on Kubernetes) Web UI and REST API Users, CI pipelines
8471 gRPC endpoint remote runners connect to, TLS Runner servers in other locations (inbound TCP)
8475 Plaintext gRPC for runners on the same machine/cluster Only the installation's own runners; never published
8472 (optional) Mock services (turned on with SPITFIRE_MOCK_ADDR) The system under test

Runners connect out to the controller; no inbound port is needed on a runner server.

With a reverse proxy (ingress, nginx) in front of the UI, the client address is taken from X-Forwarded-For only when the request comes from loopback or a private network. Declare a proxy on a public address (a cloud load balancer, Cloudflare) in SPITFIRE_TRUSTED_PROXIES (comma-separated CIDRs); otherwise the audit log and the sign-in limits see the proxy's address.

Sign-in is throttled: one client address may try 30 times at once, then once every 2 s; an account accepts 10 wrong passwords, then one a minute. When many users sit behind one proxy/NAT, raise the first limit with SPITFIRE_SIGNIN_BURST.

TLS and runner pin basics

  • Port 8471 is always TLS. The controller creates its own identity on first start and stores it in the database (encrypted with SPITFIRE_SECRET_KEY).
  • A remote runner verifies the controller by the pin of that key (sha256:…). The pin and the ready-made install command are in the key dialog on the Runners page. The pin is required because connection secrets travel to runners over this channel.
  • To use your own certificate, give the controller SPITFIRE_GRPC_TLS_CERT and SPITFIRE_GRPC_TLS_KEY; runners then verify with --tls (system CAs) or --ca <PEM file> instead of a pin.
  • The controller address remote runners see is set at installation with --grpc-public-addr HOST:PORT or with SPITFIRE_GRPC_PUBLIC_ADDR.

Details: Runners → TLS pin and certificates.

Uninstalling

bash
~/spitfire/uninstall.sh docker
~/spitfire/uninstall.sh kubernetes --context C --namespace NS
~/spitfire/uninstall.sh runner          # remote runners installed with install.sh runner

Windows: .\uninstall.ps1 docker or .\uninstall.ps1 runner.

By default the data (Postgres volume / PVC) and the generated keys (.env / spitfire-secrets) are kept; a later install.sh brings everything back. To delete everything, add --purge (Windows: -Purge).

Warning

--purge deletes the database and SPITFIRE_SECRET_KEY; it cannot be undone. Take a backup first.

Common problems

Symptom: HATA: Docker daemon'una ulaşılamıyor. (the Docker daemon cannot be reached) Cause: Docker is not running, or your user is not in the docker group. Fix: Start Docker Desktop or sudo systemctl start docker; add your user to the docker group and log in again.

Symptom: HATA: Docker Compose bulunamadı. (Docker Compose not found) Cause: The Compose v2 plugin is not installed. Fix: Install the Docker Compose v2 plugin (https://docs.docker.com/compose/install/).

Symptom: HATA: Port 8470 başka bir uygulama tarafından kullanılıyor. (port in use) Cause: Another service on the machine uses that port. Fix: Pick another port: install.sh docker --port 8480 --grpc-port 8481.

Symptom: HATA: İmaj indirilemedi: algebransoft/spitfire:... (image could not be pulled) Cause: The machine cannot reach Docker Hub, or the version is wrong. Fix: Try internet access with docker pull; behind a proxy, configure the Docker daemon's proxy; check the version number.

Symptom: The setup screen says "Wrong setup code". Cause: The code was copied incompletely, or it belongs to another installation. Fix: Copy it again from the .env file or the controller log (First sign-in and setup code).

Symptom: The sign-in page opens instead of the setup screen, saying "Setup is already complete". Cause: The first admin already exists (perhaps through --admin-email). Fix: Sign in with that account. If its password is unknown, use spitfire-controller reset-password on the server: Users and access.

Symptom: HATA: Controller 180 sn içinde hazır olmadı. (the controller was not ready within 180 s) Cause: The controller failed while starting (database, missing setting…). Fix: Read the log with docker compose -p spitfire -f deploy/docker/docker-compose.yml logs -f controller; if you cannot solve it, prepare a support bundle with ./install.sh --support-bundle (Troubleshooting).

Symptom: The Version and updates card shows Check failed. Cause: The controller cannot reach spitfire.tr. Fix: Behind a proxy, run the install command again with HTTPS_PROXY set; without internet access set SPITFIRE_UPDATE_CHECK=off.

Symptom: After a reinstall, saved connections no longer work; secrets cannot be read or Test fails. Cause: SPITFIRE_SECRET_KEY changed (e.g. .env was deleted and the installation redone). Fix: Put back the .env you backed up and run the installer again; without a backup, enter the secrets again.