I’ve been using binary installation in self-built docker image. As v13 deprecates this option, I’m looking to migrate from 11→12 using official Docker installation.
One reason why I’ve been using my own image so far was the fact my server already runs nginx proxy, and the official image comes with its own, making topology unnecessarily complex.
Is there a way to opt out of the seafile-provided nginx and continue using existing on-prem nginx? Any guidance from other users who have done so?
Starting with Seafile version 12.0, the official Docker deployment uses Caddy as the default reverse proxy. However, you can easily opt out of this and use your existing Nginx instance by following the official guide: Use other reverse proxy - Seafile Admin Manual.
Here is a summary of the steps required:
Modify your .env file: Remove caddy.yml from the COMPOSE_FILE variable so that the Caddy container is not started.
COMPOSE_FILE='seafile-server.yml'
Modify seafile-server.yml:
Add a ports section to the seafile service to expose the internal port (usually 80:80).
Remove the labels section used by Caddy.
Configure your existing Nginx: Point your Nginx server block to the port you exposed on the Seafile container. The documentation provides specific configuration snippets for:
Main Seafile service (Port 80)
SeaDoc (Port 8888)
Notification server (Port 8083)
Restart the services:
docker compose down
docker compose up -d
nginx -s reload
For the detailed Nginx configuration snippets and specific headers required for WebSockets (Notifications/SeaDoc), please refer to the official manual page.
That’s great news then. Didn’t realize the stack is put together by multiple compose files so was under impression nginx (or now caddy) is baked into seafile server and cannot be opted out. All good!
The Nginx process and logs you are seeing inside the container are expected. Starting with the “multi-component” (mc) images, Seafile uses an internal Nginx instance inside the container to act as a local dispatcher.
This internal Nginx routes traffic to the various services (Seahub, Seaf-server, WebDAV, etc.) within the same container. This is why you only need to expose port 80 to your external Nginx. The external proxy no longer needs specific blocks for /seafhttp, /media, or /seafdav because the internal Nginx handles those routes and simplifies the external configuration.
To summarize:
Internal Nginx (inside the container): Handles internal routing between components. It is a core part of the seafile-mc image and cannot be opted out of without building a custom architecture.
External Proxy (Caddy/Your Nginx): Handles SSL and external access, pointing to the container’s exposed port.
Regarding your request for the documentation: the reason those blocks were removed is that they are now handled internally. For a standard Docker-based v12 deployment, your external Nginx only needs the main / location block pointing to the Seafile container’s port 80, as described in the Use other reverse proxy guide.
If you have specific needs to bypass the internal Nginx entirely, you would need to revert to a standalone component architecture, but for the official Docker image, this “double proxy” (External Nginx → Internal Nginx → Service) is the designed behavior.
I also suggest you to use 13.0 version, as 12.0 is already outdated.
v13 docs on self-hosted nginx usage for seadoc only define /socket.io & /sdoc-server/ endpoints proxying to port 8888. However when looking in the seadoc’s own internal nginx config @ /etc/nginx/sites-enabled/nginx-sdoc.conf, there are some differences:
there’s also a /converter/ endpoint missing in the docs;
there’s also a root (/) location missing in the docs pointing to port 7070;
the /socket.io proxy port differs: 7070 vs 8888 defined in the docs above;
EDIT: ignore, I now understand our own nginx routing to 8888 really is pointed at the seadoc’s internal nginx listening on port 80, so all my questions are moot.