ultisuite-backend/deploy/nginx/default.conf.template
R3D347HR4Y 556d5f416d Enhance API and configuration for contact discovery and public sharing
- Introduced new endpoints for contact discovery, including scanning, listing, and managing discovered contacts.
- Implemented retry logic for handling missing DAV credentials during contact operations.
- Added public share functionality for drive API, allowing users to manage public shares, including upload, delete, and rename operations.
- Updated Nextcloud configuration to support public share links and improved error handling for public share permissions.
- Enhanced logging and validation across contact and drive APIs for better error tracking and user feedback.
- Added tests for new contact matching and ranking functionalities to ensure accuracy and reliability.
2026-06-06 20:27:02 +02:00

388 lines
14 KiB
Plaintext

# Edge reverse proxy — single entry point (replaces Caddy).
# Optional upstreams use Docker DNS resolver so nginx starts even if a module is disabled.
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Reflect browser Origin for cross-origin API calls (web app on :3000, API on :80).
map $http_origin $cors_allow_origin {
default $http_origin;
'' '*';
}
server {
listen 80;
server_name ${DOMAIN};
client_max_body_size 10G;
# ultid API (must stay after ^~ /api/auth/ — mail OIDC routes)
location /api/ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $ultid_upstream ultid:8080;
proxy_hide_header Access-Control-Allow-Origin;
proxy_hide_header Access-Control-Allow-Methods;
proxy_hide_header Access-Control-Allow-Headers;
proxy_hide_header Access-Control-Expose-Headers;
proxy_hide_header Access-Control-Max-Age;
proxy_hide_header Access-Control-Allow-Credentials;
proxy_hide_header Vary;
add_header Access-Control-Allow-Origin $cors_allow_origin always;
add_header Access-Control-Allow-Methods "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Accept, Authorization, Content-Type, Idempotency-Key, Origin, X-Requested-With, X-Trace-Id" always;
add_header Access-Control-Expose-Headers "X-Trace-Id" always;
add_header Access-Control-Max-Age 300 always;
add_header Vary Origin always;
proxy_pass http://$ultid_upstream;
proxy_http_version 1.1;
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;
}
location /ws {
resolver 127.0.0.11 valid=10s ipv6=off;
set $ultid_ws_upstream ultid:8080;
proxy_hide_header Access-Control-Allow-Origin;
add_header Access-Control-Allow-Origin $cors_allow_origin always;
add_header Vary Origin always;
proxy_pass http://$ultid_ws_upstream;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
}
# Ultimail OIDC post-login — before Authentik /auth/ (path collision)
location ^~ /auth/complete {
resolver 127.0.0.11 valid=10s ipv6=off;
set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
proxy_pass http://$mail_upstream;
proxy_http_version 1.1;
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 Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location /auth/ {
proxy_pass http://authentik-server:9000;
proxy_http_version 1.1;
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 Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 86400;
}
location /meet/ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $jitsi_upstream jitsi-web;
rewrite ^/meet/(.*)$ /$1 break;
proxy_pass http://$jitsi_upstream;
proxy_http_version 1.1;
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;
}
# Public Nextcloud share links → UltiDrive viewer
location ~ ^/cloud/index\.php/s/([^/]+)/?(.*)$ {
return 301 /drive/s/$1$is_args$args;
}
location /cloud/ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $nc_upstream nextcloud;
rewrite ^/cloud/(.*)$ /$1 break;
proxy_pass http://$nc_upstream;
proxy_http_version 1.1;
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;
}
location = /cloud {
return 301 /cloud/;
}
# OnlyOffice fetches Nextcloud after StorageUrl host rewrite (URLs lack /cloud prefix).
location ^~ /index.php {
resolver 127.0.0.11 valid=10s ipv6=off;
set $nc_upstream nextcloud;
proxy_pass http://$nc_upstream;
proxy_http_version 1.1;
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_read_timeout 300s;
}
location /office/ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $oo_upstream onlyoffice;
rewrite ^/office/(.*)$ /$1 break;
proxy_pass http://$oo_upstream;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host/office;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
}
location = /office {
return 301 /office/;
}
# UltiDrive — variable proxy_pass must not include a URI path (passes client URI as-is).
location ^~ /drive/api/auth/ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $drive_upstream ${DRIVE_FRONTEND_UPSTREAM};
rewrite ^/drive/api/auth/(.*)$ /api/auth/$1 break;
proxy_pass http://$drive_upstream;
proxy_http_version 1.1;
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;
}
location ^~ /drive/_next/ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $drive_upstream ${DRIVE_FRONTEND_UPSTREAM};
proxy_pass http://$drive_upstream;
proxy_http_version 1.1;
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 Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
# Next.js dev-only assets (no /drive prefix in generated URLs with assetPrefix-only setup)
location ^~ /__nextjs_font/ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $drive_upstream ${DRIVE_FRONTEND_UPSTREAM};
proxy_pass http://$drive_upstream;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
location = /__nextjs_original-stack-frames {
resolver 127.0.0.11 valid=10s ipv6=off;
set $drive_upstream ${DRIVE_FRONTEND_UPSTREAM};
proxy_pass http://$drive_upstream;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ^~ /__nextjs_source-map {
resolver 127.0.0.11 valid=10s ipv6=off;
set $drive_upstream ${DRIVE_FRONTEND_UPSTREAM};
proxy_pass http://$drive_upstream;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ^~ /drive/login {
resolver 127.0.0.11 valid=10s ipv6=off;
set $drive_upstream ${DRIVE_FRONTEND_UPSTREAM};
rewrite ^/drive/login(.*)$ /login$1 break;
proxy_pass http://$drive_upstream;
proxy_http_version 1.1;
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 Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location ^~ /drive/auth/complete {
resolver 127.0.0.11 valid=10s ipv6=off;
set $drive_upstream ${DRIVE_FRONTEND_UPSTREAM};
rewrite ^/drive/auth/complete(.*)$ /auth/complete$1 break;
proxy_pass http://$drive_upstream;
proxy_http_version 1.1;
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 Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location /drive/ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $drive_upstream ${DRIVE_FRONTEND_UPSTREAM};
proxy_pass http://$drive_upstream;
proxy_http_version 1.1;
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 Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location = /drive {
resolver 127.0.0.11 valid=10s ipv6=off;
set $drive_upstream ${DRIVE_FRONTEND_UPSTREAM};
proxy_pass http://$drive_upstream;
proxy_http_version 1.1;
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 Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
# Ultimail frontend — dev: pnpm dev on host (MAIL_FRONTEND_UPSTREAM=host.docker.internal:3000)
# Prod: set MAIL_FRONTEND_UPSTREAM=ultimail:3000 when the container exists.
location ^~ /api/auth/ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
proxy_pass http://$mail_upstream;
proxy_http_version 1.1;
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;
}
location ^~ /mail/ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
proxy_pass http://$mail_upstream;
proxy_http_version 1.1;
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 Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
# Do not 301 /mail → /mail/ (Next 308 /mail/ → /mail causes a redirect loop).
location = /mail {
resolver 127.0.0.11 valid=10s ipv6=off;
set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
proxy_pass http://$mail_upstream;
proxy_http_version 1.1;
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 Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location = /mail/ {
return 302 /mail/inbox;
}
location ^~ /login {
resolver 127.0.0.11 valid=10s ipv6=off;
set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
proxy_pass http://$mail_upstream;
proxy_http_version 1.1;
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 Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location ^~ /contacts {
resolver 127.0.0.11 valid=10s ipv6=off;
set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
proxy_pass http://$mail_upstream;
proxy_http_version 1.1;
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 Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location ^~ /_next/ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
proxy_pass http://$mail_upstream;
proxy_http_version 1.1;
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 Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location ^~ /brand/ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
proxy_pass http://$mail_upstream;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ^~ /mail-backgrounds/ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
proxy_pass http://$mail_upstream;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Public assets at repo root (launcher icons, etc.)
location ~* ^/[^/]+\.(svg|png|ico|webp)$ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
proxy_pass http://$mail_upstream$request_uri;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
location = / {
return 302 /mail/inbox;
}
location / {
default_type text/plain;
return 404 "Not found\n";
}
}