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/aws.md +102
| @@ -0,0 +1,102 @@ | |||
| 1 | # Vole on AWS | ||
| 2 | |||
| 3 | This creates one EC2 instance, a security group, a key pair, and an elastic | ||
| 4 | address, then turns the machine into a Vole instance on first boot. It takes | ||
| 5 | about three minutes. | ||
| 6 | |||
| 7 | ## What you need | ||
| 8 | |||
| 9 | - Credentials for an account that may create instances, security groups, and | ||
| 10 | elastic addresses. The usual AWS environment variables or profile are enough; | ||
| 11 | no permission is needed for anything outside the instance and its address | ||
| 12 | unless DNS is also managed here. | ||
| 13 | - A DNS name, such as `forge.example.com`. Either point it at the elastic address, | ||
| 14 | or let Terraform create the record if the name is in a Route 53 zone this | ||
| 15 | account holds. | ||
| 16 | - Your SSH public key, and the URL of a Vole `.deb` for `amd64`. | ||
| 17 | |||
| 18 | ## Deploy | ||
| 19 | |||
| 20 | From a clone of the Vole repository: | ||
| 21 | |||
| 22 | ```sh | ||
| 23 | export AWS_PROFILE=... # or AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY | ||
| 24 | cd deploy/terraform/aws | ||
| 25 | terraform init | ||
| 26 | |||
| 27 | terraform apply \ | ||
| 28 | -var region=eu-central-1 \ | ||
| 29 | -var domain=forge.example.com \ | ||
| 30 | -var "admin_ssh_public_key=$(cat ~/.ssh/id_ed25519.pub)" \ | ||
| 31 | -var vole_package_url=https://example.com/r/vole/releases/v0.2.0/artifacts/vole_0.2.0-1_amd64.deb | ||
| 32 | ``` | ||
| 33 | |||
| 34 | Type `yes` when it asks. Then point `forge.example.com` at the `public_ipv4` | ||
| 35 | output, or pass `-var create_dns=true -var dns_zone=example.com` to have Terraform | ||
| 36 | create the record in Route 53. | ||
| 37 | |||
| 38 | ## What you get | ||
| 39 | |||
| 40 | ```text | ||
| 41 | web_url = "https://forge.example.com" | ||
| 42 | git_remote = "ssh://git@forge.example.com:2222/" | ||
| 43 | public_ipv4 = "203.0.113.10" | ||
| 44 | admin_account = "admin" | ||
| 45 | server_login = "ssh -i <private-key> ubuntu@203.0.113.10" | ||
| 46 | ``` | ||
| 47 | |||
| 48 | Open `web_url` after DNS resolves. The account named by `admin_account` is an | ||
| 49 | instance admin and has no passkey yet; issue one from your laptop: | ||
| 50 | |||
| 51 | ```sh | ||
| 52 | vole admin --remote ssh://git@forge.example.com:2222 account invite admin | ||
| 53 | ``` | ||
| 54 | |||
| 55 | ## The settings worth changing | ||
| 56 | |||
| 57 | Everything else has a working default. Pass these with `-var` or in a | ||
| 58 | `terraform.tfvars` file beside `main.tf`. | ||
| 59 | |||
| 60 | | Setting | Default | What it does | | ||
| 61 | |---|---|---| | ||
| 62 | | `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. This is the one setting to change before you leave a public instance running | | ||
| 63 | | `instance_type` | `t3.medium` | 2 vCPU, 4 GB. `t3.large` doubles the memory if builds run on this machine | | ||
| 64 | | `disk_gb` | `40` | Root volume. Repositories, LFS objects, CI logs, and build artifacts live on it; grow it before it fills | | ||
| 65 | | `region` | `eu-central-1` | Any region with an Ubuntu 24.04 `amd64` image, which is all of them | | ||
| 66 | | `name` | `vole` | Name of the instance, key pair, and security group | | ||
| 67 | | `tls_mode` | `acme` | `proxy` leaves TLS to a proxy you run instead, and serves plain HTTP on loopback | | ||
| 68 | | `instance_name` | `Vole` | What the landing page calls this forge | | ||
| 69 | | `protect_instance` | `true` | Refuses termination through the API, so `terraform destroy` needs `-var protect_instance=false` | | ||
| 70 | |||
| 71 | `terraform apply` is safe to run again: it reports no changes. It does not upgrade | ||
| 72 | Vole, and it does not touch the machine's data. | ||
| 73 | |||
| 74 | The elastic address is not decoration. An EC2 public address changes when an | ||
| 75 | instance is stopped and started, and both the host name in `public_url` and the | ||
| 76 | SSH host key people's Git clients pin depend on the instance keeping its | ||
| 77 | address. | ||
| 78 | |||
| 79 | ## If something is not right | ||
| 80 | |||
| 81 | - **The browser shows a certificate warning.** DNS is not answering with the | ||
| 82 | elastic address yet, or ports 80 and 443 are not reachable. Check with | ||
| 83 | `dig +short forge.example.com`, then look at `journalctl -u vole | grep -i acme` | ||
| 84 | on the machine. | ||
| 85 | - **Ports 80 and 443 time out.** The default VPC's subnet needs a route to an | ||
| 86 | internet gateway. Terraform does not create a VPC; it uses the account's | ||
| 87 | default one. | ||
| 88 | - **The instance is up but the forge is not.** First-boot output is in | ||
| 89 | `/var/log/vole-first-boot.log`, and the service log is `journalctl -u vole` | ||
| 90 | through Systems Manager or the EC2 console. The usual cause is a package URL | ||
| 91 | that 404s or is for the other architecture. | ||
| 92 | - **`terraform apply` fails on credentials.** No profile or keys were found, or | ||
| 93 | the identity may not create instances. | ||
| 94 | - **Pushing is refused.** Port 2222 has to be reachable from where you push, and | ||
| 95 | the key has to belong to an account. `vole whoami --remote | ||
| 96 | ssh://git@forge.example.com:2222` says which account your key is. | ||
| 97 | |||
| 98 | ## Next | ||
| 99 | |||
| 100 | - [Deploying Vole](README.md) — backups, upgrades, and what first boot does | ||
| 101 | - [Packages](../packaging.md) — the `.deb`, the unit file, and upgrades on the machine | ||
| 102 | - [Accounts and access](../accounts-and-access.md) — the first accounts, roles, and passkeys | ||