Firetower

Install the Firetower

One line on the server. It asks a handful of questions and brings the stack up.

Firetower is built server-first: the control plane runs on a Linux machine — a VPS, a cloud VM, a box in your office — and you connect to it from wherever you are, with the desktop client on your Mac or Windows machine, or the mobile app. Nothing below runs on your laptop.

#Before you start

  • A Linux server you can SSH into, as root or with sudo.
  • A domain you can add DNS records to, and an API token for whoever hosts its DNS.

#Install

▶Run this onthe server the Firetower will run on

sh
curl -fsSL https://usefiretower.com/install.sh | sh

It gets three things onto the machine, showing each line and asking before it runs: Docker with the Compose plugin, if there is none, using Docker's own installer; Node 20 or newer, which the CLI runs on; and the Firetower CLI. Then it hands over to firetower install, and nothing else is decided for you.

Note

Already have Docker and Node? npm i -g @firetower/cli and firetower install is the same thing without the first two steps.

The first question decides the rest, and there are two answers:

  How will people reach this Firetower?

◆  Select
│  ● Tailscale or another mesh VPN   recommended — free, and takes 5 min
│  ○ Advanced (type my own IP)       public, your LAN, or a VPN you run
└

Nothing is published to the internet. Your people reach the Firetower because they are on your tailnet, and nobody else can reach it at all.

Install it on the server first, so the CLI has an address to find:

sh
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

Turn off key expiry for the machine in the Tailscale admin console while you are there — a server that drops off the tailnet is a Firetower nobody can reach.

Then run firetower install and take the first answer. It finds the address itself:

  ✓ Mesh network detected      100.69.206.104 (tailscale0)

◆  Reach Firetower on 100.69.206.104?
│  ● Yes
└

◆  Domain
│  firetower.example.com
└

◆  Where should the certificate come from?
│  ● Let's Encrypt, through Cloudflare
└

◆  API token
│  ••••••••••••••••••••••••••••••••
└

Create these DNS records in Cloudflare:

  firetower.example.com     A   100.69.206.104
  *.firetower.example.com   A   100.69.206.104

◆  Done?
│  ● Yes, continue
└

Both records. The wildcard is not optional — previews are served on subdomains. They are public records pointing at a private address: they resolve for everybody and answer only for people on your tailnet.

#With a custom IP

For a LAN, a VPN of your own, or a public address. You type it, and Firetower does not check it:

  ◆  Select
│  ○ Tailscale or another mesh VPN
│  ● Advanced (type my own IP)
└

Firetower will be reached at the address you type, and will not
check it. We assume you know what you are doing.

◆  Which address will people reach this on?
│  34.79.12.180
└

From there it is the same questions — domain, certificate, token, records — with your address in the two records instead of a tailnet one.

This loses work

On an address the internet can reach, the login page is the only thing in front of the control plane — and previews have no login at all. It holds your git tokens, your agent credentials and your worker SSH keys. Use a mesh VPN unless you have a reason not to.

If the machine is reached at an address it does not hold — behind NAT, a floating IP, or a load balancer, which is every VM on Google Cloud, AWS and Azure — it asks a second time for the address to listen on, prefilled with 0.0.0.0.

#Either way

It checks the machine, writes the deployment, generates the secrets and brings the stack up. The first start builds Caddy with your DNS provider compiled in, which takes a few minutes and is cached afterwards.

  Firetower is running.

  https://firetower.example.com

  username  admin
  password  velvet-timber-harbor-332

That password is printed once. You are asked to replace it when you sign in, and then to delete ADMIN_INITIAL_PASSWORD from .env.

This loses work

The root key is the only unrecoverable thing here. Every stored credential is sealed with it, and the installer makes you acknowledge it for that reason. Back it up somewhere that is not your database backup.

#Next