vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Document deploying to a server, one guide per path
b8e7a5679847cf4cdda0754f6154805585e1be96 · Keenan Nemetz · 3d ago · parent b86148d1
Document deploying to a server, one guide per path The guides are for someone who has a machine and a domain and has not deployed a forge before, so they start from what to have ready and end at a working https address with one instance admin. Each ends with the same three things: where first-boot output is, what a certificate warning means, and that pushing needs port 2222 reachable and a key that belongs to an account. The index page carries what the per-cloud pages should not repeat: backups are separate from a cloud snapshot because secrets.key must not travel with the data, and upgrades are a package install rather than an apply.
docs/deploy/digitalocean.md +95
| @@ -0,0 +1,95 @@ | |||
| 1 | # Vole on DigitalOcean | ||
| 2 | |||
| 3 | This creates one droplet, a firewall, and an SSH key, then turns the machine into | ||
| 4 | a Vole instance on first boot. It takes about three minutes. | ||
| 5 | |||
| 6 | ## What you need | ||
| 7 | |||
| 8 | - A DigitalOcean API token with read and write access. Put it in | ||
| 9 | `DIGITALOCEAN_TOKEN`, or in `DIGITALOCEAN_TOKEN` in your Terraform | ||
| 10 | environment, which is the same thing. | ||
| 11 | - A DNS name, such as `forge.example.com`. Either point it at the droplet's | ||
| 12 | address, or let Terraform add the name to DigitalOcean's DNS and create the | ||
| 13 | record. | ||
| 14 | - Your SSH public key, and the URL of a Vole `.deb` for `amd64`. | ||
| 15 | |||
| 16 | ## Deploy | ||
| 17 | |||
| 18 | From a clone of the Vole repository: | ||
| 19 | |||
| 20 | ```sh | ||
| 21 | export DIGITALOCEAN_TOKEN=... # your API token | ||
| 22 | cd deploy/terraform/digitalocean | ||
| 23 | terraform init | ||
| 24 | |||
| 25 | terraform apply \ | ||
| 26 | -var domain=forge.example.com \ | ||
| 27 | -var "admin_ssh_public_key=$(cat ~/.ssh/id_ed25519.pub)" \ | ||
| 28 | -var vole_package_url=https://example.com/r/vole/releases/v0.2.0/artifacts/vole_0.2.0-1_amd64.deb | ||
| 29 | ``` | ||
| 30 | |||
| 31 | Type `yes` when it asks. Then point `forge.example.com` at the `public_ipv4` | ||
| 32 | output, or pass `-var create_dns=true -var dns_zone=example.com` to have Terraform | ||
| 33 | create the record in DigitalOcean's DNS. | ||
| 34 | |||
| 35 | ## What you get | ||
| 36 | |||
| 37 | ```text | ||
| 38 | web_url = "https://forge.example.com" | ||
| 39 | git_remote = "ssh://git@forge.example.com:2222/" | ||
| 40 | public_ipv4 = "203.0.113.10" | ||
| 41 | admin_account = "admin" | ||
| 42 | server_login = "ssh root@203.0.113.10" | ||
| 43 | ``` | ||
| 44 | |||
| 45 | Open `web_url` after DNS resolves. The account named by `admin_account` is an | ||
| 46 | instance admin and has no passkey yet; issue one from your laptop: | ||
| 47 | |||
| 48 | ```sh | ||
| 49 | vole admin --remote ssh://git@forge.example.com:2222 account invite admin | ||
| 50 | ``` | ||
| 51 | |||
| 52 | ## The settings worth changing | ||
| 53 | |||
| 54 | Everything else has a working default. Pass these with `-var` or in a | ||
| 55 | `terraform.tfvars` file beside `main.tf`. | ||
| 56 | |||
| 57 | | Setting | Default | What it does | | ||
| 58 | |---|---|---| | ||
| 59 | | `ssh_admin_cidrs` | everything | Addresses that may reach port 22 (server login) and 2222 (Git over SSH). Setting this to your team's range is the cheapest way to keep the write side private | | ||
| 60 | | `size` | `s-2vcpu-4gb` | 2 vCPU, 4 GB, 80 GB. `s-4vcpu-8gb` doubles all three if builds run on this machine | | ||
| 61 | | `region` | `nyc3` | `sfo3`, `ams3`, `fra1`, `blr1`, `syd1`, and others | | ||
| 62 | | `name` | `vole` | Name of the droplet, firewall, and SSH key | | ||
| 63 | | `enable_backups` | `true` | Weekly droplet backups, for about 20% of the droplet price | | ||
| 64 | | `tls_mode` | `acme` | `proxy` leaves TLS to a proxy you run instead, and serves plain HTTP on loopback | | ||
| 65 | | `instance_name` | `Vole` | What the landing page calls this forge | | ||
| 66 | |||
| 67 | The droplet reports CPU, memory, and disk to DigitalOcean's graphs, which is the | ||
| 68 | quickest way to see that a build filled the disk. | ||
| 69 | |||
| 70 | `terraform apply` is safe to run again: it reports no changes. It does not upgrade | ||
| 71 | Vole, and it does not touch the machine's data. | ||
| 72 | |||
| 73 | DigitalOcean has no delete protection on droplets, so `terraform destroy` does | ||
| 74 | what it says. The instance's repositories and accounts are on that droplet. | ||
| 75 | |||
| 76 | ## If something is not right | ||
| 77 | |||
| 78 | - **The browser shows a certificate warning.** DNS is not answering with the | ||
| 79 | droplet's address yet, or ports 80 and 443 are not reachable. Check with | ||
| 80 | `dig +short forge.example.com`, then look at `journalctl -u vole | grep -i acme` | ||
| 81 | on the machine. | ||
| 82 | - **The droplet is up but the forge is not.** First-boot output is in | ||
| 83 | `/var/log/vole-first-boot.log`, and the service log is `journalctl -u vole`. | ||
| 84 | The usual cause is a package URL that 404s or is for the other architecture. | ||
| 85 | - **`terraform apply` fails on credentials.** `DIGITALOCEAN_TOKEN` is unset or the | ||
| 86 | token is read-only. | ||
| 87 | - **Pushing is refused.** Port 2222 has to be reachable from where you push, and | ||
| 88 | the key has to belong to an account. `vole whoami --remote | ||
| 89 | ssh://git@forge.example.com:2222` says which account your key is. | ||
| 90 | |||
| 91 | ## Next | ||
| 92 | |||
| 93 | - [Deploying Vole](README.md) — backups, upgrades, and what first boot does | ||
| 94 | - [Packages](../packaging.md) — the `.deb`, the unit file, and upgrades on the machine | ||
| 95 | - [Accounts and access](../accounts-and-access.md) — the first accounts, roles, and passkeys | ||