Wie installiere ich Mastodon Social Network auf Debian 12
Mastodon ist ein freies, dezentrales und quelloffenes soziales Netzwerk. Es wurde als Alternative zu Twitter entwickelt. Genau wie bei Twitter können sich Menschen gegenseitig folgen und Nachrichten, Bilder und Videos posten. Aber anders als bei Twitter gibt es keinen zentralen Speicher oder eine Autorität für die Inhalte.
Stattdessen arbeitet Mastodon mit Tausenden von verschiedenen Servern, die von verschiedenen Mitgliedern der Community betrieben werden. Nutzer/innen, die sich auf einem Server angemeldet haben, können sich ganz einfach mit Nutzer/innen auf einem anderen Netzwerk verbinden und sich gegenseitig folgen.
Jeder kann seine eigene Instanz eines Mastodon-Servers installieren. In dieser Anleitung lernst du, wie du deine Mastodon-Instanz auf einem Server mit Debian 12 mit Docker einrichtest. Docker erleichtert die Installation von Mastodon, da alle benötigten Pakete und Dienste in Containern enthalten sind.
Voraussetzungen
- Ein Server mit Debian 12 mit mindestens 2 CPU-Kernen und 2 GB Arbeitsspeicher. Du musst den Server entsprechend deinen Anforderungen aufrüsten.
- Ein Nicht-Root-Benutzer mit sudo-Rechten.
- Einen vollständig qualifizierten Domainnamen (FQDN), der auf deinen Server verweist. Für unsere Zwecke verwenden wir
mastodon.example.com
als Domänennamen. - Mastodon sendet E-Mail-Benachrichtigungen an die Benutzer. Wir empfehlen dir, einen Transaktions-E-Mail-Dienst eines Drittanbieters wie Mailgun, SendGrid, Amazon SES oder Sparkpost zu verwenden. Die Anweisungen in diesem Leitfaden beziehen sich auf Amazon SES.
- Stelle sicher, dass alles auf dem neuesten Stand ist.
$ sudo apt update
- Installiere grundlegende Hilfspakete. Einige davon sind vielleicht schon installiert.
$ sudo apt install curl wget nano software-properties-common dirmngr apt-transport-https ca-certificates lsb-release debian-archive-keyring gnupg2 ufw unzip -y
Schritt 1 – Firewall konfigurieren
Der erste Schritt besteht darin, die Firewall zu konfigurieren. Debian wird standardmäßig mit ufw (Uncomplicated Firewall) ausgeliefert.
Überprüfe, ob die Firewall läuft.
$ sudo ufw status
Du solltest die folgende Ausgabe erhalten.
Status: inactive
Erlaube den SSH-Port, damit die Firewall die aktuelle Verbindung nicht unterbricht, wenn du sie aktivierst.
$ sudo ufw allow OpenSSH
Lasse auch HTTP- und HTTPS-Ports zu.
$ sudo ufw allow http $ sudo ufw allow https
Aktiviere die Firewall
$ sudo ufw enable Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup
Überprüfe den Status der Firewall erneut.
$ sudo ufw status
Du solltest eine ähnliche Ausgabe sehen.
Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 80/tcp ALLOW Anywhere 443 ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) 80/tcp (v6) ALLOW Anywhere (v6) 443 (v6) ALLOW Anywhere (v6)
Schritt 2 – Installiere Docker und Docker Compose
Debian 12 wird mit einer älteren Version von Docker ausgeliefert. Um die neueste Version zu installieren, importiere zunächst den Docker GPG-Schlüssel.
$ sudo install -m 0755 -d /etc/apt/keyrings $ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg $ sudo chmod a+r /etc/apt/keyrings/docker.gpg
Erstelle die Docker-Repository-Datei.
$ echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Aktualisiere die Liste der System-Repositorys.
$ sudo apt update
Installiere die neueste Version von Docker.
$ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Überprüfe, ob sie läuft.
$ sudo systemctl status docker ? docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; preset: enabled) Active: active (running) since Mon 2024-01-01 09:00:14 UTC; 17s ago TriggeredBy: ? docker.socket Docs: https://docs.docker.com Main PID: 1839 (dockerd) Tasks: 9 Memory: 27.6M CPU: 598ms CGroup: /system.slice/docker.service ??1839 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Docker erfordert standardmäßig Root-Rechte. Wenn du vermeiden willst, dass du jedes Mal sudo
verwendest, wenn du den Befehl docker
ausführst, füge deinen Benutzernamen der Gruppe docker
hinzu.
$ sudo usermod -aG docker $(whoami)
Um diese Änderung zu aktivieren, musst du dich vom Server abmelden und als derselbe Benutzer wieder anmelden oder den folgenden Befehl verwenden.
$ su - ${USER}
Bestätige, dass dein Benutzer der Docker-Gruppe hinzugefügt wurde.
$ groups navjot sudo users docker
Schritt 3 – Vorbereitungen für die Installation
Das Standardlimit für die mmap-Anzahl ist für Elasticsearch sehr niedrig. Führe den folgenden Befehl aus, um den Standardwert zu überprüfen.
$ sudo sysctl vm.max_map_count
Du erhältst die folgende Ausgabe.
vm.max_map_count = 65530
Erhöhe den Wert mit den folgenden Befehlen.
$ echo "vm.max_map_count=262144" | sudo tee /etc/sysctl.d/90-max_map_count.conf vm.max_map_count=262144 $ sudo sysctl --load /etc/sysctl.d/90-max_map_count.conf vm.max_map_count=262144
Schritt 4 – Mastodon installieren
Verzeichnisse erstellen und Besitzverhältnisse festlegen
Erstelle Verzeichnisse für Mastodon und die zugehörigen Dienste.
$ sudo mkdir -p /opt/mastodon/database/{postgresql,pgbackups,redis,elasticsearch} $ sudo mkdir -p /opt/mastodon/web/{public,system} $ sudo mkdir -p /opt/mastodon/branding
Setze die richtigen Besitzverhältnisse für die Verzeichnisse Elasticsearch, web und backup.
$ sudo chown 991:991 /opt/mastodon/web/{public,system} $ sudo chown 1000 /opt/mastodon/database/elasticsearch $ sudo chown 70:70 /opt/mastodon/database/pgbackups
Wechsle in das Mastodon-Verzeichnis.
$ cd /opt/mastodon
Umgebungs- und Docker-Compose-Dateien erstellen
Erstelle Umgebungsdateien für die Anwendung und die Datenbank.
$ sudo touch application.env database.env
Erstelle und öffne die Docker compose Datei zur Bearbeitung.
$ sudo nano docker-compose.yml
Füge den folgenden Code in die Datei ein.
services: postgresql: image: postgres:16-alpine env_file: database.env restart: always shm_size: 512mb healthcheck: test: ['CMD', 'pg_isready', '-U', 'postgres'] volumes: - postgresql:/var/lib/postgresql/data - pgbackups:/backups networks: - internal_network redis: image: redis:7-alpine restart: always healthcheck: test: ['CMD', 'redis-cli', 'ping'] volumes: - redis:/data networks: - internal_network redis-volatile: image: redis:7-alpine restart: always healthcheck: test: ['CMD', 'redis-cli', 'ping'] networks: - internal_network elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:7.17.16 restart: always env_file: database.env environment: - cluster.name=elasticsearch-mastodon - discovery.type=single-node - bootstrap.memory_lock=true - xpack.security.enabled=true - ingest.geoip.downloader.enabled=false - "ES_JAVA_OPTS=-Xms512m -Xmx512m -Des.enforce.bootstrap.checks=true" - xpack.license.self_generated.type=basic - xpack.watcher.enabled=false - xpack.graph.enabled=false - xpack.ml.enabled=false - thread_pool.write.queue_size=1000 ulimits: memlock: soft: -1 hard: -1 nofile: soft: 65536 hard: 65536 healthcheck: test: ["CMD-SHELL", "nc -z elasticsearch 9200"] volumes: - elasticsearch:/usr/share/elasticsearch/data networks: - internal_network ports: - '127.0.0.1:9200:9200' website: image: tootsuite/mastodon:v4.2.3 env_file: - application.env - database.env command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000" restart: always depends_on: - postgresql - redis - redis-volatile - elasticsearch ports: - '127.0.0.1:3000:3000' networks: - internal_network - external_network healthcheck: test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:3000/health || exit 1'] volumes: - uploads:/mastodon/public/system shell: image: tootsuite/mastodon:v4.2.3 env_file: - application.env - database.env command: /bin/bash restart: "no" networks: - internal_network - external_network volumes: - uploads:/mastodon/public/system - static:/static streaming: image: tootsuite/mastodon:v4.2.3 env_file: - application.env - database.env command: node ./streaming restart: always depends_on: - postgresql - redis - redis-volatile - elasticsearch ports: - '127.0.0.1:4000:4000' networks: - internal_network - external_network healthcheck: test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1'] sidekiq: image: tootsuite/mastodon:v4.2.3 env_file: - application.env - database.env command: bundle exec sidekiq restart: always depends_on: - postgresql - redis - redis-volatile - website networks: - internal_network - external_network healthcheck: test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"] volumes: - uploads:/mastodon/public/system networks: external_network: internal_network: internal: true volumes: postgresql: driver_opts: type: none device: /opt/mastodon/database/postgresql o: bind pgbackups: driver_opts: type: none device: /opt/mastodon/database/pgbackups o: bind redis: driver_opts: type: none device: /opt/mastodon/database/redis o: bind elasticsearch: driver_opts: type: none device: /opt/mastodon/database/elasticsearch o: bind uploads: driver_opts: type: none device: /opt/mastodon/web/system o: bind static: driver_opts: type: none device: /opt/mastodon/web/public o: bind
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Zum Zeitpunkt der Erstellung dieses Tutorials ist die neueste Version von Mastodon v4.2.3 verfügbar. Schau auf der Mastodon GitHub Releases Seite nach und passe die Version in der Docker Compose Datei entsprechend an. Wir verwenden auch die neuesten Versionen von PostgreSQL und Redis. Du kannst sie nach deinen Anforderungen anpassen. Wir verwenden im Moment Elasticsearch 7.17.16.
Anwendungsgeheimnisse erstellen
Der nächste Schritt ist die Erstellung der Anwendungsgeheimnisse.
Erstelle die Werte SECRET_KEY_BASE
und OTP_SECRET
, indem du den folgenden Befehl zweimal ausführst. Das erste Mal wird einige Zeit in Anspruch nehmen, da es die Images zieht.
$ docker compose run --rm shell bundle exec rake secret 349623c049e3b856f6848638146e459857862b908ed387bbef372a30d9bd7c604fc4de5338addc86bd369a99d38ef59bacfa28e02a1750f7094ea6ede05457b8
Du kannst dafür auch das Dienstprogramm openssl
verwenden.
$ openssl rand -hex 64 ae01cf7d4dfae0182461a1345f1f2bf159658a27339ffafe7d356bef9ee8d4fa015ab2e72a608f236bd8e3f9b2af2dcb1d55ee5c8e43646959112c7da5582f4b
Erstelle die Werte VAPID_PRIVATE_KEY
und VAPID_PUBLIC_KEY
, indem du den folgenden Befehl ausführst.
$ docker compose run --rm shell bundle exec rake mastodon:webpush:generate_vapid_key
Du wirst eine ähnliche Ausgabe erhalten.
VAPID_PRIVATE_KEY=u2qsCs5JdmdmMLnUuU0sgmFGvZedteJz-lFB_xF4_ac= VAPID_PUBLIC_KEY=BJXjE2hIXvFpo6dnHqyf1i-2PcP-cBoL95UCmhhxwlAgtFw_vnrYp4GBneR7_cmI9LZUYjHFh-TBAPSb9WTqH9A=
Verwende das Dienstprogramm openssl
, um PostgreSQL- und Elasticsearch-Passwörter zu generieren.
$ openssl rand -hex 15 dd0bd7a95960623ed8e084a1fb7d5c $ openssl rand -hex 15 0fb52834c991b5e296c647166185bc
Mastodon Umgebungsdateien
Öffne die Datei application.env
zum Bearbeiten.
$ sudo nano application.env
Füge die folgenden Zeilen in die Datei ein.
# environment RAILS_ENV=production NODE_ENV=production # domain LOCAL_DOMAIN=mastodon.example.com # redirect to the first profile SINGLE_USER_MODE=false # do not serve static files RAILS_SERVE_STATIC_FILES=false # concurrency WEB_CONCURRENCY=2 MAX_THREADS=5 # pgbouncer #PREPARED_STATEMENTS=false # locale DEFAULT_LOCALE=en # email, not used SMTP_SERVER=email-smtp.us-west-2.amazonaws.com SMTP_PORT=587 SMTP_LOGIN=AKIA3FIG4NVFB343PZEI SMTP_PASSWORD=AZX01WiA6JGbeZ2pwVXnyC9DhEa2nKcmXSu/zbLp SMTP_FROM_ADDRESS=noreply@nspeaks.com # secrets SECRET_KEY_BASE=349623c049e3b856f6848638146e459857862b908ed387bbef372a30d9bd7c604fc4de5338addc86bd369a99d38ef59bacfa28e02a1750f7094ea6ede05457b8 OTP_SECRET=ae01cf7d4dfae0182461a1345f1f2bf159658a27339ffafe7d356bef9ee8d4fa015ab2e72a608f236bd8e3f9b2af2dcb1d55ee5c8e43646959112c7da5582f4b # Changing VAPID keys will break push notifications VAPID_PRIVATE_KEY=oNe_4BEL7Tpc3iV8eMtLegfLwrzA7ifitGJ2YOg3dUM= VAPID_PUBLIC_KEY=BKBgmB90vIrJg6Ifq3cCHixalyPghJDkui9vm1wscxvAfNNoAQL0KinoxRTLDp0UFlGK_ahUG2n4W2n4x9AUAWM= # IP and session retention # ----------------------- # Make sure to modify the scheduling of ip_cleanup_scheduler in config/sidekiq.yml # to be less than daily if you lower IP_RETENTION_PERIOD below two days (172800). # ----------------------- IP_RETENTION_PERIOD=2592000 SESSION_RETENTION_PERIOD=2592000
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Wir haben den Amazon SES-Versanddienst aktiviert. Wenn du ihn nicht brauchst, kannst du den Abschnitt löschen. Standardmäßig speichert Mastodon eine IP-Adresse für 1 Jahr, aber wir haben sie auf 30 Tage (2592000 Sekunden) geändert. Du kannst sie nach deinen Bedürfnissen ändern. Achte darauf, dass du sie länger als 2 Tage speicherst, sonst musst du ein bisschen mehr basteln, was den Rahmen dieses Tutorials sprengen würde.
Öffne die Datei database.env
, um sie zu bearbeiten.
$ sudo nano database.env
Füge die folgenden Zeilen in die Datei ein.
# postgresql configuration POSTGRES_USER=mastodon POSTGRES_DB=mastodon POSTGRES_PASSWORD=0fb52834c991b5e296c647166185bc PGPASSWORD=0fb52834c991b5e296c647166185bc PGPORT=5432 PGHOST=postgresql PGUSER=mastodon # pgbouncer configuration #POOL_MODE=transaction #ADMIN_USERS=postgres,mastodon #DATABASE_URL="postgres://mastodon:0fb52834c991b5e296c647166185bc@postgresql:5432/mastodon" # elasticsearch ELASTIC_PASSWORD=dd0bd7a95960623ed8e084a1fb7d5c # mastodon database configuration #DB_HOST=pgbouncer DB_HOST=postgresql DB_USER=mastodon DB_NAME=mastodon DB_PASS=0fb52834c991b5e296c647166185bc DB_PORT=5432 REDIS_HOST=redis REDIS_PORT=6379 CACHE_REDIS_HOST=redis-volatile CACHE_REDIS_PORT=6379 ES_ENABLED=true ES_HOST=elasticsearch ES_PORT=9200 ES_USER=elastic ES_PASS=dd0bd7a95960623ed8e084a1fb7d5c
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Mastodon vorbereiten
Bereite die statischen Dateien vor, damit sie von Nginx bedient werden können. Dieser Schritt wird einige Zeit in Anspruch nehmen, da Docker alle Images zum ersten Mal abruft.
$ docker compose run --rm shell bash -c "cp -r /opt/mastodon/public/* /static/"
Bringe die Datenschicht hoch.
$ docker compose up -d postgresql redis redis-volatile
Überprüfe den Status der Container.
$ watch docker compose ps
Warte auf running (healthy)
, drücke dann Ctrl + C
und initialisiere die Datenbank mit dem folgenden Befehl.
$ docker compose run --rm shell bundle exec rake db:setup
Wenn du die Fehlermeldung erhältst, dass die Datenbank mastodon
bereits existiert, führe den folgenden Befehl aus.
$ docker compose run --rm shell bundle exec rake db:migrate
Schritt 5 – Nginx installieren
Debian 12 wird mit einer älteren Version von Nginx ausgeliefert. Um die neueste Version zu installieren, musst du das offizielle Nginx-Repository herunterladen.
Importiere den Signierschlüssel von Nginx.
$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \ | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
Füge das Repository für die Mainline-Version von Nginx hinzu.
$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \ http://nginx.org/packages/mainline/debian `lsb_release -cs` nginx" \ | sudo tee /etc/apt/sources.list.d/nginx.list
Aktualisiere die System-Repositories.
$ sudo apt update
Installiere Nginx.
$ sudo apt install nginx
Überprüfe die Installation. Auf Debian-Systemen brauchst du sudo
, um den folgenden Befehl auszuführen.
$ sudo nginx -v nginx version: nginx/1.25.3
Starte den Nginx-Server.
$ sudo systemctl start nginx
Überprüfe den Status des Servers.
$ sudo systemctl status nginx ? nginx.service - nginx - high performance web server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled) Active: active (running) since Mon 2024-01-01 10:17:38 UTC; 4s ago Docs: https://nginx.org/en/docs/ Process: 8972 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS) Main PID: 8973 (nginx) Tasks: 3 (limit: 4637) Memory: 2.9M CPU: 17ms CGroup: /system.slice/nginx.service ??8973 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf" ??8974 "nginx: worker process" ??8975 "nginx: worker process" Jan 01 10:17:38 mastodon systemd[1]: Starting nginx.service - nginx - high performance web server... Jan 01 10:17:38 mastodon systemd[1]: Started nginx.service - nginx - high performance web server.
Schritt 6 – SSL installieren
Wir müssen Certbot installieren, um das SSL-Zertifikat zu erstellen. Du kannst Certbot entweder über das Repository von Debian installieren oder die neueste Version mit dem Snapd-Tool herunterladen. Wir werden die Snapd-Version verwenden.
Bei Debian 12 ist Snapd noch nicht installiert. Installiere das Snapd-Paket.
$ sudo apt install snapd
Führe die folgenden Befehle aus, um sicherzustellen, dass deine Version von Snapd auf dem neuesten Stand ist. Vergewissere dich, dass deine Version von Snapd auf dem neuesten Stand ist.
$ sudo snap install core $ sudo snap refresh core
Installiere Certbot.
$ sudo snap install --classic certbot
Verwende den folgenden Befehl, um sicherzustellen, dass der Certbot-Befehl ausgeführt wird, indem du einen symbolischen Link zum Verzeichnis /usr/bin
erstellst.
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
Überprüfe die Installation.
$ certbot --version certbot 2.8.0
Führe den folgenden Befehl aus, um ein SSL-Zertifikat zu erzeugen.
$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m name@example.com -d mastodon.example.com
Mit dem obigen Befehl wird ein Zertifikat in das Verzeichnis /etc/letsencrypt/live/mastodon.example.com
auf deinem Server heruntergeladen.
Erstelle ein Diffie-Hellman-Gruppenzertifikat.
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
Überprüfe den Certbot Erneuerungszeitplanungsdienst.
$ systemctl list-timers
Du findest snap.certbot.renew.service
als einen der Dienste, die für die Ausführung vorgesehen sind.
NEXT LEFT LAST PASSED UNIT ACTIVATES ----------------------------------------------------------------------------------------------------------------------------------------- Mon 2024-01-01 20:03:52 UTC 9h left Mon 2023-12-11 21:56:24 UTC 2 weeks 6 days ago apt-daily.timer apt-daily.service Mon 2024-01-01 21:06:00 UTC 10h left - - snap.certbot.renew.timersnap.certbot.renew.service Tue 2024-01-02 00:00:00 UTC 13h left - - dpkg-db-backup.timer dpkg-db-backup.service
Führe einen Probelauf des Prozesses durch, um zu prüfen, ob die SSL-Erneuerung einwandfrei funktioniert.
$ sudo certbot renew --dry-run
Wenn du keine Fehler siehst, bist du bereit. Dein Zertifikat wird automatisch erneuert.
Schritt 7 – Nginx konfigurieren
Öffne die Datei /etc/nginx/nginx.conf
zum Bearbeiten.
$ sudo nano /etc/nginx/nginx.conf
Füge die folgende Zeile vor der Zeile include /etc/nginx/conf.d/*.conf;
ein.
server_names_hash_bucket_size 64;
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Erstelle und öffne die Datei /etc/nginx/conf.d/mastodon.conf
zum Bearbeiten.
$ sudo nano /etc/nginx/conf.d/mastodon.conf
Füge den folgenden Code in die Datei ein.
map $http_upgrade $connection_upgrade { default upgrade; '' close; } 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 default_server; server_name mastodon.example.com; location / { return 301 https://$host$request_uri; } } server { listen 443 ssl; server_name mastodon.example.com; access_log /var/log/nginx/mastodon.access.log; error_log /var/log/nginx/mastodon.error.log; http2 on; # Enable HTTP/2 - works only on Nginx 1.25.1+ ssl_certificate /etc/letsencrypt/live/mastodon.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/mastodon.example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/mastodon.example.com/chain.pem; ssl_session_timeout 1d; # Enable TLS versions (TLSv1.3 is required upcoming HTTP/3 QUIC). ssl_protocols TLSv1.2 TLSv1.3; # Enable TLSv1.3's 0-RTT. Use $ssl_early_data when reverse proxying to # prevent replay attacks. # # @see: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data ssl_early_data on; ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384'; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; keepalive_timeout 70; sendfile on; client_max_body_size 80m; # OCSP Stapling --- # fetch OCSP records from URL in ssl_certificate and cache them ssl_stapling on; ssl_stapling_verify on; ssl_dhparam /etc/ssl/certs/dhparam.pem; add_header X-Early-Data $tls1_3_early_data; root /opt/mastodon/web/public; 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; location / { try_files $uri @proxy; } location ~ ^/(system/accounts/avatars|system/media_attachments/files) { add_header Cache-Control "public, max-age=31536000, immutable"; add_header Strict-Transport-Security "max-age=31536000" always; root /opt/mastodon/; try_files $uri @proxy; } location ~ ^/(emoji|packs) { add_header Cache-Control "public, max-age=31536000, immutable"; add_header Strict-Transport-Security "max-age=31536000" always; try_files $uri @proxy; } location /sw.js { add_header Cache-Control "public, max-age=0"; add_header Strict-Transport-Security "max-age=31536000" always; try_files $uri @proxy; } 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; } 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; } # This block is useful for debugging TLS v1.3. Please feel free to remove this # and use the `$ssl_early_data` variable exposed by NGINX directly should you # wish to do so. map $ssl_early_data $tls1_3_early_data { "~." $ssl_early_data; default ""; }
Wenn du fertig bist, speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Überprüfe die Syntax der Nginx-Konfigurationsdatei.
$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Starte den Nginx-Server neu.
$ sudo systemctl restart nginx
Schritt 8 – Mastodon starten
Tootctl CLI-Tool
Das Tootctl CLI-Tool wird verwendet, um administrative Aufgaben auf Mastodon durchzuführen. Wir müssen es auf der Host-Shell zugänglich machen.
Erstelle die Datei /usr/local/bin/tootctl
und öffne sie zum Bearbeiten.
$ sudo nano /usr/local/bin/tootctl
Füge den folgenden Code in die Datei ein.
#!/bin/bash docker compose -f /opt/mastodon/docker-compose.yml run --rm shell tootctl "$@"
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Erteile der Datei die Berechtigung zur Ausführung.
$ sudo chmod +x /usr/local/bin/tootctl
Mastodon-Dienstdatei
Du kannst die Mastodon-Container mit dem Docker-Befehl compose starten, aber es ist einfacher, dies über eine systemd Unit-Datei zu tun.
Erstelle und öffne die Mastodon-Dienstdatei zum Bearbeiten.
$ sudo nano /etc/systemd/system/mastodon.service
Füge den folgenden Code in die Datei ein.
[Unit] Description=Mastodon service After=docker.service [Service] Type=oneshot RemainAfterExit=yes WorkingDirectory=/opt/mastodon ExecStart=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml up -d ExecStop=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml down [Install] WantedBy=multi-user.target
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Lade den Systemdaemon neu, um die Servicedatei zu starten.
$ sudo systemctl daemon-reload
Aktiviere und starte den Mastodon-Dienst.
$ sudo systemctl enable --now mastodon.service
Überprüfe den Status der Docker-Container.
$ watch docker compose -f /opt/mastodon/docker-compose.yml ps
Sobald der Status der Container auf running (healthy)
wechselt, verlasse den Bildschirm, indem du Strg + C drückst.
Erstelle den Benutzer admin für Mastodon und notiere dir das angegebene Passwort.
$ tootctl accounts create navjot --email name@example.com --confirmed --role Owner OK New password: 1338afbe1b4e06e823b6625da80cb537
Wenn du die Benutzerregistrierung schließen willst, verwende den folgenden Befehl.
$ tootctl settings registrations close
Um die Registrierungen wieder zu öffnen, gibst du den folgenden Befehl ein.
$ tootctl settings registrations open
Suche initialisieren
Bevor du Elasticsearch-Indizes erstellen und befüllen kannst, musst du ein Toot erstellen. Sobald du ein Toot erstellt hast, gibst du den folgenden Befehl ein.
$ tootctl search deploy
Möglicherweise bekommst du die folgende Fehlermeldung.
/opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/progress.rb:76:in `total=': You can't set the item's total value to less than the current progress. (ProgressBar::InvalidProgressError) from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/base.rb:178:in `block in update_progress' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/output.rb:43:in `with_refresh' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/base.rb:177:in `update_progress' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/base.rb:101:in `total=' from /opt/mastodon/lib/mastodon/search_cli.rb:67:in `deploy' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/invocation.rb:116:in `invoke' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor.rb:243:in `block in subcommand' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch' from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/base.rb:485:in `start' from /opt/mastodon/bin/tootctl:8:in `<main>'
In diesem Fall musst du die Shell des Website-Containers aufrufen.
$ docker exec -it mastodon-website-1 /bin/bash
Führe den folgenden Befehl aus.
$ sed -E '/progress.total = /d' -i lib/mastodon/search_cli.rb
Beende die Container-Shell.
$ exit
Führe den Befehl Elasticsearch deploy erneut aus. Manchmal funktioniert der Befehl auch zu einem späteren Zeitpunkt. Dies ist ein laufendes Problem bei Mastodon, daher gibt es im Moment noch keine endgültige Lösung.
$ tootctl search deploy Done! 1/?? |-=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=| ETA: ??:??:?? (0 docs/s) Indexed 1 records, de-indexed 0
Zusätzliche Hilfsdienste
Lass uns einen weiteren Dienst zum Entfernen heruntergeladener Mediendateien erstellen.
Erstelle und öffne den Mastodon-Medienentfernungsdienst zur Bearbeitung.
$ sudo nano /etc/systemd/system/mastodon-media-remove.service
Füge den folgenden Code in ihn ein.
[Unit] Description=Mastodon - media remove service Wants=mastodon-media-remove.timer [Service] Type=oneshot StandardError=null StandardOutput=null WorkingDirectory=/opt/mastodon ExecStart=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml run --rm shell tootctl media remove [Install] WantedBy=multi-user.target
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Wenn du die Medienentfernung zeitlich planen möchtest, kannst du einen Timer-Dienst dafür einrichten.
$ sudo nano /etc/systemd/system/mastodon-media-remove.timer
Füge den folgenden Code ein.
[Unit] Description=Schedule a media remove every week [Timer] Persistent=true OnCalendar=Sat *-*-* 00:00:00 Unit=mastodon-media-remove.service [Install] WantedBy=timers.target
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Du kannst einen weiteren Dienst einrichten, um die mit OpenGraph-Tags erstellten Rich-Vorschaukarten zu entfernen.
$ sudo nano /etc/systemd/system/mastodon-preview_cards-remove.service
Füge den folgenden Code ein.
[Unit] Description=Mastodon - preview cards remove service Wants=mastodon-preview_cards-remove.timer [Service] Type=oneshot StandardError=null StandardOutput=null WorkingDirectory=/opt/mastodon ExecStart=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml run --rm shell tootctl preview_cards remove [Install] WantedBy=multi-user.target
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Richte den entsprechenden Timer-Dienst ein.
$ sudo nano /etc/systemd/system/mastodon-preview_cards-remove.timer
Füge den folgenden Code ein.
[Unit] Description=Schedule a preview cards remove every week [Timer] Persistent=true OnCalendar=Sat *-*-* 00:00:00 Unit=mastodon-preview_cards-remove.service [Install] WantedBy=timers.target
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Lade den Systemdaemon neu.
$ sudo systemctl daemon-reload
Aktiviere und starte die Timer.
$ sudo systemctl enable --now mastodon-preview_cards-remove.timer $ sudo systemctl enable --now mastodon-media-remove.timer
Liste alle Timer auf, um den Zeitplan der Mastodon-Dienste zu überprüfen.
$ systemctl list-timers ..... Sat 2024-01-06 00:00:00 UTC 4 days left - - mastodon-media-remove.timer mastodon-media-remove.service Sat 2024-01-06 00:00:00 UTC 4 days left - - mastodon-preview_cards-remove.timer mastodon-preview_cards-remove.service
Zugriff auf Mastodon
Besuche die URL https://mastodon.example.com
, um auf deine Instanz zuzugreifen, und du wirst eine ähnliche Seite sehen.
Im obigen Screenshot kannst du sehen, dass es 0 Benutzer gibt. Das liegt daran, dass wir uns noch nicht eingeloggt haben. Auch wenn du ein Administratorkonto erstellst, wird es beim ersten Durchlauf nicht auf der Hauptseite angezeigt. Melde dich dazu in deiner Instanz an und du gelangst auf die folgende Seite.
Klicke auf die Option Einstellungen in der rechten Seitenleiste, um zu den Einstellungen zu gelangen. Klicke auf die Option Administration im linken Menü, um auf das Mastodon Administrationspanel zuzugreifen.
Klicke auf die Option Servereinstellungen in der linken Seitenleiste.
Hier gibst du deinen Kontaktbenutzernamen und deine geschäftliche E-Mail-Adresse ein, die dann auf der Startseite deines Servers angezeigt werden. Gib außerdem verschiedene andere Informationen ein, z.B. die Serverbeschreibung, das Logo und die Serverregeln, um deine Mastodon-Instanz anzupassen.
Schritt 9 – Mastodon-Wartung
Um die Leistung und die Logs deiner Mastodon-Instanz einzusehen, gehe zu https://mastodon.example.com/sidekiq/
.
Hier kannst du eine Liste verschiedener Prozesse und geplanter Aufgaben im Zusammenhang mit deiner Mastodon-Instanz einsehen. Du kannst auch nach fehlgeschlagenen Aufgaben unter dem Abschnitt Dead or Retries suchen. Hier erfährst du auch, wie viel Speicherplatz deine Instanz verbraucht.
Du kannst den Zustand der Datenbank deiner Instanz unter https://mastodon.example.com/pghero/
überprüfen.
Du kannst deine Datenbank warten, SQL-Abfragen ausführen und ungenutzte Indizes entfernen. Um die Abfragestatistik zu aktivieren, klickst du auf der oben genannten Seite auf die Schaltfläche Aktivieren und du erhältst die folgenden Informationen.
Wechsle zum Benutzer root.
$ sudo -i su
Wechsle in das Verzeichnis /opt/mastodon/database/postgresql
.
$ cd /opt/mastodon/database/postgresql
Öffne die Datei postgresql.conf
.
$ nano postgresql.conf
Suche die Zeile #shared_preload_libraries = '' # (change requires restart)
und ersetze sie durch die folgende.
shared_preload_libraries = 'pg_stat_statements'
Füge die folgende Zeile am Ende der Datei ein.
pg_stat_statements.track = all
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Starte die Mastodon-Container neu.
$ systemctl restart mastodon.service
Beende die Root-Shell.
$ exit
Wenn du auf der Seite mit dem Datenbankstatus nachschaust, kannst du sehen, ob es jetzt langsame Abfragen gibt.
Hinweis: Du kannst die PgHero- und Sidekiq-URLs auch über das Menü “ Einstellungen “ aufrufen.
Wenn deine Seite aus irgendeinem Grund nicht geladen wird, kannst du die von Docker generierten Logs überprüfen.
$ docker logs <container-name>
Schritt 10 – Mastodon sichern
Für das Backup von Mastodon verwenden wir das Drittanbieter-Tool Restic. Der erste Schritt zur Sicherung mit Restic besteht darin, alle Dateien und Verzeichnisse zur Repository-Liste hinzuzufügen.
Erstelle und öffne die Datei mit der Repository-Liste zum Bearbeiten.
$ sudo nano /opt/mastodon/backup-files
Füge die folgenden Zeilen in die Datei ein.
/etc/nginx /etc/letsencrypt /etc/systemd/system /root /opt/mastodon/database/pgbackups /opt/mastodon/*.env /opt/mastodon/docker-compose.yml /opt/mastodon/branding /opt/mastodon/database/redis /opt/mastodon/web/system /opt/mastodon/backup-files /opt/mastodon/mastodon-backup
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Installiere Restic.
$ sudo apt install restic
Erstelle ein Backup-Repository und erstelle das erste Backup. Wir sichern unsere Daten im S3-Dienst.
$ restic -r s3:https://$SERVER:$PORT/mybucket init $ restic -r s3:https://$SERVER:$PORT/mybucket backup $(cat /opt/mastodon/backup-files) --exclude /opt/mastodon/database/postgresql
Erstelle einen Mastodon Backup Service Timer und öffne ihn zur Bearbeitung.
$ sudo nano /etc/systemd/system/mastodon-backup.timer
Füge den folgenden Code in die Datei ein.
[Unit] Description=Schedule a mastodon backup every hour [Timer] Persistent=true OnCalendar=*:00:00 Unit=mastodon-backup.service [Install] WantedBy=timers.target
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Erstelle eine Mastodon-Backup-Service-Datei und öffne sie zur Bearbeitung.
$ sudo nano /etc/systemd/system/mastodon-backup.service
Füge den folgenden Code in die Datei ein.
[Unit] Description=Mastodon - backup service # Without this, they can run at the same time and race to docker compose, # double-creating networks and failing due to ambiguous network definition # requiring `docker network prune` and restarting After=mastodon.service [Service] Type=oneshot StandardError=file:/var/log/mastodon-backup.err StandardOutput=file:/var/log/mastodon-backup.log WorkingDirectory=/opt/mastodon ExecStart=/bin/bash /opt/mastodon/mastodon-backup [Install] WantedBy=multi-user.target
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Als Nächstes erstellst du die Datei /opt/mastodon/mastodon-backup
und öffnest sie zur Bearbeitung. Sie enthält die eigentlichen Backup-Befehle.
$ sudo nano /opt/mastodon/mastodon-backup
Füge den folgenden Code in die Datei ein.
#!/bin/bash set -e AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= SERVER= PORT= RESTIC_PASSWORD_FILE=/root/restic-pasword docker compose -f /opt/mastodon/docker-compose.yml run --rm postgresql sh -c "pg_dump -Fp mastodon | gzip > /backups/dump.sql.gz" restic -r s3:https://$SERVER:$PORT/mybucket --cache-dir=/root backup $(cat /opt/mastodon/backup-files) --exclude /opt/mastodon/database/postgresql restic -r s3:https://$SERVER:$PORT/mybucket --cache-dir=/root forget --prune --keep-hourly 24 --keep-daily 7 --keep-monthly 3
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Gib dem Backup-Skript Ausführungsrechte.
$ sudo chmod +x /opt/mastodon/mastodon-backup
Lade den Service Daemon neu und starte den Backup-Dienst und den Timer.
$ sudo systemctl daemon-reload $ sudo systemctl enable --now mastodon-backup.service $ sudo systemctl enable --now mastodon-backup.timer
Überprüfe mit den folgenden Befehlen, ob stündliche Backups durchgeführt werden und ob sie zugänglich sind.
$ restic -r s3:https://$SERVER:$PORT/mybucket snapshots $ restic -r s3:https://$SERVER:$PORT/mybucket mount /mnt
Schritt 11 – Upgrade von Mastodon
Das Upgrade von Mastodon erfordert mehrere Schritte. Wechsle zunächst in das Verzeichnis.
$ cd /opt/mastodon
Ziehe die neuesten Container-Images für Mastodon.
$ docker compose pull
Nimm Änderungen an der docker-compose.yml
vor, wenn du möchtest.
Führe alle Datenbankmigrationen durch.
$ docker compose run --rm shell bundle exec rake db:migrate
Aktualisiere deine Kopien der statischen Dateien.
$ docker compose run --rm shell bash -c "cp -r /opt/mastodon/public/* /static/"
Starte die Mastodon-Container neu.
$ sudo systemctl restart mastodon.service
Die obigen Anweisungen sind allgemeine Update-Anweisungen. Überprüfe immer die GitHub-Releaseseite von Mastodon, um nach speziellen Update-Aufgaben und Befehlen zwischen den Versionen zu suchen, damit alles reibungslos funktioniert.
Fazit
Damit ist unsere Anleitung zur Installation von Mastodon Social Network mit Docker auf einem Debian 12 Server abgeschlossen. Wenn du noch Fragen hast, schreibe sie in die Kommentare unten.