Gracias: puedo confirmar que la fuente autenticada en sí se está generando correctamente ahora de mi lado.
El problema restante parece ser la compatibilidad del cliente: ni Google Calendar ni Outlook parecen contentos de suscribirse directamente a una fuente ICS autenticada en esta forma, por lo que por ahora planeo evitarlo colocando un proxy inverso Nginx a nivel de host delante de mi instalación de Discourse en un solo contenedor y sirviendo un archivo .ics simple allí en su lugar.
Dado que estoy en la configuración estándar de contenedor único, creo que esto significa quitar los puertos 80/443 del contenedor, haciendo que Discourse escuche en un puerto interno alto, y luego hacer que Nginx del host proxifique el foro y también sirva una ruta de archivo de calendario estático.
Aproximadamente, los comandos que espero usar son:
# 1. Instalar nginx del host + certbot
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. Detener el contenedor de Discourse para liberar los puertos 80/443
cd /var/discourse
sudo ./launcher stop app
# 3. Editar la configuración del contenedor para que Discourse ya no se vincule directamente a 80/443
sudo nano /var/discourse/containers/app.yml
Luego, en app.yml, cambie la sección expose de:
expose:
- "80:80"
- "443:443"
a algo como:
expose:
- "127.0.0.1:8080:80"
y, si está presente, elimine las plantillas SSL/Let’s Encrypt del contenedor para que la terminación TLS se realice en el proxy inverso del host en su lugar.
Luego reconstruir:
cd /var/discourse
sudo ./launcher rebuild app
Luego crear un sitio Nginx a nivel de host como:
sudo nano /etc/nginx/sites-available/discourse
con algo parecido a:
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";
}
}
Habilitarlo y recargar:
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
Luego obtener un certificado Let’s Encrypt con Certbot y dejar que actualice la configuración de Nginx:
sudo certbot --nginx -d forum.example.com
sudo nginx -t
sudo systemctl reload nginx
Después de eso, la configuración de Nginx típicamente incluirá un bloque de servidor HTTPS también, por ejemplo:
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";
}
}
En ese momento, puedo usar un script/temporizador en el host para obtener el ICS de Discourse autenticado y escribir:
/var/www/private-calendar/ethan.ics
al cual Google Calendar / Outlook puede suscribirse como una URL ICS pública normal.
Así que desde mi punto de vista, el lado de Discourse parece resuelto ahora; la brecha práctica restante es en su mayor parte que los clientes de calendario importantes no manejan bien las fuentes ICS autenticadas, razón por la cual estoy recurriendo a un enfoque de proxy público/archivo estático por ahora.
También asumo que Certbot es la ruta más simple aquí, ya que puede administrar la emisión/renovación de Let’s Encrypt directamente contra Nginx del host. También podría usar acme.sh, pero mi impresión es que sería más una elección manual que el camino más sencillo para esta configuración específica.