Good evening everyone,
I installed seafile-docker on a raspi5 as a home server. The docker container contains a nginx reverse proxy that splits the traffic for seahub and seafhttp. Everything is working fine, but now I want to use another nginx reverse proxy on an external server that has its own domain and is accessible over the internet. Both are connected via a wireguard vpn.
I installed nginx on the external server using this configuration:
server {
server_name subdomain.domain.net;
listen 80;
client_max_body_size 10m;
location / {
proxy_pass http://192.168.200.5:8081; # The ip of the home server.
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-Proto $scheme;
proxy_set_header Forwarded "for=$remote_addr;proto=$scheme";
proxy_set_header Connection "";
proxy_http_version 1.1;
access_log /var/log/nginx/seafile.access.log;
error_log /var/log/nginx/seafile.error.log info;
}
}
Then I changed SERVICE_URL, CSRF_TRUSTED_ORIGINS and FILE_SERVER_ROOT in seahub_settings.py on my home server:
# -*- coding: utf-8 -*-
SECRET_KEY = <secret>
SERVICE_URL = "hxxp://subdomain.domain.net" # The domain of the external server
CSRF_TRUSTED_ORIGINS = [
'hxxp://subdomain.domain.net' # The domain of the external server
]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'seahub_db',
'USER': 'seafile',
'PASSWORD': <secret>,
'HOST': 'db',
'PORT': '3306',
'OPTIONS': {'charset': 'utf8mb4'},
}
}
CACHES = {
'default': {
'BACKEND': 'django_pylibmc.memcached.PyLibMCCache',
'LOCATION': 'memcached:11211',
},
'locmem': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
},
}
COMPRESS_CACHE_BACKEND = 'locmem'
TIME_ZONE = 'Etc/UTC'
FILE_SERVER_ROOT = "hxxp://subdomain.domain.net/seafhttp" # The domain of the external server
Now I can access seafile via hxxp://subdomain.domain.net with a web browser, browse the libraries, download files and so on.
But if I try to upload a little text file (<1kB) via the web browser, the upload fails. I opened the browsers DevTools and saw that a POST Request to
hxxp://subdomain.domain.net/seafhttp/upload-aj/8c4f438a-a28a-4ccd-8622-26908bad872d?ret-json=1 failed with 504 Gateway Time-out.
The seafile.error.log on the external server says:
2025/07/10 20:53:59 [error] 15443#15443: *15 upstream prematurely closed connection while reading response header from upstream, client: 92.72.xxx.xxx, server: subdomain.domain.net, request: "POST /seafhttp/upload-aj/35ca7b54-5800-4507-8991-9f823ab158e7?ret-json=1 HTTP/1.1", upstream: "http://192.168.200.5:8081/seafhttp/upload-aj/35ca7b54-5800-4507-8991-9f823ab158e7?ret-json=1", host: "subdomain.domain.net", referrer: "hxxp://subdomain.domain.net/library/11992eee-70cc-40dd-bfb8-665a5c333341/Meine%20Bibliothek/"
Why did that happen? All other requests are forwarded correctly by the external and the internal nginx to seahub inside the container. Only POST requests to seafhttp fail.
I opened a shell on the external server and sent the failed POST request using curl to the url shown in the browsers DevTools:
curl -X POST "hxxp://subdomain.domain.net/seafhttp/upload-aj/8c4f438a-a28a-4ccd-8622-26908bad872d?ret-json=1" \
-H "Accept: application/json, text/javascript, */*; q=0.01" \
-H "Origin: hxxp://subdomain.domain.net" \
-H "Referer: hxxp://subdomain.domain.net/library/11992eee-70cc-40dd-bfb8-665a5c333341/Meine%20Bibliothek/" \
-H "Cookie: sfcsrftoken=KEetmxleEqNFVXxHcBOp3EDk27xtxXWI; sessionid=yga10pila7la4oujh4z95pttvr32mizg" \
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36" \
-F "file=@/root/testupload.txt" \
-F "parent_dir=/"
This worked! The file uploaded with curl appears in the seafile library.
So everything seems to work fine, except upload requests to seafhttp that have been forwarded by both nginx instances. Since direct requests to the home server do work, i think there must be something wrong with the externals nginx configuration shown above…
Does anyone know a solution for this?
Thank you,
Volker