this repo has no description
1# BSPDS Production Installation on Alpine Linux
2> **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.
3
4This guide covers installing BSPDS on Alpine Linux 3.23 (current stable as of December 2025).
5
6## Prerequisites
7- A VPS with at least 2GB RAM and 20GB disk
8- A domain name pointing to your server's IP
9- A **wildcard TLS certificate** for `*.pds.example.com` (user handles are served as subdomains)
10- Root access
11## 1. System Setup
12```sh
13apk update && apk upgrade
14apk add curl git build-base openssl-dev pkgconf
15```
16## 2. Install Rust
17```sh
18apk add rustup
19rustup-init -y
20source ~/.cargo/env
21rustup default stable
22```
23This installs the latest stable Rust (1.92+ as of December 2025). Alpine 3.23 also ships Rust 1.91 via `apk add rust cargo` if you prefer system packages.
24## 3. Install postgres
25Alpine 3.23 includes PostgreSQL 18:
26```sh
27apk add postgresql postgresql-contrib
28rc-update add postgresql
29/etc/init.d/postgresql setup
30rc-service postgresql start
31psql -U postgres -c "CREATE USER bspds WITH PASSWORD 'your-secure-password';"
32psql -U postgres -c "CREATE DATABASE pds OWNER bspds;"
33psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE pds TO bspds;"
34```
35## 4. Install minio
36```sh
37curl -O https://dl.min.io/server/minio/release/linux-amd64/minio
38chmod +x minio
39mv minio /usr/local/bin/
40mkdir -p /var/lib/minio/data
41adduser -D -H -s /sbin/nologin minio-user
42chown -R minio-user:minio-user /var/lib/minio
43cat > /etc/conf.d/minio << 'EOF'
44MINIO_ROOT_USER="minioadmin"
45MINIO_ROOT_PASSWORD="your-minio-password"
46MINIO_VOLUMES="/var/lib/minio/data"
47MINIO_OPTS="--console-address :9001"
48EOF
49cat > /etc/init.d/minio << 'EOF'
50#!/sbin/openrc-run
51name="minio"
52description="MinIO Object Storage"
53command="/usr/local/bin/minio"
54command_args="server ${MINIO_VOLUMES} ${MINIO_OPTS}"
55command_user="minio-user"
56command_background=true
57pidfile="/run/${RC_SVCNAME}.pid"
58output_log="/var/log/minio.log"
59error_log="/var/log/minio.log"
60depend() {
61 need net
62}
63start_pre() {
64 . /etc/conf.d/minio
65 export MINIO_ROOT_USER MINIO_ROOT_PASSWORD
66}
67EOF
68chmod +x /etc/init.d/minio
69rc-update add minio
70rc-service minio start
71```
72Create the blob bucket (wait a few seconds for minio to start):
73```sh
74curl -O https://dl.min.io/client/mc/release/linux-amd64/mc
75chmod +x mc
76mv mc /usr/local/bin/
77mc alias set local http://localhost:9000 minioadmin your-minio-password
78mc mb local/pds-blobs
79```
80## 5. Install valkey
81Alpine 3.23 includes Valkey 9:
82```sh
83apk add valkey
84rc-update add valkey
85rc-service valkey start
86```
87## 6. Install deno (for frontend build)
88```sh
89curl -fsSL https://deno.land/install.sh | sh
90export PATH="$HOME/.deno/bin:$PATH"
91echo 'export PATH="$HOME/.deno/bin:$PATH"' >> ~/.profile
92```
93## 7. Clone and Build BSPDS
94```sh
95mkdir -p /opt && cd /opt
96git clone https://tangled.org/lewis.moe/bspds-sandbox bspds
97cd bspds
98cd frontend
99deno task build
100cd ..
101cargo build --release
102```
103## 8. Install sqlx-cli and Run Migrations
104```sh
105cargo install sqlx-cli --no-default-features --features postgres
106export DATABASE_URL="postgres://bspds:your-secure-password@localhost:5432/pds"
107sqlx migrate run
108```
109## 9. Configure BSPDS
110```sh
111mkdir -p /etc/bspds
112cp /opt/bspds/.env.example /etc/bspds/bspds.env
113chmod 600 /etc/bspds/bspds.env
114```
115Edit `/etc/bspds/bspds.env` and fill in your values. Generate secrets with:
116```sh
117openssl rand -base64 48
118```
119## 10. Create OpenRC Service
120```sh
121adduser -D -H -s /sbin/nologin bspds
122cp /opt/bspds/target/release/bspds /usr/local/bin/
123mkdir -p /var/lib/bspds
124cp -r /opt/bspds/frontend/dist /var/lib/bspds/frontend
125chown -R bspds:bspds /var/lib/bspds
126cat > /etc/init.d/bspds << 'EOF'
127#!/sbin/openrc-run
128name="bspds"
129description="BSPDS - AT Protocol PDS"
130command="/usr/local/bin/bspds"
131command_user="bspds"
132command_background=true
133pidfile="/run/${RC_SVCNAME}.pid"
134output_log="/var/log/bspds.log"
135error_log="/var/log/bspds.log"
136depend() {
137 need net postgresql minio
138}
139start_pre() {
140 export FRONTEND_DIR=/var/lib/bspds/frontend
141 . /etc/bspds/bspds.env
142 export SERVER_HOST SERVER_PORT PDS_HOSTNAME DATABASE_URL
143 export S3_ENDPOINT AWS_REGION S3_BUCKET AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY
144 export VALKEY_URL JWT_SECRET DPOP_SECRET MASTER_KEY CRAWLERS
145}
146EOF
147chmod +x /etc/init.d/bspds
148rc-update add bspds
149rc-service bspds start
150```
151## 11. Install and Configure nginx
152Alpine 3.23 includes nginx 1.28:
153```sh
154apk add nginx certbot certbot-nginx
155cat > /etc/nginx/http.d/bspds.conf << 'EOF'
156server {
157 listen 80;
158 listen [::]:80;
159 server_name pds.example.com;
160 location / {
161 proxy_pass http://127.0.0.1:3000;
162 proxy_http_version 1.1;
163 proxy_set_header Upgrade $http_upgrade;
164 proxy_set_header Connection "upgrade";
165 proxy_set_header Host $host;
166 proxy_set_header X-Real-IP $remote_addr;
167 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
168 proxy_set_header X-Forwarded-Proto $scheme;
169 proxy_read_timeout 86400;
170 }
171}
172EOF
173rc-update add nginx
174rc-service nginx start
175```
176## 12. Obtain Wildcard SSL Certificate
177User handles are served as subdomains (e.g., `alice.pds.example.com`), so you need a wildcard certificate.
178
179Wildcard certs require DNS-01 validation. For manual DNS validation (works with any provider):
180```sh
181certbot certonly --manual --preferred-challenges dns \
182 -d pds.example.com -d '*.pds.example.com'
183```
184Follow the prompts to add TXT records to your DNS.
185
186If your DNS provider has a certbot plugin, you can use that for auto-renewal:
187```sh
188apk add certbot-dns-cloudflare
189certbot certonly --dns-cloudflare \
190 --dns-cloudflare-credentials /etc/cloudflare.ini \
191 -d pds.example.com -d '*.pds.example.com'
192```
193
194After obtaining the cert, update nginx to use it, then set up auto-renewal:
195```sh
196echo "0 0 * * * certbot renew --quiet && rc-service nginx reload" | crontab -
197```
198## 13. Configure Firewall
199```sh
200apk add iptables ip6tables
201iptables -A INPUT -p tcp --dport 22 -j ACCEPT
202iptables -A INPUT -p tcp --dport 80 -j ACCEPT
203iptables -A INPUT -p tcp --dport 443 -j ACCEPT
204iptables -A INPUT -i lo -j ACCEPT
205iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
206iptables -P INPUT DROP
207ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
208ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT
209ip6tables -A INPUT -p tcp --dport 443 -j ACCEPT
210ip6tables -A INPUT -i lo -j ACCEPT
211ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
212ip6tables -P INPUT DROP
213rc-update add iptables
214rc-update add ip6tables
215/etc/init.d/iptables save
216/etc/init.d/ip6tables save
217```
218## 14. Verify Installation
219```sh
220rc-service bspds status
221curl -s https://pds.example.com/xrpc/_health
222curl -s https://pds.example.com/.well-known/atproto-did
223```
224## Maintenance
225View logs:
226```sh
227tail -f /var/log/bspds.log
228```
229Update BSPDS:
230```sh
231cd /opt/bspds
232git pull
233cd frontend && deno task build && cd ..
234cargo build --release
235rc-service bspds stop
236cp target/release/bspds /usr/local/bin/
237cp -r frontend/dist /var/lib/bspds/frontend
238DATABASE_URL="postgres://bspds:your-secure-password@localhost:5432/pds" sqlx migrate run
239rc-service bspds start
240```
241Backup database:
242```sh
243pg_dump -U postgres pds > /var/backups/pds-$(date +%Y%m%d).sql
244```