forked from
tangled.org/core
Monorepo for Tangled — https://tangled.org
1# knot self-hosting guide
2
3So you want to run your own knot server? Great! Here are a few prerequisites:
4
51. A server of some kind (a VPS, a Raspberry Pi, etc.). Preferably running a Linux distribution of some kind.
62. A (sub)domain name. People generally use `knot.example.com`.
73. A valid SSL certificate for your domain.
8
9There's a couple of ways to get started:
10* NixOS: refer to
11[flake.nix](https://tangled.sh/@tangled.sh/core/blob/master/flake.nix)
12* Docker: Documented at
13[@tangled.sh/knot-docker](https://tangled.sh/@tangled.sh/knot-docker)
14(community maintained: support is not guaranteed!)
15* Manual: Documented below.
16
17## manual setup
18
19First, clone this repository:
20
21```
22git clone https://tangled.org/@tangled.org/core
23```
24
25Then, build the `knot` CLI. This is the knot administration and operation tool.
26For the purpose of this guide, we're only concerned with these subcommands:
27
28* `knot server`: the main knot server process, typically run as a
29supervised service
30* `knot guard`: handles role-based access control for git over SSH
31(you'll never have to run this yourself)
32* `knot keys`: fetches SSH keys associated with your knot; we'll use
33this to generate the SSH `AuthorizedKeysCommand`
34
35```
36cd core
37export CGO_ENABLED=1
38go build -o knot ./cmd/knot
39```
40
41Next, move the `knot` binary to a location owned by `root` --
42`/usr/local/bin/` is a good choice. Make sure the binary itself is also owned by `root`:
43
44```
45sudo mv knot /usr/local/bin/knot
46sudo chown root:root /usr/local/bin/knot
47```
48
49This is necessary because SSH `AuthorizedKeysCommand` requires [really
50specific permissions](https://stackoverflow.com/a/27638306). The
51`AuthorizedKeysCommand` specifies a command that is run by `sshd` to
52retrieve a user's public SSH keys dynamically for authentication. Let's
53set that up.
54
55```
56sudo tee /etc/ssh/sshd_config.d/authorized_keys_command.conf <<EOF
57Match User git
58 AuthorizedKeysCommand /usr/local/bin/knot keys -o authorized-keys
59 AuthorizedKeysCommandUser nobody
60EOF
61```
62
63Then, reload `sshd`:
64
65```
66sudo systemctl reload ssh
67```
68
69Next, create the `git` user. We'll use the `git` user's home directory
70to store repositories:
71
72```
73sudo adduser git
74```
75
76Create `/home/git/.knot.env` with the following, updating the values as
77necessary. The `KNOT_SERVER_OWNER` should be set to your
78DID, you can find your DID in the [Settings](https://tangled.sh/settings) page.
79
80```
81KNOT_REPO_SCAN_PATH=/home/git
82KNOT_SERVER_HOSTNAME=knot.example.com
83APPVIEW_ENDPOINT=https://tangled.sh
84KNOT_SERVER_OWNER=did:plc:foobar
85KNOT_SERVER_INTERNAL_LISTEN_ADDR=127.0.0.1:5444
86KNOT_SERVER_LISTEN_ADDR=127.0.0.1:5555
87```
88
89If you run a Linux distribution that uses systemd, you can use the provided
90service file to run the server. Copy
91[`knotserver.service`](/systemd/knotserver.service)
92to `/etc/systemd/system/`. Then, run:
93
94```
95systemctl enable knotserver
96systemctl start knotserver
97```
98
99The last step is to configure a reverse proxy like Nginx or Caddy to front your
100knot. Here's an example configuration for Nginx:
101
102```
103server {
104 listen 80;
105 listen [::]:80;
106 server_name knot.example.com;
107
108 location / {
109 proxy_pass http://localhost:5555;
110 proxy_set_header Host $host;
111 proxy_set_header X-Real-IP $remote_addr;
112 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
113 proxy_set_header X-Forwarded-Proto $scheme;
114 }
115
116 # wss endpoint for git events
117 location /events {
118 proxy_set_header X-Forwarded-For $remote_addr;
119 proxy_set_header Host $http_host;
120 proxy_set_header Upgrade websocket;
121 proxy_set_header Connection Upgrade;
122 proxy_pass http://localhost:5555;
123 }
124 # additional config for SSL/TLS go here.
125}
126
127```
128
129Remember to use Let's Encrypt or similar to procure a certificate for your
130knot domain.
131
132You should now have a running knot server! You can finalize
133your registration by hitting the `verify` button on the
134[/settings/knots](https://tangled.org/settings/knots) page. This simply creates
135a record on your PDS to announce the existence of the knot.
136
137### custom paths
138
139(This section applies to manual setup only. Docker users should edit the mounts
140in `docker-compose.yml` instead.)
141
142Right now, the database and repositories of your knot lives in `/home/git`. You
143can move these paths if you'd like to store them in another folder. Be careful
144when adjusting these paths:
145
146* Stop your knot when moving data (e.g. `systemctl stop knotserver`) to prevent
147any possible side effects. Remember to restart it once you're done.
148* Make backups before moving in case something goes wrong.
149* Make sure the `git` user can read and write from the new paths.
150
151#### database
152
153As an example, let's say the current database is at `/home/git/knotserver.db`,
154and we want to move it to `/home/git/database/knotserver.db`.
155
156Copy the current database to the new location. Make sure to copy the `.db-shm`
157and `.db-wal` files if they exist.
158
159```
160mkdir /home/git/database
161cp /home/git/knotserver.db* /home/git/database
162```
163
164In the environment (e.g. `/home/git/.knot.env`), set `KNOT_SERVER_DB_PATH` to
165the new file path (_not_ the directory):
166
167```
168KNOT_SERVER_DB_PATH=/home/git/database/knotserver.db
169```
170
171#### repositories
172
173As an example, let's say the repositories are currently in `/home/git`, and we
174want to move them into `/home/git/repositories`.
175
176Create the new folder, then move the existing repositories (if there are any):
177
178```
179mkdir /home/git/repositories
180# move all DIDs into the new folder; these will vary for you!
181mv /home/git/did:plc:wshs7t2adsemcrrd4snkeqli /home/git/repositories
182```
183
184In the environment (e.g. `/home/git/.knot.env`), update `KNOT_REPO_SCAN_PATH`
185to the new directory:
186
187```
188KNOT_REPO_SCAN_PATH=/home/git/repositories
189```
190
191Similarly, update your `sshd` `AuthorizedKeysCommand` to use the updated
192repository path:
193
194```
195sudo tee /etc/ssh/sshd_config.d/authorized_keys_command.conf <<EOF
196Match User git
197 AuthorizedKeysCommand /usr/local/bin/knot keys -o authorized-keys -git-dir /home/git/repositories
198 AuthorizedKeysCommandUser nobody
199EOF
200```
201
202Make sure to restart your SSH server!
203
204#### MOTD (message of the day)
205
206To configure the MOTD used ("Welcome to this knot!" by default), edit the
207`/home/git/motd` file:
208
209```
210printf "Hi from this knot!\n" > /home/git/motd
211```
212
213Note that you should add a newline at the end if setting a non-empty message
214since the knot won't do this for you.