1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# knotless-fork-infra
Our [knotless fork](https://knotless.dev/johnandersen777.bsky.social/knotless) (branch `runner-atlibs-composition`), deployed:
| | |
|---|---|
| https://knotless.socialweb.computer | knotless-serve + pages |
| https://knotless-runner.socialweb.computer | `knotless-run --executor composition`: CI on an [atlibs composition](REPORT.md) |
## Sign in
Log in → your handle → Log in.


Authorize on your PDS.


## Set up CI on a composition
**+** → name → Create repository.

Settings › Actions › Runners: `aliceoa.bsky.social` (new repositories here name it already).

Settings › Executor: `bobvmbuilder.bsky.social/socialweb-computer-cicd` → Look it up → bidders → Bind it.
Runner: `https://knotless-runner.socialweb.computer` → follow the sign-in link.
```json
["did:plc:4vcig7s43z3nyqrnepmcfzqt", "did:plc:7q5lnitxv4meizdon5fmhzrq"]
```


Authorize the composition at the runner: its own client, only its modules' scopes.


## Push
```sh
export KNOTLESS_APPVIEW=https://knotless.socialweb.computer
knotless login you.bsky.social
git init -q -b main kc-ci-demo && cd kc-ci-demo
echo 42 > answer.txt && git add . && git commit -q -m answer
git remote add origin knotless://you.bsky.social/kc-ci-demo
git push -u origin main
```

A workflow: each push to main rents a VM, runs the steps, releases it.
```sh
mkdir -p .knotless/workflows && cat > .knotless/workflows/ci.yml <<'EOF'
on:
push:
refs: [refs/heads/main]
steps:
- name: where
run: uname -a && id -un && pwd && git log --oneline -1
- name: test
run: test "$(cat answer.txt)" = 42 && echo "answer ok"
EOF
git add . && git commit -q -m ci && git push
```
Checks: rented, steps run, released.

## Deploy
Build on hat-8, ship to the socialweb.computer gateway, run as systemd-managed docker containers behind its Caddy.
```sh
git clone https://knotless.dev/johnandersen777.bsky.social/knotless-fork-infra && cd knotless-fork-infra
scripts/build.sh
scripts/deploy.sh
scripts/deploy.sh rollback # back to the image the last deploy replaced
```
| File | |
|---|---|
| `versions.env` | fork commit, base images by digest |
| `scripts/build.sh` | `knotless-fork:<commit>` on hat-8 |
| `Dockerfile` | the fork's image + `dumbpipe` and `ssh` (atlibs-iroh reaches a rented machine with them) |
| `scripts/deploy.sh` | `docker save \| docker load` to the gateway, units, Caddy (backup, validate, reload), restart |
| `host/systemd/` | serve `127.0.0.1:2590`, pages (network only), runner `127.0.0.1:8796` |
| `host/caddy/` | `/etc/caddy/sites/knotless*.caddy` |
| `host/knotless-fork.env` | `/etc/knotless-fork/knotless-fork.env`: domains, DIDs; no secrets |
Caps (4 vCPU / 8 GB host): serve 1.5 CPU 1.5 GB, pages 1 CPU 512 MB, runner 1 CPU 512 MB; `--cpu-shares 256` each, so the gateway wins contention.
Once, after the first deploy: the runner's account logs in at
`https://knotless.socialweb.computer/oauth/bot?account=aliceoa.bsky.social`.
State: `/var/lib/knotless-fork/{serve,runner}` on the gateway.
Unlicense.