FrontierJS

Start · Basecamp

One command. A box, Basecamp on it, and https:// answering.

Type the hostname you want Basecamp on. You get the command to run, and a preview of everything it does: buys the box, installs Basecamp, writes the DNS record, waits for the certificate and makes your first admin.

~/frontierjs
$ fli basecamp:create --domain basecamp.example.com

No password box here. The run asks for it at your own terminal, or generates one when you press Enter.

Before you run it

not yet Where this is going

$ npm i -g @frontierjs/cli

That one install, then the command above, with no checkout. Today basecamp:create runs Basecamp from the framework's own source, so it needs a checkout beside fli. Basecamp is to ship as an image the box pulls by digest (FJS-D1526); until it does, this is the path:

  • A frontierjs checkout with Bun. The install runs from its packages/basecamp.
  • An SSH key at ~/.ssh/id_ed25519.pub (or id_rsa.pub, or --key).
  • DIGITALOCEAN_TOKEN — the box is billed to its account.
  • CLOUDFLARE_TOKEN — Zone › DNS › Edit, Zone › Config Rules › Edit, Zone › Zone Settings › Read.
git clone https://github.com/frontierjs/frontierjs && cd frontierjs
bun install
(cd packages/cli && bun link)      # fli on PATH, pointed at this tree

fli eset DIGITALOCEAN_TOKEN <token> --global
fli eset CLOUDFLARE_TOKEN <token> --global

Either token missing on a first run at a terminal: the run opens the page that makes it and takes the paste.

What happens when you run it

The run, start to finish, with your values in it. Questions answered with Enter take the default shown.

fli basecamp:create
$ fli basecamp:create --domain basecamp.example.com
fli basecamp:create a box at DigitalOcean for Basecamp
✓ example.com is at Cloudflare
? Server name Enter: basecamp
›
? Add Host basecamp to ~/.ssh/config once it has an address? [Y]es [n]o yes
? Install Basecamp on it once it is up? [N]o [y]es yes
? First admin's email required
› ‹your email›
? Make the box an Outpost too, so apps can run beside Basecamp on it? [Y]es [n]o yes
? Password for ‹your email› Enter generates one
›
hostname basecamp.example.com
server basecamp · DigitalOcean · 4gb
admin ‹your email› — password generated
? Buy the box at DigitalOcean? [Y]es [n]o yes
· Creating basecamp at DigitalOcean (4gb) — about a minute
ip 203.0.113.10 reserved
✓ Added Host basecamp to ~/.ssh/config — ssh basecamp
· Waiting for ssh on root@203.0.113.10 — a fresh box answers in about a minute
┆ fli deploy:setup docker and caddy on the box
┆ fli deploy build the image, ship it, start Basecamp
✓ Basecamp is on basecamp (203.0.113.10)
✓ basecamp.example.com → 203.0.113.10 in example.com, DNS-only
· Waiting for https://basecamp.example.com to answer on Caddy's certificate — up to three minutes
✓ https://basecamp.example.com answers on a valid certificate
? Put basecamp.example.com behind Cloudflare's proxy? The edge then verifies this certificate (Full (strict), this host only) [Y]es [n]o yes
✓ basecamp.example.com is behind Cloudflare's proxy, Full (strict) for this host
admin ‹your email›
password ‹generated› shown once — change it after you sign in
┆ fli deploy:outpost the box joins its own fleet
$
Lines lifted from packages/cli/commands/basecamp with your values put in, and trimmed — not a recorded run. The numbers in the margin are the steps beside it. ‹…› is what your cloud answers; ┆ is a child fli run, whose own output is folded.
  1. 1

    The zone, before anything else

    The hostname is checked against your Cloudflare token first. A token that opens no zone holding it refuses here — nothing asked, nothing bought. The zone is the longest one the token opens that the hostname ends with.

  2. 2

    Every question, then the bill

    Server name, the ssh Host, the Outpost, the password — all asked before the box is bought, so the minute it takes is one you can walk away from. The summary is the last stop before money is spent.

  3. 3

    The box

    A 4gb box at DigitalOcean carrying your SSH public key and nothing else, on a reserved IP that a replacement box keeps. Its Host block goes into ~/.ssh/config unless one of that name is already there.

  4. 4

    Ring 0, on your terminal

    Once ssh answers, fli deploy:setup puts docker and caddy on the box and fli deploy builds Basecamp, ships it and starts it. Each is a full fli run of its own — what it asks, it asks you.

  5. 5

    The record

    One A record, DNS-only, carrying Basecamp's fleet mark, so the Basecamp on the box manages it later. A record somebody made by hand at that name is refused, never overwritten.

  6. 6

    The certificate, then the proxy

    It waits for Caddy's certificate, then offers Cloudflare's proxy with Full (strict) for this host alone. The zone's own SSL mode is never changed — it covers every other host in the zone.

  7. 7

    The first admin, and the Outpost

    The first admin and its workspace are made on the box; a generated password is printed once. Then fli deploy:outpost enrolls the box in its own fleet, so apps can run beside Basecamp.

Afterwards

Sign in at your hostname with the admin it made, and change the password. A later deploy runs from packages/basecamp, with the line the run printed. Want the box without Basecamp yet? Answer no to the install — it prints the fli basecamp:install line that finishes the job later.