[SOLVED] Using nginx reverse proxy for seafile-docker

Hi Seafile team!

I recently installed Seafile using your docker image which is really great

As I am hosting other services aswell I want to use nginx, which is installed on the system itself, as a reverse proxy.

The nginx config looks like this:

server {
  listen 443 ssl http2;
  server_name seafile . mydomain . com;

  ssl_certificate /ssl.cer;
  ssl_certificate_key /ssl.key;

  proxy_set_header X-Real-IP $remote_addr;

  location / {
    proxy_pass http://localhost:3001;
  }
}

But for some reason the seafile server then redirects me from https:// seafile . mydomain . com to localhost/accounts/login?next=/

I can replace localhost in the address bar myself and open https:// seafile . mydomain . com/accounts/login?next=/ which then works just fine.
I log in on the page and it redirects me to localhost.
Again I can replace localhost and open https:// seafile . mydomain . com/ which works fine again.

When I edit my nginx configuration and replace localhost with 127.0.0.1 then I always get redirected to 127.0.0.1.

Any ideas how I could fix this? I’d really appreciate it!

2 Likes

Is that the only thing in your NGinx config? It’s missing some things, if that’s the case.

Yes thats everything. The seafile container itself also comes with an nginx installation.

I am basically just getting my traffic on port 443 passed to the docker container listening on 3001 which then has its own ‘location /seafhttp’ and stuff configured.

The nginx config in the seafile docker container is generated based on this

I took a look inside my container and this is the nginx config in there:

# -*- mode: nginx -*-
# Auto generated at 05/09/2018 18:22:15
server {
listen 80;
server_name seafile.example.com;

    client_max_body_size 10m;

    location / {
        proxy_pass http://127.0.0.1:8000/;
        proxy_read_timeout 310s;
        proxy_set_header Host $host;
        proxy_set_header Forwarded "for=$remote_addr;proto=$scheme";
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Connection "";
        proxy_http_version 1.1;
    }

    location /seafhttp {
        rewrite ^/seafhttp(.*)$ $1 break;
        proxy_pass http://127.0.0.1:8082;
        client_max_body_size 0;
        proxy_connect_timeout  36000s;
        proxy_read_timeout  36000s;
    }

    location /seafdav {
        client_max_body_size 0;
        fastcgi_pass    127.0.0.1:8080;
        fastcgi_param   SCRIPT_FILENAME     $document_root$fastcgi_script_name;
        fastcgi_param   PATH_INFO           $fastcgi_script_name;

        fastcgi_param   SERVER_PROTOCOL     $server_protocol;
        fastcgi_param   QUERY_STRING        $query_string;
        fastcgi_param   REQUEST_METHOD      $request_method;
        fastcgi_param   CONTENT_TYPE        $content_type;
        fastcgi_param   CONTENT_LENGTH      $content_length;
        fastcgi_param   SERVER_ADDR         $server_addr;
        fastcgi_param   SERVER_PORT         $server_port;
        fastcgi_param   SERVER_NAME         $server_name;

        access_log      /var/log/nginx/seafdav.access.log;
        error_log       /var/log/nginx/seafdav.error.log;
    }

    location /media {
        root /opt/seafile/seafile-server-latest/seahub;
    }

    # For letsencrypt
    location /.well-known/acme-challenge/ {
        alias /var/www/challenges/;
        try_files $uri =404;
    }
}

You are missing some vital settings in the one you originally posted, Some of these settings that are both in the template and the container. Should be under proxy_pass http://localhost:3001; You are also missing the entire location /seafhttp section, which is necessary to sync files. I would use the settings in the template, excepting the https cert locations. Obviously, yours are stored elsewhere. The primary things you are missing are all of the proxy_set_header lines, and the entire seafhttp location.

1 Like

And I’m still vague on exactly what it is you are trying to accomplish. So, your stripped down NGinx file, you are trying to sending to another NGinx installation?

I don’t know if that’s possible. There have been people who have tried allowing something else, say a router, to handle the http certs and then forward the traffic to NGinx/Apache. However, I’ve not known anyone to be successful with it.

On top of that, even if you were successful with that config, you are using a custom port, 3001, but you aren’t listening for that port inside the docker. You are listening for port 80.

Honestly, I’m not certain how to go about passing from one NGinx instance to another. Maybe someone else can shed some light on whether or not you can pull it off that way. Nor do I use dockers, so my experience is limited there as well.

What I do know is that in order for a web server to work, it has to know where to find the folders, and in the case of Seafile, that would be the root location and the seafhttp location.

Thank you for your help, wthess!

I finally got it working! It was indeed the missing proxy_set_header lines.
I just copied the one from the template to my own nginx config and its working now.

The /seafhttp for example is not necessary as the docker container just exposes one port.

To clear things up about my setup:

