Danke – ich kann bestätigen, dass der authentifizierte Feed auf meiner Seite jetzt ordnungsgemäß generiert wird.
Das verbleibende Problem scheint die Client-Kompatibilität zu sein: Weder Google Kalender noch Outlook scheinen direkt ein authentifiziertes ICS-Feed in dieser Form abonnieren zu wollen. Daher plane ich vorerst, dies zu umgehen, indem ich einen Nginx Reverse Proxy auf Host-Ebene vor meiner Ein-Container-Discourse-Installation setze und dort stattdessen eine einfache .ics-Datei bereitstelle.
Da ich das Standard-Ein-Container-Setup verwende, bedeutet dies meiner Meinung nach, die Ports 80/443 vom Container zu entfernen, Discourse dazu zu bringen, auf einem internen hohen Port zu lauschen, und dann den Host-Nginx den Forum-Verkehr zu proxen und zusätzlich einen statischen Kalenderfeed-Pfad bereitzustellen.
Grob gesagt sind die Befehle, die ich voraussichtlich verwenden werde:
# 1. Host nginx + certbot installieren
sudo apt update
sudo apt install -y nginx snapd
sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -sf /snap/bin/certbot /usr/bin/certbot
# 2. Den Discourse-Container stoppen, damit die Ports 80/443 freigegeben werden können
cd /var/discourse
sudo ./launcher stop app
# 3. Die Container-Konfiguration bearbeiten, damit Discourse nicht mehr direkt an 80/443 bindet
sudo nano /var/discourse/containers/app.yml
Dann in app.yml den expose-Abschnitt ändern von:
expose:
- "80:80"
- "443:443"
auf etwas wie:
expose:
- "127.0.0.1:8080:80"
und, falls vorhanden, die Container-SSL-/Let’s Encrypt-Vorlagen entfernen, damit TLS am Host-Reverse-Proxy beendet wird.
Dann neu erstellen:
cd /var/discourse
sudo ./launcher rebuild app
Anschließend eine Nginx-Konfiguration auf Host-Ebene erstellen, z. B.:
sudo nano /etc/nginx/sites-available/discourse
mit etwas in der Art von:
server {
listen 80;
listen [::]:80;
server_name forum.example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
}
location /private-calendar/ethan.ics {
alias /var/www/private-calendar/ethan.ics;
default_type text/calendar;
add_header Content-Type "text/calendar; charset=utf-8";
}
}
Aktivieren und neu laden:
sudo mkdir -p /var/www/private-calendar
sudo mkdir -p /var/www/certbot
sudo ln -s /etc/nginx/sites-available/discourse /etc/nginx/sites-enabled/discourse
sudo nginx -t
sudo systemctl reload nginx
Dann ein Let’s Encrypt-Zertifikat mit Certbot beziehen und es die Nginx-Konfiguration aktualisieren lassen:
sudo certbot --nginx -d forum.example.com
sudo nginx -t
sudo systemctl reload nginx
Danach wird die Nginx-Konfiguration typischerweise auch einen HTTPS-Serverblock enthalten, z. B.:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name forum.example.com;
ssl_certificate /etc/letsencrypt/live/forum.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/forum.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
}
location /private-calendar/ethan.ics {
alias /var/www/private-calendar/ethan.ics;
default_type text/calendar;
add_header Content-Type "text/calendar; charset=utf-8";
}
}
Zu diesem Zeitpunkt kann ich ein Skript/einen Timer auf dem Host verwenden, um den authentifizierten Discourse ICS abzurufen und in folgende Datei zu schreiben:
/var/www/private-calendar/ethan.ics
worauf Google Kalender/Outlook dann als normale öffentliche ICS-URL abonnieren können.
Aus meiner Sicht ist die Discourse-Seite also jetzt gelöst; die verbleibende praktische Lücke ist hauptsächlich, dass große Kalenderclients authentifizierte ICS-Feeds nicht besonders gut verarbeiten, weshalb ich vorerst auf einen öffentlichen Proxy-/Static-File-Ansatz zurückgreife.
Ich gehe auch davon aus, dass Certbot der einfachste Weg ist, da es die Ausstellung/Erneuerung von Let’s Encrypt direkt gegen den Host Nginx verwalten kann. Ich könnte auch acme.sh verwenden, aber mein Eindruck ist, dass dies bei diesem speziellen Setup eher eine manuelle Wahl wäre als der direkteste Weg.