Nginx reverse proxy trouble

Hi,

I recently installed Seafile on Debian 12 following the docs (no docker) and it looks correct. I can log in and browse, etc.

Then I followed the docs to set up a reverse proxy in nginx. The only variance is that I used an existing host with nginx rather than the seafile host. When I visit https//files.mydomain.com/ the login screen has no structure:

The other problem is that when I log in I get the error

Forbidden (403)

CSRF verification failed. Request aborted.

I have searched and read a few posts about this error but still haven’t found a solution for this problem.

nginx config file looks like this:

log_format seafileformat '$http_x_forwarded_for $remote_addr [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_response_time';

server {
    listen 443 ssl;
    ssl_certificate		/etc/ssl/server_chain.pem;
    ssl_certificate_key		/etc/ssl/private/server.key;
    server_name			files.mydomain.com;
    server_tokens		off;

    location / {
	proxy_pass		http://10.5.21.101:8000;
	proxy_set_header	Host $http_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-Host $server_name;
	proxy_read_timeout	1200s;
	proxy_set_header	X-Forwarded-Proto https;

	# used for view/edit office file via Office Online Server
	client_max_body_size 1G;

	access_log		/var/log/nginx/seahub.access.log seafileformat;
	error_log		/var/log/nginx/seahub.error.log;
    }

    location /seafhttp {
        rewrite ^/seafhttp(.*)$ $1 break;
        proxy_pass		http://10.5.21.101:8082;
        client_max_body_size	1G;
        proxy_set_header	X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_connect_timeout	36000s;
        proxy_read_timeout	36000s;
        proxy_send_timeout	36000s;
	proxy_request_buffering off;

        send_timeout		36000s;

        access_log	/var/log/nginx/seafhttp.access.log seafileformat;
        error_log	/var/log/nginx/seafhttp.error.log;
    }
    location /media {
        root /opt/seafile/seafile-server-latest/seahub;
    }
}

server {
	listen 80;
	server_name		files.mydomain.com;
	return			301	https://files.mydomain.com$request_uri;

	server_tokens off;      # Prevents the Nginx version from being displayed in the HTTP response header
}

seahub_settings.py like this:

# -*- coding: utf-8 -*-
SECRET_KEY = "secret"
SERVICE_URL = "https://files.mydomain.com"
FILE_SERVER_ROOT = 'https://files.mydomain.com/seafhttp'
CSRF_TRUSTED_ORIGINS = 'https://files.mydomain.com'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'seahub_db',
        'USER': 'seafile',
        'PASSWORD': 'also.secret',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'OPTIONS': {'charset': 'utf8mb4'},
    }
}

What did I do wrong?

I found a handy guide in the forum by user Nightshade. After implementing the recommended changes and reloading https//files.mydomain.com/ I just get “Internal Server Error”, so less functional than before. I will see if the logs give any insight.

Edit: seahub.error.log is empty on the nginx host. seahub.access.log is almost as uninteresting:

- x.x.x.x [23/Sep/2024:09:19:13 -0600] "GET / HTTP/2.0" 500 141 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0" 0.042
- x.x.x.x [23/Sep/2024:09:19:14 -0600] "GET /favicon.ico HTTP/2.0" 500 141 "https://files.mydomain.com/" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0" 0.030

The logs in /opt/seafile/logs/ don’t appear to even get touched when loading the page, although I can see traffic between the two hosts on port 8000 when I get the error, so I’m not sure where to go with this.

I changed “daemon = True” to “False” in gunicorn.py and ran seahub.sh start and got this error:

  File "/opt/seafile/seafile-server-11.0.12/seahub/seahub/urls.py", line 865
    urlpatterns += [
IndentationError: unexpected indent

This is interesting because line 865 in that file is the line after the section I inserted according to Nightshade’s instructions:

854: if settings.SERVE_STATIC:
855:     from django.views.static import serve as static_view
856: ### — Original code
857: #media_url = settings.MEDIA_URL.strip('/')
858: ### — Begin new code for external nginx
859: media_url = settings.MEDIA_URL
860: site_root = settings.SITE_ROOT
861: if media_url.startswith(site_root):
862:     media_url = media_url[len(site_root):]
863: media_url = media_url.strip('/')
864: ## — End new code
865:    urlpatterns += [
866:        re_path(r'^%s/(?P<path>.*)$' % (media_url), static_view,
867:            {'document_root': settings.MEDIA_ROOT}),
868:    ]

So I guess maybe there was a problem with my paste job, or these instructions are no longer valid for Seafile 11. Is there a plan on the roadmap to include documentation for using an external reverse proxy with Seafile? Seems like a fairly important function for users who don’t run everything on one server.

I found deleting 4 spaces from the beginning of lines 865-868 in the urls.py file and restarting the seahub service resolved the Internal Server Error and I now see a normal login screen, so I consider this resolved.

The affected lines now look like this:

865: urlpatterns += [
866:     re_path(r'^%s/(?P<path>.*)$' % (media_url), static_view,
867:         {'document_root': settings.MEDIA_ROOT}),
868: ]

I’ll start a new thread for the CSRF error.