# RayMail — @@DOMAIN@@ # Proxies to the RayMail web container on 127.0.0.1:3880. # Stalwart's admin/JMAP port (3881) is deliberately NOT exposed here; the web # app reaches it over the internal docker network instead. ServerName @@DOMAIN@@ Alias /.well-known/acme-challenge/ /var/www/letsencrypt/.well-known/acme-challenge/ Require all granted ProxyPass /.well-known/acme-challenge/ ! RewriteEngine on RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/ RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] ServerName @@DOMAIN@@ ProxyPreserveHost On # WebSocket upgrade — JMAP push + live telemetry stream RewriteEngine on RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteCond %{HTTP:Connection} upgrade [NC] RewriteRule ^/?(.*) "ws://127.0.0.1:3880/$1" [P,L] ProxyPass / http://127.0.0.1:3880/ ProxyPassReverse / http://127.0.0.1:3880/ ProxyTimeout 120 # The reader iframe is sandboxed in-app; these harden the shell around it. Header always set X-Content-Type-Options "nosniff" Header always set Referrer-Policy "strict-origin-when-cross-origin" Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" SSLEngine on SSLCertificateFile /etc/letsencrypt/live/@@DOMAIN@@/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/@@DOMAIN@@/privkey.pem ErrorLog ${APACHE_LOG_DIR}/raymail-error.log CustomLog ${APACHE_LOG_DIR}/raymail-access.log combined