# Initial VPS Setup Guide

Use this when bootstrapping a fresh Hetzner VPS or recovering after a server migration. For day-to-day operations (adding clients, reloading Caddy, using the editor), see [README.md](README.md).

If you ever need to migrate to a new Hetzner server, follow these steps to rebuild the environment from scratch.

## 1. Install Dependencies
```bash
# Update server packages
sudo apt update && sudo apt upgrade -y

# Install Git, Go, and curl (Go is required to build our custom Caddy)
sudo apt install -y git golang-go curl

# Install opencode (for the web editor)
curl -fsSL https://opencode.ai/install | bash
```

## 2. Install Custom Caddy (with caddy-exec)
Because we use Caddy to start and stop the web editor via webhook URLs, we need a custom build of Caddy with the `caddy-exec` plugin.

```bash
# Install xcaddy (the official Caddy build tool).
# `apt-key` is removed on modern Debian/Ubuntu, so we use a keyring file in
# /usr/share/keyrings/ instead. The .deb.txt that follows already includes a
# matching `signed-by=` clause, so no further wiring is needed.
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl gnupg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-xcaddy-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-xcaddy.list
sudo apt update
sudo apt install xcaddy

# Build Caddy with the exec plugin
xcaddy build --with github.com/abiosoft/caddy-exec

# Move the newly built binary to the system path
sudo mv caddy /usr/bin/caddy
sudo chmod +x /usr/bin/caddy
```

## 3. Clone This Repository
```bash
# Create the directory for the monorepo
sudo mkdir -p /srv/sites
sudo chown $USER:$USER /srv/sites

# Clone your git repository into the folder
git clone git@github.com:damosullivan/sites.git /srv/sites
```

## 4. Set the Editor Password
The `Caddyfile` you just cloned contains three placeholders: two `<HASHED_PASSWORD>` (in the `basic_auth` blocks for `/start` and `/stop`) and one `<OPENCODE_PASSWORD>` (in the `/start` exec line). They all represent the **same** password — the hash protects the Caddy webhooks, the plaintext is the basic auth for the opencode web UI itself.

```bash
# On the server, generate a hash
caddy hash-password --plaintext "your_password"

# Edit /srv/sites/Caddyfile:
#   - replace BOTH <HASHED_PASSWORD> with the hash output
#   - replace <OPENCODE_PASSWORD> with the plaintext (your_password)
sudo nano /srv/sites/Caddyfile

# Sanity check — neither placeholder should appear
grep -nE 'HASHED_PASSWORD|OPENCODE_PASSWORD' /srv/sites/Caddyfile
```

## 5. Configure systemd for Caddy
The upstream `caddy.service` expects a `caddy` system user to exist, but installing Caddy manually (as we did) does not create one — starting the service will fail with `status=217/USER`. For a single-user VPS the simplest fix is to override the user in the drop-in. The drop-in also sets the working directory (so relative paths in the Caddyfile resolve). The editor's basic auth password lives in the `Caddyfile` itself (see step 4), not in the drop-in.

```bash
# Download the official Caddy systemd service file
sudo curl -o /etc/systemd/system/caddy.service https://raw.githubusercontent.com/caddyserver/dist/master/init/caddy.service

# Create a drop-in override
sudo systemctl edit caddy
```
Paste the following, save, and exit:
```ini
[Service]
User=damien
Group=damien
WorkingDirectory=/srv/sites
ExecStart=
ExecStart=/usr/bin/caddy run --environ --config /srv/sites/Caddyfile
ExecReload=
ExecReload=/usr/bin/caddy reload --config /srv/sites/Caddyfile --force
```

> **Multi-user alternative:** if you'd rather run Caddy as the standard `caddy` user, create it before starting the service and chown the served paths to it:
> ```bash
> sudo useradd --system --home /var/lib/caddy --shell /usr/sbin/nologin caddy
> sudo chown -R caddy:damien /srv/sites
> sudo chmod -R g+rw /srv/sites
> ```
> Then drop the `User=` and `Group=` lines from the drop-in above.

Now enable and start Caddy:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now caddy
sudo systemctl status caddy --no-pager   # should show "active (running)"
```
