Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 13 additions & 44 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,33 @@

## Install

Install should be from GH releases

Example: Install the published Linux x64 binary from GitHub Releases:
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/getalfredo/alfredo/main/scripts/install.sh)
```

If running as root, the binary gets placed in ~/alfredo
Else, it gets placed in ~/alfredoapp/alfredo
Alfredo installs on Ubuntu 24.04 x64. The full flow is in the [install and upgrade spec](./spec/install.md).

For local development without a VPS, see [Local VPS (containers)](./local-vps.md).

## First Run Workflow

The `./alfredo first-run`, is the first step to prepare/ensure the VPS is ready for installing Alfredo service.

### Step 1. Secure and prepare the VPS

Goal: reach a minimum security baseline before any Alfredo service, database, or secret is installed on the server.

This step should cover:
### Step 1. Secure the host

- Start from a fresh supported VPS image - Ubuntu 24.04
- Update the operating system and security packages.
- Pick an existing user (or create one) which: is a non-root admin user with `sudo` and Docker capabilities without having to sudo
- Ensure SSH key access is set for that user.
- Disable direct root login over SSH.
- Disable SSH password authentication after key-based access is confirmed.
- Enable a host firewall with only the required ports open.
- Install basic intrusion protection such as `fail2ban` or an equivalent provider-level control.
- Enable automatic security updates.
- Confirm time sync, hostname, and basic system logging are working.
Before you install anything, secure the host by hand. Use the Baseline in the [machine ops spec](./spec/machine-ops.md#check-catalog) as the checklist. The installer doesn't change your SSH or firewall configuration.

This step should explicitly happen before:
### Step 2. Install HQ

- creating the Alfredo admin account
- generating or copying application secrets
- installing the Alfredo service
- exposing Alfredo to a public domain
Run the installer in HQ mode with root privileges. The installer sets up HQ and the HQ Porter as services, with rootless Docker and Railpack.

Exit criteria for Step 1:
### Step 3. Create the first Admin

- the VPS is reachable only through approved access paths
- root SSH access is blocked
- password-based SSH access is blocked
- only required inbound ports are open
- the machine can receive security updates automatically
- we can log in with a non-root admin user and perform privileged actions safely
Run the `user:create` command that the installer prints, then open the HQ address that the installer prints.

### Step 4. Open the firewall

Only after this baseline is complete should we run:
To serve public hostnames, allow ports 80 and 443 with the `ufw` commands that the installer prints. After you set the **HQ hostname**, close HQ's own port.

```bash
./alfredo first-run
```
### Add a Porter

In HQ, select **Add Porter**, copy the install command, secure the new host, and run the command on it.

### Upgrade

To upgrade, run the same install command again, on the HQ host first and then on each Porter host.

## CLI commands

Expand Down
86 changes: 86 additions & 0 deletions docs/spec/install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Install and upgrade

Status: agreed in [Install & upgrade flow for HQ and Porter](https://github.com/getalfredo/alfredo/issues/17). The design is deliberately simple: one installer script, and upgrading means running the script again.

## The installer

One script, `install.sh`, installs both HQ and Porter. It has two modes:

- **HQ mode** installs HQ and the HQ Porter on the same host.
- **Porter mode** installs a Porter only.

The Admin runs the installer with root privileges, through `sudo` or as root. Everything that the installer sets up runs as a non-root service user afterward.

The installer supports Ubuntu 24.04 on x64. On any other host, it stops with a clear message and changes nothing. Development hosts run the binaries directly and don't use the installer.

The installer doesn't prompt. Its inputs are arguments.

## Before installing: secure the host

The Admin secures the host by hand before running the installer. The install guide lists the Baseline from the [machine ops spec](machine-ops.md) as the checklist. The installer doesn't check the Baseline and doesn't change the host's SSH or firewall configuration. After the install, the Porter's Machine checks show what's still open.

## What a Porter install sets up

Porter mode does the following, in one unattended run:

- Creates Porter's service user and data directory.
- Sets up rootless Docker with Compose under the service user, including the right to bind ports 80 and 443 and the client IP address setting that the [reverse proxy spec](reverse-proxy.md) needs. Docker's built-in BuildKit provides BuildKit.
- Installs Railpack.
- Adds the read-only sudoers file for Machine checks, as the [Porter spec](porter.md#privileges) describes.
- Installs the Porter binary, writes the HQ address and API key to Porter's configuration, and registers Porter as a systemd service that starts on boot.

Every Porter gets the build dependencies. A project's Porter is fixed at creation, so every Porter has to be able to build.

The installer never stops, turns off, or reconfigures a Docker daemon that it didn't set up. One installer flag selects rootful Docker instead. Without the flag, the installer always sets up rootless Docker, including next to an existing rootful daemon. The installer doesn't detect an existing daemon and doesn't ask.

When the installer finishes, it prints the `ufw` commands that allow ports 80 and 443. It doesn't run them.

## Installing HQ

HQ mode does the following:

1. Creates HQ's service user and a `0700` data directory, as the [security spec](security.md) requires. HQ and Porter run as different users.
2. Installs Git, which HQ needs to fetch project sources.
3. Installs the HQ binary and registers HQ as a systemd service that starts on boot.
4. Runs the Porter install on the same host and enrolls the HQ Porter. The installer has HQ create a dedicated API key and writes it to the HQ Porter's configuration. The Admin never sees this key.

The installer then prints the next steps:

- The command that creates the first Admin, `alfredo user:create`. Admin accounts come from the CLI, as the [users spec](users.md) states.
- HQ's address, `http://<ip>:<port>`. The Admin works there until they set the **HQ hostname**.
- The `ufw` commands for ports 80 and 443, and a reminder to close HQ's own port after the HQ hostname is set.

