Hi!
I am trying to run seafile 12.0 (fresh docker container, as a docker compose) from ubuntu 24 LTS at a non-root domain behind a traefik reverse proxy. I tried applying the modifications outlined in the installation instructions for seafile 11, but could not manage to get it to work (fully).
My current docker-compose file (see end of the post) tries to provide seafile at ${DOMAIN_NAME}/cloud
- but fails to do so.
I have tried a couple of configurations and modifications:
- Strip the subpath from the url using traefiks strip-prefix middleware, do not modify the nginx config and update the seahub_settings.py according to the 11.0 documentation
- Do not strip the subpath from the url, do not modify the nginx config and update seahub_settings.py according to the 11.0 documentation
- Do not strip the subpath from the url, modify the nginx config and update the seahub_settings.py according to the 11.0 documentation
For 1, 2, and 3 I modified seahub_settings.py to various degrees (e.g., by only updating media and site_root, up to the full example). Some of the configurations provided me at least with the seafile logos, and an error message that seafile could not be found
For 2 and 3, I also tried to add a rewrite rule to nginx that would strip the /cloud subpath from the request and then process it again - this did not work at all.
Frankly, I am at a loss for any further modifications and would be very glad if anybody can give me some pointers in the right direction. Unfortunately, it is not a possibility to provide seafile at a subdomain (e.g., cloud.${DOMAIN_NAME}) for various (company) reasons. I am more than happy to submit a PR to the documentation to update it with steps on how to get non-root domains working (and/or together with traefik) once/if I get this issue fixed.
Finally, while trying to solve the non-root domain problem I think I may have found a bug: It seems that the served html document by seafile (the few times that I managed), requests the jquery javascript from a hardcoded root domain /media… instead of honoring the updated MEDIA_URL provided in seahub_settings.py. Maybe that is just a product of my missconfiguration - but every other resource used the correct URL. This is also why there is the exposed /media subdomain.
Thanks for any help and/or advice in advance!
Docker compose:
services:
seafile-db:
image: ${SEAFILE_DB_IMAGE:-mariadb:10.11}
container_name: seafile-mysql
environment:
- MYSQL_ROOT_PASSWORD=${SEAFILE_SQL_ROOT_PASSWD}
- MYSQL_LOG_CONSOLE=true
- MARIADB_AUTO_UPGRADE=1
volumes:
- ${STORAGE_PATH}/seafile/db:/var/lib/mysql
- /etc/localtime:/etc/localtime:ro
networks:
- seafile-net
healthcheck:
test:
[
"CMD",
"/usr/local/bin/healthcheck.sh",
"--connect",
"--mariadbupgrade",
"--innodb_initialized",
]
interval: 20s
start_period: 30s
timeout: 5s
retries: 10
seafile-memcached:
image: ${SEAFILE_MEMCACHED_IMAGE:-memcached:1.6.29}
container_name: seafile-memcached
entrypoint: memcached -m 256
networks:
- seafile-net
seafile:
image: ${SEAFILE_IMAGE:-seafileltd/seafile-mc:12.0-latest}
container_name: seafile
volumes:
- ${STORAGE_PATH}/seafile/data:/shared
- /etc/localtime:/etc/localtime:ro
environment:
- DB_HOST=${SEAFILE_MYSQL_DB_HOST:-seafile-db}
- DB_PORT=${SEAFILE_MYSQL_DB_PORT:-3306}
- DB_USER=${SEAFILE_MYSQL_DB_USER:-seafile}
- DB_ROOT_PASSWD=${SEAFILE_SQL_ROOT_PASSWD}
- DB_PASSWORD=${SEAFILE_MYSQL_DB_PASSWORD:?Variable is not set or empty}
- SEAFILE_MYSQL_DB_CCNET_DB_NAME=${SEAFILE_MYSQL_DB_CCNET_DB_NAME:-ccnet_db}
- SEAFILE_MYSQL_DB_SEAFILE_DB_NAME=${SEAFILE_MYSQL_DB_SEAFILE_DB_NAME:-seafile_db}
- SEAFILE_MYSQL_DB_SEAHUB_DB_NAME=${SEAFILE_MYSQL_DB_SEAHUB_DB_NAME:-seahub_db}
- TIME_ZONE=${TZ}
# - INIT_SEAFILE_ADMIN_EMAIL=${INIT_SEAFILE_ADMIN_EMAIL:-me@example.com}
# - INIT_SEAFILE_ADMIN_PASSWORD=${INIT_SEAFILE_ADMIN_PASSWORD:-asecret}
- SEAFILE_SERVER_HOSTNAME=${DOMAIN_NAME}
- SEAFILE_SERVER_PROTOCOL=https
- SITE_ROOT=${SEAFILE_URL_SUBPATH}
- NON_ROOT=${NON_ROOT:-false} # defines if seafile should run as non-root user
- JWT_PRIVATE_KEY=${JWT_PRIVATE_KEY:?Variable is not set or empty}
- SEAFILE_LOG_TO_STDOUT=${SEAFILE_LOG_TO_STDOUT:-false}
- ENABLE_SEADOC=${ENABLE_SEADOC:-false}
# - SEADOC_SERVER_URL=${SEADOC_SERVER_URL:-http://seafile.example.com/sdoc-server}
labels:
- "traefik.enable=true"
- "traefik.http.routers.seafile.entrypoints=websecure"
- "traefik.http.routers.seafile.rule=Host(`${DOMAIN_NAME}`) && PathPrefix(`${SEAFILE_URL_SUBPATH}`)"
- "traefik.http.routers.seafile.service=seafile"
- "traefik.http.services.seafile.loadbalancer.server.port=80"
# Strip the SEAFILE_URL_SUBPATH from the request path
- "traefik.http.middlewares.strip-seafile-path.stripprefix.prefixes=${SEAFILE_URL_SUBPATH}"
- "traefik.http.routers.seafile.middlewares=strip-seafile-path"
# Fix for loading the jquery-path which seems to be hardcoded in the served html
- "traefik.http.routers.seafile-media-fix.rule=Host(`${DOMAIN_NAME}`) && PathPrefix(`/media`)"
- "traefik.http.routers.seafile-media-fix.entrypoints=websecure"
- "treafik.http.services.seafile-media-fix.loadbalancer.server.port=80"
# - "traefik.http.routers.webdav.rule=Host(`${DOMAIN_NAME}`) && PathPrefix(`/seafdav`)"
# - "traefik.http.routers.webdav.entrypoints=websecure"
# - "traefik.http.routers.seafhttp.rule=Host(`${DOMAIN_NAME}`) && PathPrefix(`/seafhttp`)"
# - "traefik.http.routers.seafhttp.entrypoints=websecure"
depends_on:
- seafile-db
- seafile-memcached
networks:
- seafile-net
- proxy
networks:
seafile-net:
proxy:
# No need to mark it as external as my startup script merges this with the traefik configuration