I’ve moved from bare metal nginx to dockerized caddy, and managed to redirect seafile correctly with caddy.
However, the onlyoffice Integration is somehow broken, clicking on an office file results in a blank tab.
Has anyone managed to setup seafile with onlyoffice behind caddy?
And would be willing to share his Caddyfile (without domain names)?
Thanks a lot,
Ruediger
I’ve given up on caddy, I was unable to get onlyoffice working in seafile with caddy.
So I moved back to nginx, but with nginx running in Docker using this image here: https://hub.docker.com/r/jonasal/nginx-certbot
This will take care of automatic certbot updates, you only need to provide the conf files for nginx. Quite nice!
Hi. Here is my full setup for seafile on single node. I found onlyoffice docs for setting up behind nginx reverse proxy and partially rewrote it for caddy-docker-proxy.
This setup is behind nginx proxy manager, which is responsible for https.
Hope it helps.
docker-compose.yml
services:
caddy:
image: ${SEAFILE_CADDY_IMAGE:-lucaslorentz/caddy-docker-proxy:2.9-alpine}
container_name: seafile-caddy
restart: unless-stopped
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ${SEAFILE_CADDY_VOLUME:-/opt/seafile-caddy}:/data/caddy
healthcheck:
test: ["CMD-SHELL", "curl --fail http://localhost:2019/metrics || exit 1"]
start_period: 20s
interval: 20s
timeout: 5s
retries: 3
labels:
caddy: ":80"
caddy.0_map: "{header.x-forwarded-proto} {proto_override}"
caddy.0_map.~^$: "{scheme}"
caddy.0_map.default: "{header.x-forwarded-proto}"
caddy.1_map: "{host} {this_host}"
caddy.1_map.~^$: "${SEAFILE_SERVER_HOSTNAME}"
caddy.1_map.default: "{host}"
caddy.2_map: "{header.x-forwarded-host} {host_override}"
caddy.2_map.~^$: "{this_host}"
caddy.2_map.default: "{header.x-forwarded-host}"
seafile:
image: ${SEAFILE_IMAGE:-seafileltd/seafile-pro-mc:13.0-latest}
container_name: seafile
restart: unless-stopped
volumes:
- ${SEAFILE_VOLUME:-/opt/seafile-data}:/shared
environment:
- INIT_SEAFILE_MYSQL_ROOT_PASSWORD=${INIT_SEAFILE_MYSQL_ROOT_PASSWORD:-}
- SEAFILE_MYSQL_DB_HOST=${SEAFILE_MYSQL_DB_HOST:-db}
- SEAFILE_MYSQL_DB_PORT=${SEAFILE_MYSQL_DB_PORT:-3306}
- SEAFILE_MYSQL_DB_USER=${SEAFILE_MYSQL_DB_USER:-seafile}
- SEAFILE_MYSQL_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=${TIME_ZONE:-Etc/UTC}
- INIT_SEAFILE_ADMIN_EMAIL=${INIT_SEAFILE_ADMIN_EMAIL:-me@example.com}
- INIT_SEAFILE_ADMIN_PASSWORD=${INIT_SEAFILE_ADMIN_PASSWORD:-asecret}
- SEAFILE_SERVER_HOSTNAME=${SEAFILE_SERVER_HOSTNAME:?Variable is not set or empty}
- SEAFILE_SERVER_PROTOCOL=${SEAFILE_SERVER_PROTOCOL:-http}
- SITE_ROOT=${SITE_ROOT:-/}
- NON_ROOT=${NON_ROOT:-false}
- 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:-true}
- SEADOC_SERVER_URL=${SEAFILE_SERVER_PROTOCOL:-http}://${SEAFILE_SERVER_HOSTNAME:?Variable is not set or empty}/sdoc-server
- CACHE_PROVIDER=${CACHE_PROVIDER:-redis}
- REDIS_HOST=${REDIS_HOST:-redis}
- REDIS_PORT=${REDIS_PORT:-6379}
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
- MEMCACHED_HOST=${MEMCACHED_HOST:-memcached}
- MEMCACHED_PORT=${MEMCACHED_PORT:-11211}
- SEAF_SERVER_STORAGE_TYPE=${SEAF_SERVER_STORAGE_TYPE:-}
- S3_COMMIT_BUCKET=${S3_COMMIT_BUCKET:-}
- S3_FS_BUCKET=${S3_FS_BUCKET:-}
- S3_BLOCK_BUCKET=${S3_BLOCK_BUCKET:-}
- S3_KEY_ID=${S3_KEY_ID:-}
- S3_SECRET_KEY=${S3_SECRET_KEY:-}
- S3_USE_V4_SIGNATURE=${S3_USE_V4_SIGNATURE:-true}
- S3_AWS_REGION=${S3_AWS_REGION:-us-east-1}
- S3_HOST=${S3_HOST:-}
- S3_USE_HTTPS=${S3_USE_HTTPS:-true}
- S3_PATH_STYLE_REQUEST=${S3_PATH_STYLE_REQUEST:-false}
- S3_SSE_C_KEY=${S3_SSE_C_KEY:-}
- ENABLE_NOTIFICATION_SERVER=${ENABLE_NOTIFICATION_SERVER:-false}
- INNER_NOTIFICATION_SERVER_URL=${INNER_NOTIFICATION_SERVER_URL:-http://notification-server:8083}
- NOTIFICATION_SERVER_URL=${NOTIFICATION_SERVER_URL:-${SEAFILE_SERVER_PROTOCOL:-http}://${SEAFILE_SERVER_HOSTNAME:?Variable is not set or empty}/notification}
- ENABLE_SEAFILE_AI=${ENABLE_SEAFILE_AI:-false}
- SEAFILE_AI_SERVER_URL=${SEAFILE_AI_SERVER_URL:-http://seafile-ai:8888}
- SEAFILE_AI_SECRET_KEY=${JWT_PRIVATE_KEY:?Variable is not set or empty}
- MD_FILE_COUNT_LIMIT=${MD_FILE_COUNT_LIMIT:-100000}
labels:
# caddy: ${SEAFILE_SERVER_PROTOCOL:-http}://${SEAFILE_SERVER_HOSTNAME:?Variable is not set or empty}
caddy: ":80"
caddy.reverse_proxy: "{{upstreams 80}}"
caddy.reverse_proxy.0_header_up: X-Forwarded-Host {host_override}
caddy.reverse_proxy.1_header_up: X-Forwarded-Proto {proto_override}
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
seadoc:
image: ${SEADOC_IMAGE:-seafileltd/sdoc-server:2.0-latest}
container_name: seadoc
restart: unless-stopped
volumes:
- ${SEADOC_VOLUME:-/opt/seadoc-data/}:/shared
environment:
- DB_HOST=${SEAFILE_MYSQL_DB_HOST:-db}
- DB_PORT=${SEAFILE_MYSQL_DB_PORT:-3306}
- DB_USER=${SEAFILE_MYSQL_DB_USER:-seafile}
- DB_PASSWORD=${SEAFILE_MYSQL_DB_PASSWORD:?Variable is not set or empty}
- DB_NAME=${SEADOC_MYSQL_DB_NAME:-seahub_db}
- TIME_ZONE=${TIME_ZONE:-Etc/UTC}
- JWT_PRIVATE_KEY=${JWT_PRIVATE_KEY:?Variable is not set or empty}
- NON_ROOT=${NON_ROOT:-false}
- SEAHUB_SERVICE_URL=${SEAFILE_SERVICE_URL:-http://seafile}
labels:
# caddy: ${SEAFILE_SERVER_PROTOCOL:-http}://${SEAFILE_SERVER_HOSTNAME:?Variable is not set or empty}
caddy: ":80"
caddy.@ws.0_header: "Connection *Upgrade*"
caddy.@ws.1_header: "Upgrade websocket"
caddy.0_reverse_proxy: "@ws {{upstreams 80}}"
caddy.1_handle_path: "/socket.io/*"
caddy.1_handle_path.0_rewrite: "* /socket.io{uri}"
caddy.1_handle_path.1_reverse_proxy: "{{upstreams 80}}"
caddy.2_handle_path: "/sdoc-server/*"
caddy.2_handle_path.0_rewrite: "* {uri}"
caddy.2_handle_path.1_reverse_proxy: "{{upstreams 80}}"
depends_on:
db:
condition: service_healthy
db:
image: ${SEAFILE_DB_IMAGE:-mariadb:10.11}
container_name: seafile-mysql
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=${INIT_SEAFILE_MYSQL_ROOT_PASSWORD:-}
- MYSQL_LOG_CONSOLE=true
- MARIADB_AUTO_UPGRADE=1
volumes:
- "${SEAFILE_MYSQL_VOLUME:-/opt/seafile-mysql/db}:/var/lib/mysql"
healthcheck:
test:
[
"CMD",
"/usr/local/bin/healthcheck.sh",
"--connect",
"--mariadbupgrade",
"--innodb_initialized",
]
interval: 20s
start_period: 30s
timeout: 5s
retries: 10
redis:
image: ${SEAFILE_REDIS_IMAGE:-redis}
container_name: seafile-redis
restart: unless-stopped
command:
- /bin/sh
- -c
- redis-server --requirepass "$$REDIS_PASSWORD"
environment:
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
elasticsearch:
image: ${SEAFILE_ELASTICSEARCH_IMAGE:-elasticsearch:8.15.0}
container_name: seafile-elasticsearch
restart: unless-stopped
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms2g -Xmx2g"
- "xpack.security.enabled=false"
ulimits:
memlock:
soft: -1
hard: -1
mem_limit: 4g
volumes:
- "${SEAFILE_ELASTICSEARCH_VOLUME:-/opt/seafile-elasticsearch/data}:/usr/share/elasticsearch/data"
onlyoffice:
image: ${ONLYOFFICE_IMAGE:-onlyoffice/documentserver:8.1.0.1}
restart: unless-stopped
container_name: seafile-onlyoffice
environment:
#- DB_TYPE=${DB_TYPE:-mariadb}
#- DB_HOST=${SEAFILE_MYSQL_DB_HOST:-db}
#- DB_USER=${SEAFILE_MYSQL_DB_USER:-seafile}
#- DB_PWD=${SEAFILE_MYSQL_DB_PASSWORD:?Variable is not set or empty}
- JWT_ENABLED=true
- JWT_SECRET=${ONLYOFFICE_JWT_SECRET:?Variable is not set or empty}
volumes:
- ${ONLYOFFICE_VOLUME:-/opt/onlyoffice}/logs:/var/log/onlyoffice
- ${ONLYOFFICE_VOLUME:-/opt/onlyoffice}/data:/var/www/onlyoffice/Data
- ${ONLYOFFICE_VOLUME:-/opt/onlyoffice}/lib:/var/lib/onlyoffice
labels:
caddy: ":80"
caddy.handle_path: "/documentserver/*"
caddy.handle_path.reverse_proxy: "{{upstreams 80}}"
caddy.handle_path.reverse_proxy.0_header_up: X-Forwarded-Host {host}/documentserver
caddy.handle_path.reverse_proxy.1_header_up: X-Forwarded-Proto {proto_override}