docs: slightly improve docs

This commit is contained in:
Sam 2023-03-23 10:49:49 +01:00
parent dd608bbb22
commit 0d5b6e276e
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
9 changed files with 73 additions and 47 deletions

68
docs/production.md Normal file
View file

@ -0,0 +1,68 @@
# Running pronouns.cc in production
The configuration files in this directory are the same files used to run pronouns.cc in production.
You might have to change paths and ports, but they should work fine as-is.
## Building pronouns.cc
```bash
git clone https://codeberg.org/u1f320/pronouns.cc.git pronouns
cd pronouns
make all
# if running for the first time
./pronouns database migrate
```
## Configuration
pronouns.cc is configured using `.env` files. Note that there are two separate `.env` files,
one in the repository root (for the backend) and one in the frontend directory.
### Backend keys
- `HMAC_KEY`: the key used to sign tokens. This should be a base64 string, you can generate one with `scripts/genkey`.
- `DATABASE_URL`: the URL for the PostgreSQL database.
- `REDIS`: the URL for the Redis database.
- `PORT` (int): the port the backend will listen on.
- `EXPORTER_PORT` (int): the port that the exporter service will listen on.
- `DEBUG` (true/false): whether to enable request logging.
- `BASE_URL`: the base URL for the frontend, used to construct some links.
- `MINIO_ENDPOINT`: the S3 endpoint for object storage.
- `MINIO_BUCKET`: the S3 bucket name.
- `MINIO_ACCESS_KEY_ID`: the S3 access key ID.
- `MINIO_ACCESS_KEY_SECRET`: the S3 access key secret.
- `MINIO_SSL`: whether to use SSL for S3.
- `FRONTEND_IP`: the IP for the frontend, which the rate limiter will ignore.
- `REQUIRE_INVITE`: whether to require invites to sign up.
- `DISCORD_CLIENT_ID`: for Discord auth, the client ID.
- `DISCORD_CLIENT_SECRET`: for Discord auth, the client secret.
- `DISCORD_PUBLIC_KEY`: public key for the Discord bot endpoint.
### Frontend keys
- `PUBLIC_BASE_URL`: the base URL for the frontend.
- `PRIVATE_SENTRY_DSN`: your Sentry DSN.
## Updating
```bash
make all
systemctl stop pronouns-api pronouns-fe
systemctl stop pronouns-exporter # only if the User, Member, Field, Export tables changed
./pronouns database migrate # only if a new migration was added
systemctl start pronouns-api pronouns-fe
systemctl start pronouns-exporter # if the exporter was stopped
```
## Proxy
Both the backend and frontend are expected to run behind a reverse proxy such as Caddy or nginx.
This directory contains a sample configuration file for nginx.
Every path should be proxied to the frontend, except:
- `/api/`: this should be proxied to the backend, with the URL being rewritten to remove `/api`
(for example, a request to `$DOMAIN/api/v1/users/@me` should be proxied to `localhost:8080/v1/users/@me`)
- `/media/`: this should be proxied to your object storage.
Make sure to rewrite `/media` into your storage bucket's name.

19
docs/pronouns-api.service Normal file
View file

@ -0,0 +1,19 @@
[Unit]
Description=pronouns.cc API
After=syslog.target
After=network.target
Requires=postgresql.service redis.service
[Service]
RestartSec=2s
Type=simple
User=pronouns
Group=pronouns
AmbientCapabilities=
WorkingDirectory=/home/pronouns/src
ExecStart=/home/pronouns/src/pronouns web
Restart=always
Environment=USER=pronouns HOME=/home/pronouns
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,19 @@
[Unit]
Description=Clean pronouns.cc database
After=syslog.target
After=network.target
Requires=postgresql.service redis.service
[Service]
RestartSec=2s
Type=oneshot
User=pronouns
Group=pronouns
AmbientCapabilities=
WorkingDirectory=/home/pronouns/src
ExecStart=/home/pronouns/src/pronouns database clean
Restart=no
Environment=USER=pronouns HOME=/home/pronouns
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,9 @@
[Unit]
Description=Clean pronouns.cc database daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target

View file

@ -0,0 +1,19 @@
[Unit]
Description=pronouns.cc data exporter service
After=syslog.target
After=network.target
Requires=postgresql.service redis.service
[Service]
RestartSec=2s
Type=simple
User=pronouns
Group=pronouns
AmbientCapabilities=
WorkingDirectory=/home/pronouns/src
ExecStart=/home/pronouns/src/pronouns exporter
Restart=always
Environment=USER=pronouns HOME=/home/pronouns
[Install]
WantedBy=multi-user.target

19
docs/pronouns-fe.service Normal file
View file

@ -0,0 +1,19 @@
[Unit]
Description=pronouns.cc frontend
After=syslog.target
After=network.target
Requires=pronouns-api.service
[Service]
RestartSec=2s
Type=simple
User=pronouns
Group=pronouns
AmbientCapabilities=
WorkingDirectory=/home/pronouns/src/frontend
ExecStart=node build/index.js
Restart=always
Environment=USER=pronouns HOME=/home/pronouns
[Install]
WantedBy=multi-user.target

75
docs/pronounscc.nginx Normal file
View file

@ -0,0 +1,75 @@
server {
server_name example.tld;
listen 80;
listen [::]:80;
# For SSL domain validation
root /var/www/html;
location /.well-known/acme-challenge/ { allow all; }
location /.well-known/pki-validation/ { allow all; }
location / { return 301 https://$server_name$request_uri; }
}
# For media proxy
proxy_cache_path /tmp/pronouns-media-cache levels=1:2 keys_zone=pronouns_media_cache:10m max_size=1g
inactive=720m use_temp_path=off;
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.tld;
ssl_session_timeout 1d;
ssl_session_cache shared:ssl_session_cache:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_stapling on;
ssl_stapling_verify on;
# To use a Let's Encrypt certificate
ssl_trusted_certificate /etc/letsencrypt/live/example.tld/chain.pem;
ssl_certificate /etc/letsencrypt/live/example.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.tld/privkey.pem;
# To use Debian/Ubuntu's self-signed certificate (For testing or before issuing a certificate)
#ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
#ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
client_max_body_size 8m;
location ~ ^/api {
rewrite ^/api(.*) $1 break;
proxy_pass http://127.0.0.1:8080;
}
location ~ ^/media {
proxy_cache pronouns_media_cache;
slice 1m;
proxy_cache_key $host$uri$is_args$args$slice_range;
proxy_set_header Range $slice_range;
proxy_cache_valid 200 206 301 304 1h;
proxy_cache_lock on;
proxy_ignore_client_abort on;
proxy_buffering on;
chunked_transfer_encoding on;
# Rewrite URL to remove /media/ and add bucket
rewrite ^/media/(.*) /pronouns/$1 break;
proxy_pass http://127.0.0.1:9000;
}
location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_pass http://127.0.0.1:3000;
}
}