Issue with nginx reverse proxy
Hi :)
I am trying to reach my Radicale instance from outside with a reverse proxy https://docs.linuxserver.io/general/swag#reverse-proxy as a subfolder for my domain.
I tried using the configuration from the Radicale documentation but that not worked.
So i tried with this:
location /radicale {
return 301 $scheme://$host/radicale/;
}
location ^~ /radicale/ {
# enable the next two lines for http auth
#auth_basic "Restricted";
#auth_basic_user_file /config/nginx/.htpasswd;
# enable the next two lines for ldap auth, also customize and enable ldap.conf in the default conf
#auth_request /auth;
#error_page 401 =200 /ldaplogin;
# enable for Authelia, also enable authelia-server.conf in the default site config
#include /config/nginx/authelia-location.conf;
include /config/nginx/proxy.conf;
resolver 127.0.0.11 valid=30s;
set $upstream_app radicale;
set $upstream_port 5232;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port/;
}
With this config i can reach https://www.mydomain.org/radicale/.web but the page fails to load per too many redirects.
Any idea how could i fix this?
Thanks!
I don't know swag or something, but why are you using all the variables? You are redirecting to a host named radicale ($upstream_app) ist this working?
In nginx, simply add (or 127.0.0.11 whatever IP your radicale is listen to)
location /webdav/ { proxy_pass http://127.0.0.1:5232/; proxy_pass_header Authorization; }
Whats in "/config/nginx/proxy.conf;" and whats your radicale configuration?
The variables are there to trick nginx into not checking the url on startup, because otherwise if radicale is unavailable it'll refuse to start. proxy.conf: https://github.com/linuxserver/docker-swag/blob/master/root/defaults/proxy.conf
(i have the same issue, btw) my config:
location /radicale {
return 301 $scheme://$host/radicale/;
}
location ^~ /radicale/ {
# enable the next two lines for http auth
#auth_basic "Restricted";
#auth_basic_user_file /config/nginx/.htpasswd;
# enable the next two lines for ldap auth, also customize and enable ldap.conf in the default conf
#auth_request /auth;
#error_page 401 =200 /ldaplogin;
# enable for Authelia, also enable authelia-server.conf in the default site config
#include /config/nginx/authelia-location.conf;
auth_request /auth-4;
auth_request_set $auth_user $upstream_http_x_organizr_user;
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app radicale;
set $upstream_port 5232;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port/;
proxy_set_header X-Script-Name /radicale;
proxy_set_header X-Remote-User $auth_user;
}
# -*- mode: conf -*-
# vim:ft=cfg
# Config file for Radicale - A simple calendar server
#
# Place it into /etc/radicale/config (global)
# or ~/.config/radicale/config (user)
#
# The current values are the default ones
[server]
# CalDAV server hostnames separated by a comma
# IPv4 syntax: address:port
# IPv6 syntax: [address]:port
# For example: 0.0.0.0:9999, [::]:9999
#hosts = 127.0.0.1:5232
hosts = 0.0.0.0:5232
# Max parallel connections
#max_connections = 8
# Max size of request body (bytes)
#max_content_length = 100000000
# Socket timeout (seconds)
#timeout = 30
# SSL flag, enable HTTPS protocol
#ssl = False
# SSL certificate path
#certificate = /etc/ssl/radicale.cert.pem
# SSL private key
#key = /etc/ssl/radicale.key.pem
# CA certificate for validating clients. This can be used to secure
# TCP traffic between Radicale and a reverse proxy
#certificate_authority =
[encoding]
# Encoding for responding requests
#request = utf-8
# Encoding for storing local collections
#stock = utf-8
[auth]
# Authentication method
# Value: none | htpasswd | remote_user | http_x_remote_user
type = http_x_remote_user
# Htpasswd filename
#htpasswd_filename = /etc/radicale/users
# Htpasswd encryption method
# Value: plain | bcrypt | md5
# bcrypt requires the installation of radicale[bcrypt].
#htpasswd_encryption = md5
# Incorrect authentication delay (seconds)
#delay = 1
# Message displayed in the client when a password is needed
#realm = Radicale - Password Required
[rights]
# Rights backend
# Value: none | authenticated | owner_only | owner_write | from_file
#type = owner_only
# File for rights management from_file
#file = /etc/radicale/rights
[storage]
# Storage backend
# Value: multifilesystem
#type = multifilesystem
# Folder for storing local collections, created if not present
#filesystem_folder = /var/lib/radicale/collections
filesystem_folder = /data/collections
# Delete sync token that are older (seconds)
#max_sync_token_age = 2592000
# Command that is run after changes to storage
# Example: ([ -d .git ] || git init) && git add -A && (git diff --cached --quiet || git commit -m "Changes by "%(user)s)
#hook =
[web]
# Web interface backend
# Value: none | internal
#type = internal
[logging]
# Threshold for the logger
# Value: debug | info | warning | error | critical
#level = warning
# Don't include passwords in logs
#mask_passwords = True
[headers]
# Additional HTTP headers
#Access-Control-Allow-Origin = *
Update:
changing proxy_pass $upstream_proto://$upstream_app:$upstream_port/; to proxy_pass http://radicale:5232/; did fix it for me, but this does create the aforementioned issue of nginx refusing to start if radicale is ever down:
nginx: [emerg] host not found in upstream "radicale" in /config/nginx/proxy-conf/radicale.subfolder.conf:27
I’m not sure if this would work well with your current setup but instead of using the radicale built in server, have you tried launching it using Gunicorn as per the docs?
Gunicorn allows running Radicale through a Unix socket instead of a port (just switch the—bind section to something like —bind /tmp/radicale.sock or any other location you’d want to have it at. Then you’d proxy directly into that socket instead of 5232.
As far as I know, once the socket is created, it should still remain active if radicale goes down, meaning nginx won’t notice and shouldn’t fail on you. Again, I’m not sure if this will work for your current setup but being able to run straight through a socket (unless you’re running through a container that doesn’t support doing such) is both more secure and sometimes faster than binding to localhost.
this is the proper way to do it with runtime dns resolution
proxy_pass http://$backend:5232$request_uri;
notice there is no / before $request_uri