this repo has no description
1# BSPDS Production Installation on OpenBSD
2
3> **Warning**: These instructions are untested and theoretical, written from the top of Lewis' head. They may contain errors or omissions. This warning will be removed once the guide has been verified.
4
5This guide covers installing BSPDS on OpenBSD 7.8 (current release as of December 2025).
6
7## Prerequisites
8
9- A VPS with at least 2GB RAM and 20GB disk
10- A domain name pointing to your server's IP
11- Root access (or doas configured)
12
13## Why nginx over relayd?
14
15OpenBSD's native `relayd` supports WebSockets but does **not** support HTTP/2. For a modern PDS deployment, we recommend nginx which provides HTTP/2, WebSocket support, and automatic OCSP stapling.
16
17## 1. System Setup
18
19```sh
20pkg_add curl git
21```
22
23## 2. Install Rust
24
25```sh
26pkg_add rust
27```
28
29OpenBSD 7.8 ships Rust 1.82+. For the latest stable (1.92+), use rustup:
30
31```sh
32pkg_add rustup
33rustup-init -y
34source ~/.cargo/env
35rustup default stable
36```
37
38## 3. Install postgres
39
40OpenBSD 7.8 includes PostgreSQL 17 (PostgreSQL 18 may not yet be in ports):
41
42```sh
43pkg_add postgresql-server postgresql-client
44
45mkdir -p /var/postgresql/data
46chown _postgresql:_postgresql /var/postgresql/data
47su - _postgresql -c "initdb -D /var/postgresql/data -U postgres -A scram-sha-256"
48
49rcctl enable postgresql
50rcctl start postgresql
51
52psql -U postgres -c "CREATE USER bspds WITH PASSWORD 'your-secure-password';"
53psql -U postgres -c "CREATE DATABASE pds OWNER bspds;"
54psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE pds TO bspds;"
55```
56
57## 4. Install minio
58
59OpenBSD doesn't have a minio package. Options:
60
61**Option A: Use an external S3-compatible service (recommended for production)**
62
63aws s3, backblaze b2, or upcloud managed object storage. Skip to step 5 and configure the S3 credentials in step 9.
64
65**Option B: Build minio from source**
66
67```sh
68pkg_add go
69
70mkdir -p /tmp/minio-build && cd /tmp/minio-build
71ftp -o minio.tar.gz https://github.com/minio/minio/archive/refs/tags/RELEASE.2025-10-15T17-29-55Z.tar.gz
72tar xzf minio.tar.gz
73cd minio-*
74go build -o minio .
75cp minio /usr/local/bin/
76
77mkdir -p /var/minio/data
78useradd -d /var/minio -s /sbin/nologin _minio
79chown -R _minio:_minio /var/minio
80
81cat > /etc/minio.conf << 'EOF'
82MINIO_ROOT_USER=minioadmin
83MINIO_ROOT_PASSWORD=your-minio-password
84EOF
85chmod 600 /etc/minio.conf
86
87cat > /etc/rc.d/minio << 'EOF'
88#!/bin/ksh
89
90daemon="/usr/local/bin/minio"
91daemon_user="_minio"
92daemon_flags="server /var/minio/data --console-address :9001"
93
94. /etc/rc.d/rc.subr
95
96rc_pre() {
97 . /etc/minio.conf
98 export MINIO_ROOT_USER MINIO_ROOT_PASSWORD
99}
100
101rc_cmd $1
102EOF
103
104chmod +x /etc/rc.d/minio
105rcctl enable minio
106rcctl start minio
107```
108
109Create the blob bucket:
110
111```sh
112ftp -o /usr/local/bin/mc https://dl.min.io/client/mc/release/openbsd-amd64/mc
113chmod +x /usr/local/bin/mc
114
115mc alias set local http://localhost:9000 minioadmin your-minio-password
116mc mb local/pds-blobs
117```
118
119## 5. Install redis
120
121OpenBSD has redis in ports (valkey may not be available yet):
122
123```sh
124pkg_add redis
125
126rcctl enable redis
127rcctl start redis
128```
129
130## 6. Install deno (for frontend build)
131
132```sh
133curl -fsSL https://deno.land/install.sh | sh
134export PATH="$HOME/.deno/bin:$PATH"
135echo 'export PATH="$HOME/.deno/bin:$PATH"' >> ~/.profile
136```
137
138## 7. Clone and Build BSPDS
139
140```sh
141mkdir -p /opt && cd /opt
142git clone https://tangled.org/lewis.moe/bspds.git
143cd bspds
144
145cd frontend
146deno task build
147cd ..
148
149cargo build --release
150```
151
152## 8. Install sqlx-cli and Run Migrations
153
154```sh
155cargo install sqlx-cli --no-default-features --features postgres
156
157export DATABASE_URL="postgres://bspds:your-secure-password@localhost:5432/pds"
158sqlx migrate run
159```
160
161## 9. Configure BSPDS
162
163```sh
164mkdir -p /etc/bspds
165cp /opt/bspds/.env.example /etc/bspds/bspds.conf
166chmod 600 /etc/bspds/bspds.conf
167```
168
169Edit `/etc/bspds/bspds.conf` and fill in your values. Generate secrets with:
170
171```sh
172openssl rand -base64 48
173```
174
175## 10. Create rc.d Service
176
177```sh
178useradd -d /var/empty -s /sbin/nologin _bspds
179
180cp /opt/bspds/target/release/bspds /usr/local/bin/
181mkdir -p /var/bspds
182cp -r /opt/bspds/frontend/dist /var/bspds/frontend
183chown -R _bspds:_bspds /var/bspds
184
185cat > /etc/rc.d/bspds << 'EOF'
186#!/bin/ksh
187
188daemon="/usr/local/bin/bspds"
189daemon_user="_bspds"
190daemon_logger="daemon.info"
191
192. /etc/rc.d/rc.subr
193
194rc_pre() {
195 export FRONTEND_DIR=/var/bspds/frontend
196 while IFS='=' read -r key value; do
197 case "$key" in
198 \#*|"") continue ;;
199 esac
200 export "$key=$value"
201 done < /etc/bspds/bspds.conf
202}
203
204rc_cmd $1
205EOF
206
207chmod +x /etc/rc.d/bspds
208rcctl enable bspds
209rcctl start bspds
210```
211
212## 11. Install and Configure nginx
213
214```sh
215pkg_add nginx
216
217cat > /etc/nginx/nginx.conf << 'EOF'
218worker_processes 1;
219
220events {
221 worker_connections 1024;
222}
223
224http {
225 include mime.types;
226
227 server {
228 listen 80;
229 listen [::]:80;
230 server_name pds.example.com;
231
232 location /.well-known/acme-challenge/ {
233 root /var/www/acme;
234 }
235
236 location / {
237 return 301 https://$host$request_uri;
238 }
239 }
240
241 server {
242 listen 443 ssl http2;
243 listen [::]:443 ssl http2;
244 server_name pds.example.com;
245
246 ssl_certificate /etc/ssl/pds.example.com.fullchain.pem;
247 ssl_certificate_key /etc/ssl/private/pds.example.com.key;
248 ssl_protocols TLSv1.2 TLSv1.3;
249 ssl_ciphers HIGH:!aNULL:!MD5;
250 ssl_prefer_server_ciphers on;
251 ssl_session_cache shared:SSL:10m;
252
253 location / {
254 proxy_pass http://127.0.0.1:3000;
255 proxy_http_version 1.1;
256 proxy_set_header Upgrade $http_upgrade;
257 proxy_set_header Connection "upgrade";
258 proxy_set_header Host $host;
259 proxy_set_header X-Real-IP $remote_addr;
260 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
261 proxy_set_header X-Forwarded-Proto $scheme;
262 proxy_read_timeout 86400;
263 }
264 }
265}
266EOF
267
268mkdir -p /var/www/acme
269rcctl enable nginx
270```
271
272## 12. Obtain SSL Certificate with acme-client
273
274OpenBSD's native acme-client works well:
275
276```sh
277cat >> /etc/acme-client.conf << 'EOF'
278
279authority letsencrypt {
280 api url "https://acme-v02.api.letsencrypt.org/directory"
281 account key "/etc/acme/letsencrypt-privkey.pem"
282}
283
284domain pds.example.com {
285 domain key "/etc/ssl/private/pds.example.com.key"
286 domain full chain certificate "/etc/ssl/pds.example.com.fullchain.pem"
287 sign with letsencrypt
288}
289EOF
290
291mkdir -p /etc/acme
292
293rcctl start nginx
294
295acme-client -v pds.example.com
296
297rcctl restart nginx
298```
299
300Set up auto-renewal in root's crontab:
301
302```sh
303crontab -e
304```
305
306Add:
307```
3080 0 * * * acme-client pds.example.com && rcctl reload nginx
309```
310
311## 13. Configure Packet Filter (pf)
312
313```sh
314cat >> /etc/pf.conf << 'EOF'
315
316# BSPDS rules
317pass in on egress proto tcp from any to any port { 22, 80, 443 }
318EOF
319
320pfctl -f /etc/pf.conf
321```
322
323## 14. Verify Installation
324
325```sh
326rcctl check bspds
327ftp -o - https://pds.example.com/xrpc/_health
328ftp -o - https://pds.example.com/.well-known/atproto-did
329```
330
331## Maintenance
332
333View logs:
334```sh
335tail -f /var/log/daemon
336```
337
338Update BSPDS:
339```sh
340cd /opt/bspds
341git pull
342cd frontend && deno task build && cd ..
343cargo build --release
344rcctl stop bspds
345cp target/release/bspds /usr/local/bin/
346cp -r frontend/dist /var/bspds/frontend
347DATABASE_URL="postgres://bspds:your-secure-password@localhost:5432/pds" sqlx migrate run
348rcctl start bspds
349```
350
351Backup database:
352```sh
353pg_dump -U postgres pds > /var/backups/pds-$(date +%Y%m%d).sql
354```