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 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 [flake.nix](https://tangled.sh/@tangled.sh/core/blob/master/flake.nix)
11* Docker: Documented below.
12* Manual: Documented below.
13
14## docker setup
15
16Clone this repository:
17
18```
19git clone https://tangled.sh/@tangled.sh/core
20```
21
22Modify the `docker/docker-compose.yml`, specifically the
23`KNOT_SERVER_SECRET` and `KNOT_SERVER_HOSTNAME` env vars. Then run:
24
25```
26docker compose -f docker/docker-compose.yml up
27```
28
29## manual setup
30
31First, clone this repository:
32
33```
34git clone https://tangled.sh/@tangled.sh/core
35```
36
37Then, build the `knot` CLI. This is the knot administration and operation tool.
38For the purpose of this guide, we're only concerned with these subcommands:
39
40* `knot server`: the main knot server process, typically run as a
41supervised service
42* `knot guard`: handles role-based access control for git over SSH
43(you'll never have to run this yourself)
44* `knot keys`: fetches SSH keys associated with your knot; we'll use
45this to generate the SSH `AuthorizedKeysCommand`
46
47```
48cd core
49export CGO_ENABLED=1
50go build -o knot ./cmd/knot
51```
52
53Next, move the `knot` binary to a location owned by `root` --
54`/usr/local/bin/knot` is a good choice:
55
56```
57sudo mv knot /usr/local/bin/knot
58```
59
60This is necessary because SSH `AuthorizedKeysCommand` requires [really
61specific permissions](https://stackoverflow.com/a/27638306). The
62`AuthorizedKeysCommand` specifies a command that is run by `sshd` to
63retrieve a user's public SSH keys dynamically for authentication. Let's
64set that up.
65
66```
67sudo tee /etc/ssh/sshd_config.d/authorized_keys_command.conf <<EOF
68Match User git
69 AuthorizedKeysCommand /usr/local/bin/knot keys -o authorized-keys
70 AuthorizedKeysCommandUser nobody
71EOF
72```
73
74Next, create the `git` user. We'll use the `git` user's home directory
75to store repositories:
76
77```
78sudo adduser git
79```
80
81Create `/home/git/.knot.env` with the following, updating the values as
82necessary. The `KNOT_SERVER_SECRET` can be obtaind from the
83[/knots](/knots) page on Tangled.
84
85```
86KNOT_REPO_SCAN_PATH=/home/git
87KNOT_SERVER_HOSTNAME=knot.example.com
88APPVIEW_ENDPOINT=https://tangled.sh
89KNOT_SERVER_SECRET=secret
90KNOT_SERVER_INTERNAL_LISTEN_ADDR=127.0.0.1:5444
91KNOT_SERVER_LISTEN_ADDR=127.0.0.1:5555
92```
93
94If you run a Linux distribution that uses systemd, you can use the provided
95service file to run the server. Copy
96[`knotserver.service`](/systemd/knotserver.service)
97to `/etc/systemd/system/`. Then, run:
98
99```
100systemctl enable knotserver
101systemctl start knotserver
102```
103
104You should now have a running knot server! You can finalize your registration by hitting the
105`initialize` button on the [/knots](/knots) page.
106
107### custom paths
108
109(This section applies to manual setup only. Docker users should edit the mounts
110in `docker-compose.yml` instead.)
111
112Right now, the database and repositories of your knot lives in `/home/git`. You
113can move these paths if you'd like to store them in another folder. Be careful
114when adjusting these paths:
115
116* Stop your knot when moving data (e.g. `systemctl stop knotserver`) to prevent
117any possible side effects. Remember to restart it once you're done.
118* Make backups before moving in case something goes wrong.
119* Make sure the `git` user can read and write from the new paths.
120
121#### database
122
123As an example, let's say the current database is at `/home/git/knotserver.db`,
124and we want to move it to `/home/git/database/knotserver.db`.
125
126Copy the current database to the new location. Make sure to copy the `.db-shm`
127and `.db-wal` files if they exist.
128
129```
130mkdir /home/git/database
131cp /home/git/knotserver.db* /home/git/database
132```
133
134In the environment (e.g. `/home/git/.knot.env`), set `KNOT_SERVER_DB_PATH` to
135the new file path (_not_ the directory):
136
137```
138KNOT_SERVER_DB_PATH=/home/git/database/knotserver.db
139```
140
141#### repositories
142
143As an example, let's say the repositories are currently in `/home/git`, and we
144want to move them into `/home/git/repositories`.
145
146Create the new folder, then move the existing repositories (if there are any):
147
148```
149mkdir /home/git/repositories
150# move all DIDs into the new folder; these will vary for you!
151mv /home/git/did:plc:wshs7t2adsemcrrd4snkeqli /home/git/repositories
152```
153
154In the environment (e.g. `/home/git/.knot.env`), update `KNOT_REPO_SCAN_PATH`
155to the new directory:
156
157```
158KNOT_REPO_SCAN_PATH=/home/git/repositories
159```
160
161Similarly, update your `sshd` `AuthorizedKeysCommand` to use the updated
162repository path:
163
164```
165sudo tee /etc/ssh/sshd_config.d/authorized_keys_command.conf <<EOF
166Match User git
167 AuthorizedKeysCommand /usr/local/bin/knot keys -o authorized-keys -git-dir /home/git/repositories
168 AuthorizedKeysCommandUser nobody
169EOF
170```
171
172Make sure to restart your SSH server!