I am running a VPS with nginx and docker installed. I am using docker to install all services I want to run, like Gitea on port 3001, Seafile on port 3002, Tiny tiny RSS on port 3003, and so on.
The nginx installation on my VPS then manages the incoming traffic and uses reverse proxies to make these service accessible via my domain and with my ssl certificates.

The seafile docker container comes with nginx already bundled. If I would be running just seafile on my VPS, I could just make the container expose port 443 and be fine with it, but then I couldn’t setup reverse proxies for my other containers. So I mapped the port 80, which the container exposes to port 3001 on my VPS.

docker run -d --name seafile -v /docker/seafile:/shared -p 127.0.0.1:3001:80 seafileltd/seafile:latest

In the end my nginx config looks like this and works perfectly so far!

server {
  listen 443 ssl http2;
  server_name seafile . mydomain . com;

  ssl_certificate /ssl.cer;
  ssl_certificate_key /ssl.key;

  proxy_set_header X-Real-IP $remote_addr;

  location / {
    proxy_read_timeout 310s;
    proxy_set_header Host $host;
    proxy_set_header Forwarded "for=$remote_addr;proto=$scheme";
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Connection "";
    proxy_http_version 1.1;
    proxy_pass http://localhost:3001;
  }
}

Thank you very much for the tip about the missing proxy headers!

4 Likes

Any time, and thanks for the extra info. It will help others in the future. :slight_smile:

Hi berndo3 !

I am in the exact same configuration as you, nginx reverse-proxy docker container used to redirect to other docker containers, one of them being seafile (seafile container itself embedding a nginx reverse-proxy server to its seahub and seafile servers, as previsouly explained).

However I cannot make it work. What SEAFILE_URL do you use as env var ? I am using https://mydomain.com/seafile

Ok I managed to fix it, the seafile block in main nginx conf files was correct (location /seafile { ... }), but few other settings had to be set for seafile to work at non-root domain (https://manual.seafile.com/deploy/deploy_seahub_at_non-root_domain.html).

  • SEAFILE_URL should be set to https://domain.com/seafile

  • settings_seahub.py had to be modified with following settings :

SERVE_STATIC = False
MEDIA_URL = '/seafile/seafmedia/'
COMPRESS_URL = MEDIA_URL
STATIC_URL = MEDIA_URL + 'assets/'
SITE_ROOT = '/seafile/'
LOGIN_URL = '/seafile/accounts/login/'
  • seafile internal nginx config seafile.conf must be modified also :
location / {
		...
		fastcgi_param   HTTPS               on;
		fastcgi_param   HTTP_SCHEME         https;
		...
}

...

location /seafile/seafmedia {
		rewrite ^/seafile/seafmedia(.*)$ /media$1 break;
		root /opt/seafile/latest/seahub;
}
1 Like

Hi @berndo3

I got it working by following exactly your steps but I can’t up/download any files.
my seahub.log inside the docker container is full with:

2019-02-05 00:38:03,515 [WARNING] django.request:152 get_response Not Found: /upload-aj/35c9fc1d-ae33-456a-955a-c34091a8c8ef
2019-02-05 00:55:25,166 [WARNING] django.request:152 get_response Not Found: /files/293565eb-5c0b-4ea0-9f3b-ee84bfa09762/seafile-tutorial.doc
2019-02-05 00:59:43,438 [WARNING] django.request:152 get_response Not Found: /files/b85c7bca-7824-438f-9ae7-4bd7b1823f38/seafile-tutorial.doc
2019-02-05 00:59:50,908 [WARNING] django.request:152 get_response Not Found: /upload-aj/867e628e-7ea5-4f61-a261-832d2f5afdfb

Do you or somebody know how to fix this?

2 Likes

im facing exactly the same problem right now … got it working using https, but then can’t download /upload . if someone able to solved this problem , care to share with us ?

1 Like

I am also having the down/up loading issue
Anyone knows how to fix this?

works good so far.

i have only an issue with seafdav.
MOVE returns 502 Bad Gateway

for exp. on FolderSync App
502 Bad Gateway: Source and destination must have the same scheme. If you are running behind a reverse proxy, you may have to rewrite the 'Destination' header.

maybe same problem like:

EDIT:
in
seafile-data/nginx/conf/seafile.nginx.conf

i have change /seafdav location to:

    location /seafdav {
                 proxy_pass http://127.0.0.1:8080;
                proxy_http_version 1.1;
                proxy_set_header HOST $host;
                #proxy_set_header Connection "upgrade";
                proxy_set_header X-NginX-Proxy true;
                proxy_buffering off;
                client_max_body_size 0;
                proxy_request_buffering off;
                set $dest $http_destination;
                if ($http_destination ~ "^https://my.domain/seafdav/(.+)") {
                        set $dest /seafdav/$1;
                }
                proxy_set_header DESTINATION $dest;
               

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

Webdav works good now