Merge branch 'mastodon-nginx' into 'develop'

Installing Soapbox atop Mastodon with Nginx

See merge request soapbox-pub/soapbox-fe!1345
This commit is contained in:
Alex Gleason 2022-05-10 22:41:21 +00:00
commit f08583668e
2 changed files with 196 additions and 0 deletions

View file

@ -0,0 +1,35 @@
# Installing Soapbox over Mastodon
It is possible to run Soapbox as your main frontend on top of Mastodon.
This will replace the homepage and all static pages with Soapbox, using Mastodon only as the API.
To do so, shell into your server and unpack Soapbox:
```sh
mkdir -p /opt/soapbox
curl -L https://gitlab.com/soapbox-pub/soapbox-fe/-/jobs/artifacts/develop/download?job=build-production -o soapbox-fe.zip
busybox unzip soapbox-fe.zip -o -d /opt/soapbox
```
Now create an Nginx file for Soapbox with Mastodon.
If you already have one, replace it:
```sh
curl https://gitlab.com/soapbox-pub/soapbox-fe/-/raw/develop/installation/mastodon.conf > /etc/nginx/sites-available/mastodon
```
Edit this file and replace all occurrences of `example.com` with your domain name.
Uncomment the SSL lines if you've enabled SSL, otherwise do that first.
Finally, ensure the file is symlinked, then restart Nginx:
```sh
ln -s /etc/nginx/sites-available/mastodon /etc/nginx/sites-enabled/mastodon
systemctl restart nginx
```
If all is well, hopefully this worked!
If not, run `nginx -t` to see if anything is amiss, and try reviewing Mastodon's [install guide](https://docs.joinmastodon.org/admin/install/).

161
installation/mastodon.conf Normal file
View file

@ -0,0 +1,161 @@
# Nginx configuration for Soapbox on Mastodon.
# Adapted from: https://github.com/mastodon/mastodon/blob/b4d373a3df2752d9f8bdc0d7f02350528f3789b2/dist/nginx.conf
#
# Edit this file to change occurences of "example.com" to your own domain.
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# ActivityPub routing.
map $http_accept $activitypub_location {
default /index.html;
"application/activity+json" @proxy;
# Increase `map_hash_bucket_size` to enable this route:
# 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' @proxy;
}
upstream backend {
server 127.0.0.1:3000 fail_timeout=0;
}
upstream streaming {
server 127.0.0.1:4000 fail_timeout=0;
}
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g;
server {
listen 80;
listen [::]:80;
server_name example.com;
root /opt/soapbox/static;
location /.well-known/acme-challenge/ { allow all; }
location / { return 301 https://$host$request_uri; }
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# Uncomment these lines once you acquire a certificate:
# ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
keepalive_timeout 70;
sendfile on;
client_max_body_size 80m;
root /opt/soapbox/static;
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml image/x-icon;
add_header Strict-Transport-Security "max-age=31536000" always;
# Fallback route.
# Everything not routed should fall back to the SPA.
location / {
try_files /index.html /dev/null;
}
# Mastodon backend routes.
# These are routes to Mastodon's API and important rendered pages.
location ~ ^/(api|oauth|auth|admin|pghero|sidekiq|manifest.json|.well-known/webfinger|@(.+)/embed$) {
try_files /dev/null @proxy;
}
# Mastodon ActivityPub routes.
# Conditionally send to Mastodon by Accept header.
location ~ ^/(inbox|outbox|users|@(.+)) {
try_files $activitypub_location $activitypub_location;
}
# Mastodon public files.
# https://github.com/mastodon/mastodon/tree/main/public
# Take only what we need for Soapbox.
location ~ ^/(assets|favicon.ico|browserconfig.xml|embed.js|android-chrome-192x192.png|apple-touch-icon.png|avatars/original/missing.png|headers/original/missing.png) {
root /home/mastodon/live/public;
add_header Cache-Control "public, max-age=31536000, immutable";
add_header Strict-Transport-Security "max-age=31536000" always;
}
# Soapbox build files.
# New builds produce hashed filenames, so these should be cached heavily.
location ~ ^/(packs|emoji) {
add_header Cache-Control "public, max-age=31536000, immutable";
add_header Strict-Transport-Security "max-age=31536000" always;
}
# Soapbox configuration files.
# Enable CORS so we can fetch them.
location /instance {
add_header Access-Control-Allow-Origin "*";
}
# Soapbox ServiceWorker.
location = /sw.js {
add_header Cache-Control "public, max-age=0";
add_header Strict-Transport-Security "max-age=31536000" always;
}
# Proxy to Mastodon's Ruby on Rails backend.
location @proxy {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Proxy "";
proxy_pass_header Server;
proxy_pass http://backend;
proxy_buffering on;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_cache CACHE;
proxy_cache_valid 200 7d;
proxy_cache_valid 410 24h;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
add_header X-Cached $upstream_cache_status;
add_header Strict-Transport-Security "max-age=31536000" always;
tcp_nodelay on;
}
# Mastodon's Node.js streaming server.
location ^~ /api/v1/streaming {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Proxy "";
proxy_pass http://streaming;
proxy_buffering off;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
tcp_nodelay on;
}
error_page 500 501 502 503 504 /500.html;
}