## Adding a Porter

1. The Admin creates an API key in HQ, or picks **Add Porter**, which creates one.
2. HQ shows one copyable install command with the HQ address and the API key filled in. HQ shows the command once, because it shows the key once.
3. The Admin secures the new host, then runs the command on it.
4. The Porter connects and appears in HQ's Porter list.

An Admin who reuses an existing key builds the same command by hand. The install guide documents the arguments.

## Upgrades

HQ and Porter are released together under one version number.

To upgrade, the Admin runs the same install command again. On a host that's already installed, the installer replaces the binary and restarts the service. It keeps the data directory, the configuration, the API key, and the Docker setup. Running Stacks keep running.

The order is HQ first, then the Porters:

1. The Admin runs the HQ install command on the HQ host. This upgrades HQ and the HQ Porter in the same run.
2. The Admin runs the Porter install command on each other Porter host. On an upgrade, the command needs no HQ address or API key.

HQ shows its own version and each Porter's version. A Porter whose version differs from HQ's is marked as behind, with the copyable upgrade command next to it. The [Porter spec](porter.md#removal-and-upgrades) defines what an incompatible version blocks.

HQ doesn't check for new releases. The Admin learns about a release from the project's release page.

## Not in v1

- Uninstalling through the installer.
- arm64 hosts and distributions other than Ubuntu 24.04.
- A built-in upgrade command, automatic upgrades, and an **Update available** notice.
- A Baseline check or any host hardening by the installer.

## Handoff boundaries

Implementation owns the service user names, file and directory locations, the systemd unit contents, the installer's argument names, how the installer downloads and verifies release binaries, how HQ mode creates the HQ Porter's key, and the version comparison rule. The [rootless Docker prototype script](https://github.com/getalfredo/alfredo/blob/research/docker-modes-test/docs/research/docker-modes-test/install-rootless-porter.sh) is the starting point for the Docker setup. Its [test report](https://github.com/getalfredo/alfredo/blob/research/docker-modes-test/docs/research/docker-modes-test.md) lists what it didn't cover: hosts with the `docker.io` package or the Docker snap, a real package upgrade, and a service user that already exists.
Loading