~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

deploy: knotless.dev's DNS is kept in the infra repository

Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:deploy/dns-to-infra
deploy/.gitignore+0−5
@@ -1,6 +1 @@
.terraform/
*.tfstate
*.tfstate.*
*.tfvars
!*.tfvars.example
local.env
deploy/.terraform.lock.hcldeleted+0−24
@@ -1,24 +0,0 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/cloudflare/cloudflare" {
version = "4.52.9"
constraints = "~> 4.0"
hashes = [
"h1:sIoAt5vaxgFBrst1Esfm7ixQQ/T7/JNPZu0m4bw+Bc4=",
"zh:0826cad9b57368f06466ec3e1f766086f44a373288753e144f681ddc0e61ab49",
"zh:15bf8d8abdcd202652466f3ef91110f143a7fad13c6173c7180e3dc0dbe9254b",
"zh:1a60d1d2e55a17942902b1ccc91e8f6cb150c035843d3eefc074f1291a0e7d5f",
"zh:23373a63fe06bbfa90c6c105c08429031719bedafa2458973cbdad32a384b5a7",
"zh:256a97b79cedee2575002f77ac3bf18888ce0fc97170ae8a357db406bb0a88e3",
"zh:3dd9f93c167cd59491ae77781032491d36a80843a1e44f9ee68b41b3f8e3ab8e",
"zh:5182d2d61930dd83584d8feb56102614f80ddeec532b939b58085ad74b796a6e",
"zh:5e3ca1888ba3b3bd8abd0f7dfcdd82fb5a8819affee899ed7fd891a33c17e0cb",
"zh:7a3ce2119e39fb3a90a6a459a26863851309dbc92e0735336cbc98692539cb4d",
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
"zh:c095dc680a646cc078c10bb0551e2ea8f08e7abdbcbc58cfd332c56b58788631",
"zh:d2400e010e069c19916c99136e200cf873eba6db2b18d3eb9541b38eb1f565fa",
"zh:dbc2f19f09aaefbd69334005bca2bcb0c9b690de1ed76f7ba97ce8e59a6e85df",
"zh:e685225f432da3e23b8717848de8c0ad0e22363450b2ac92cd24a56739ab5e9b",
]
}
deploy/main.tfdeleted+0−81
@@ -1,81 +0,0 @@
# The names knotless-serve answers at: the apex, and www, which the proxy
# redirects to it.
data "cloudflare_zone" "main" {
name = var.zone
}
# DNS-only, not proxied: the gateway is the zone's did:web, whose document
# and OAuth client metadata PDSes fetch from the origin, and git clones want
# bodies Cloudflare's proxy would cap. The reverse proxy on the host holds
# the certificate.
resource "cloudflare_record" "apex_a" {
zone_id = data.cloudflare_zone.main.id
name = "@"
type = "A"
content = var.host_ipv4
ttl = 1
proxied = false
comment = "knotless-serve"
}
resource "cloudflare_record" "apex_aaaa" {
count = var.host_ipv6 == "" ? 0 : 1
zone_id = data.cloudflare_zone.main.id
name = "@"
type = "AAAA"
content = var.host_ipv6
ttl = 1
proxied = false
comment = "knotless-serve"
}
resource "cloudflare_record" "www" {
zone_id = data.cloudflare_zone.main.id
name = "www"
type = "CNAME"
content = var.zone
ttl = 1
proxied = false
comment = "redirects to the apex"
}
# The handles of the service's own accounts under the zone, each a
# `_atproto.<name>` TXT record naming its DID: the runner hosts', the prod
# host's runner's (ci), the lexicon account's, the reviewer's, the triager's. A handle whose name also serves
# /.well-known/atproto-did answers there first; these answer any resolver
# that reads DNS. The `_lexicon` records are publish-lexicons.mjs's.
resource "cloudflare_record" "handle" {
for_each = var.handles
zone_id = data.cloudflare_zone.main.id
name = "_atproto.${each.key}"
type = "TXT"
content = "\"did=${each.value}\""
ttl = 300
proxied = false
comment = "atproto handle ${each.key}.${var.zone}"
}
# The runner host, apart from this one, where its bot logs in at
# /oauth/bot through its Caddy (deploy/runner-host).
resource "cloudflare_record" "runner_a" {
count = var.runner_ipv4 == "" ? 0 : 1
zone_id = data.cloudflare_zone.main.id
name = "runner"
type = "A"
content = var.runner_ipv4
ttl = 300
proxied = false
comment = "the knotless runner host: its bot login, through Caddy"
}
resource "cloudflare_record" "runner_aaaa" {
count = var.runner_ipv6 == "" ? 0 : 1
zone_id = data.cloudflare_zone.main.id
name = "runner"
type = "AAAA"
content = var.runner_ipv6
ttl = 300
proxied = false
comment = "the knotless runner host: its bot login, through Caddy"
}
deploy/outputs.tfdeleted+0−7
@@ -1,7 +0,0 @@
output "url" {
value = "https://${var.zone}"
}
output "gateway_did" {
value = "did:web:${var.zone}"
}
deploy/README.md+8−8
@@ -12,20 +12,20 @@ One Docker host, a reverse proxy in front of it for TLS, and a domain.
| `rollout-test.sh` | tries `rollout.sh` on a local docker behind a Caddy, counting failed requests |
| `release.sh` | builds the client for macOS and Linux here and puts the builds on the host, for `/install.sh` |
| `setup.sh` | makes a fresh Ubuntu 24.04 host ready for `deploy.sh`: docker, a Caddy of its own for the domain, a firewall, upgrades and pruning |
| `*.tf` | the domain's DNS records at Cloudflare: the host, the runner host, and the handles of the service's own accounts (`handles`) |
```sh
deploy/setup.sh root@host git.example.com # once, on a fresh host
just deploy root@host git.example.com # build on the host and restart; or put both in deploy/local.env
cd deploy && terraform apply # DNS, once (terraform.tfvars from the .example)
```
The Cloudflare token is allowed from one IPv4 address: where terraform
would reach Cloudflare over IPv6, run it through a proxy that dials IPv4
(`HTTPS_PROXY`). A worker that serves an account's handle at its own name,
as the reviewer's pds.js does at `review.knotless.dev`, holds that name as a
custom domain in its `wrangler.toml`, which makes the record: terraform
keeps only its `_atproto` TXT.
The domain needs an A (and AAAA) record for the host, and an `_atproto`
TXT record for each of the service's own accounts with a handle under it.
knotless.dev's are kept by the `stacks/edge` Terraform in the infra
repository, beside `stacks/knotless`, which makes the host. A worker that
serves an account's handle at its own name, as the reviewer's pds.js does
at `review.knotless.dev`, holds that name as a custom domain in its
`wrangler.toml`, which makes the record: the infra repository keeps only
its `_atproto` TXT.
### From a push to main to the site running it
deploy/terraform.tfvars.exampledeleted+0−14
@@ -1,14 +0,0 @@
cloudflare_api_token = "…" # Zone:DNS:Edit on the zone
zone = "example.com"
host_ipv4 = "203.0.113.10"
host_ipv6 = "2001:db8::10"
# Optional: the service's own accounts' handles, and the runner host.
handles = {
runner = "did:plc:…"
lexicons = "did:plc:…"
review = "did:plc:…"
ci = "did:plc:…"
}
runner_ipv4 = "203.0.113.20"
runner_ipv6 = "2001:db8::20"
deploy/variables.tfdeleted+0−39
@@ -1,39 +0,0 @@
variable "cloudflare_api_token" {
description = "A token with Zone:DNS:Edit on the zone."
type = string
sensitive = true
}
variable "zone" {
description = "The Cloudflare zone knotless-serve answers at the apex of."
type = string
}
variable "host_ipv4" {
description = "The host's IPv4 address, where the reverse proxy listens."
type = string
}
variable "host_ipv6" {
description = "The host's IPv6 address, or empty for none."
type = string
default = ""
}
variable "handles" {
description = "Accounts with a handle under the zone, by name: runner = \"did:plc:…\" gives runner.<zone>."
type = map(string)
default = {}
}
variable "runner_ipv4" {
description = "The runner host's IPv4 address, for runner.<zone>, or empty for none."
type = string
default = ""
}
variable "runner_ipv6" {
description = "The runner host's IPv6 address, or empty for none."
type = string
default = ""
}
deploy/versions.tfdeleted+0−14
@@ -1,14 +0,0 @@
terraform {
required_version = ">= 1.5"
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}