Seafile 12专业版使用自己的ssl证书开启https实现公网域名访问并启用onlyoffice

一直使用的是seafile 8.0版本,好几年没有升级,看到最新的12版本新增了seadoc并且界面美好,就折腾着安装了好久,其间踩坑无数,官方的安装教程很简洁,也许是高估了新手的水平,参考论坛大佬分享的经验加上自己不断的试错,终于算是解决了这个问题,把经验分享给大家,希望对新手能有所帮助。
首先说一下基本网络环境,有公网ip4地址(因为开始的时候使用ipv6地址来测试,知识库始终不能正常使用),并且有一个自己的域名,路由器具有端口转发功能,可以说要求并不高,基本都能满足。
下面把配置贴出来,#后边有中文的部分就是需要自己修改的地方,如原本没有此项则创建

下载地址

# Seafile PRO 12.0(Github镜像源)
wget -O .env https://manual.seafile.com/12.0/repo/docker/pro/env
wget https://manual.seafile.com/12.0/repo/docker/seadoc.yml
wget https://manual.seafile.com/12.0/repo/docker/pro/seafile-server.yml
wget https://manual.seafile.com/12.0/repo/docker/caddy.yml
wget https://manual.seafile.com/12.0/repo/docker/onlyoffice.yml

.env文件

############################################
#      Docker compose configurations       #
############################################
COMPOSE_FILE='seafile-server.yml,caddy.yml,seadoc.yml,onlyoffice.yml'
COMPOSE_PATH_SEPARATOR=','

## Images
SEAFILE_IMAGE=seafileltd/seafile-pro-mc:12.0-latest
SEAFILE_DB_IMAGE=mariadb:10.11.11
SEAFILE_MEMCACHED_IMAGE=memcached:1.6.38
SEAFILE_ELASTICSEARCH_IMAGE=elasticsearch:8.18.0
SEAFILE_CADDY_IMAGE=lucaslorentz/caddy-docker-proxy:ci-alpine
SEADOC_IMAGE=seafileltd/sdoc-server:1.0-latest
NOTIFICATION_SERVER_IMAGE=seafileltd/notification-server:12.0-latest
SEASEARCH_IMAGE=seafileltd/seasearch:latest
ONLYOFFICE_IMAGE=onlyoffice/documentserver:latest

## Persistent Storage
BASIC_STORAGE_PATH=/opt/seafile-12        #此处自定义Seafile的安装目录
SEAFILE_VOLUME=$BASIC_STORAGE_PATH/seafile-data
SEAFILE_MYSQL_VOLUME=$BASIC_STORAGE_PATH/seafile-mysql/db
SEAFILE_ELASTICSEARCH_VOLUME=$BASIC_STORAGE_PATH/seafile-elasticsearch/data
SEAFILE_CADDY_VOLUME=$BASIC_STORAGE_PATH/seafile-caddy
NOTIFICATION_SERVER_VOLUME=$BASIC_STORAGE_PATH/notification-data
SS_DATA_PATH=$BASIC_STORAGE_PATH/seasearch-data 
SEADOC_VOLUME=$BASIC_STORAGE_PATH/seadoc-data
ONLYOFFICE_VOLUME=$BASIC_STORAGE_PATH/onlyoffice

############################################
#      Startup parameters                  #
############################################

SEAFILE_SERVER_PORT=7777        #此处设置Seafile服务的访问端口
SEAFILE_SERVER_PROTOCOL=https        #此处设置是否开启https
SEAFILE_SERVER_HOSTNAME=seafile.example.com:$SEAFILE_SERVER_PORT        #此处设置Seafile服务的域名或IP地址
CADDY_CERT_PATH=$SEAFILE_CADDY_VOLUME/certs        #此处设置caddy ssl证书的存放目录
CADDY_SSL_CERTIFICATE_CRT=seafile.example.com.crt        #此处输入自己申请的ssl crt证书名称
CADDY_SSL_CERTIFICATE_KEY=seafile.example.com.key        #此处输入自己申请的ssl key证书名称
TIME_ZONE=Asia/Shanghai
JWT_PRIVATE_KEY=密码        #此处设置JWT密码,不少于32位

## Database
SEAFILE_MYSQL_DB_HOST=db
SEAFILE_MYSQL_DB_USER=seafile
SEAFILE_MYSQL_DB_PASSWORD=密码        #此处设置数据库seafile用户密码
SEAFILE_MYSQL_DB_CCNET_DB_NAME=ccnet_db
SEAFILE_MYSQL_DB_SEAFILE_DB_NAME=seafile_db
SEAFILE_MYSQL_DB_SEAHUB_DB_NAME=seahub_db

## Database root password, Used to create Seafile users
INIT_SEAFILE_MYSQL_ROOT_PASSWORD=密码        #此处设置数据库root用户密码

## Seafile admin user
INIT_SEAFILE_ADMIN_EMAIL=seafile@example.com        #此处设置Seafile网站的登录邮箱账号
INIT_SEAFILE_ADMIN_PASSWORD=密码        #此处设置Seafile网站的账号登录密码

## OnlyOffice
ONLYOFFICE_PORT=6233        #此处设置onlyoffice的映射端口
ONLYOFFICE_JWT_SECRET=密码        #此处密码应与前边的JWT密码相同

caddy.yml

    ports:
      - 80:80
      - 443:443
      - ${SEAFILE_SERVER_PORT:-7777}:443        #此处映射Seafile服务的访问端口
    environment:
      - CADDY_INGRESS_NETWORKS=seafile-net
    labels:
      caddy.auto_https: "disable_certs"        #禁止caddy自动申请ssl证书
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ${SEAFILE_CADDY_VOLUME:-/opt/seafile-caddy}:/data/caddy
      - ${CADDY_CERT_PATH:-/opt/seafile-caddy/certs}:/etc/caddy/certs        #此处设置caddy ssl证书存放目录

seadoc.yml

    labels:
      caddy: ${SEAFILE_SERVER_PROTOCOL:-http}://seafile.example.com        #此处设置Seafile服务的域名或IP地址,注意不要带端口号

seafile-server.yml

    labels:
      caddy: ${SEAFILE_SERVER_PROTOCOL:-http}://seafile.example.com        #此处设置Seafile服务的域名或IP地址,注意不要带端口号
      caddy.tls: /etc/caddy/certs/${CADDY_SSL_CERTIFICATE_CRT} /etc/caddy/certs/${CADDY_SSL_CERTIFICATE_KEY}        #此处设置caddy ssl证书,直接复制不需要修改

onlyoffice.yml

    ports:
      - ${ONLYOFFICE_PORT:-6233}:443        #此处设置onlyoffice的映射端口

准备工作完成,开始部署

docker compose pull
docker compose up -d
#启动完成之后还需要做一些修改
docker compose stop

#复制自己的ssl证书到caddy目录,证书名称必须和.env中设置的相同
/opt/seafile-12/seafile-caddy/certs
#复制自己的ssl证书到onlyoffice目录,必须重命名为onlyoffice.crt和onlyoffice.key
/opt/seafile-12/onlyoffice/data/certs

#需要手动给 elasticsearch/data的映射路径 777 权限
chmod 777 -R /opt/seafile-12/seafile-elasticsearch/data

#编辑seahub_settings.py文件,在末尾添加,根据自己的实际情况修改网址及JWT密码
ENABLE_ONLYOFFICE = True
ONLYOFFICE_APIJS_URL = 'https://seafile.example.com:6233/web-apps/apps/api/documents/api.js'
ONLYOFFICE_FILE_EXTENSION = ('doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'odt', 'fodt', 'odp', 'fodp', 'ods', 'fods', 'csv', 'ppsx', 'pps')
ONLYOFFICE_EDIT_FILE_EXTENSION = ('doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'odt', 'fodt', 'odp', 'fodp', 'ods', 'fods', 'csv', 'ppsx', 'pps')
ONLYOFFICE_JWT_SECRET = 'JWT密码'

#再次启动,顺利的话可以正常访问seafile网站并使用onlyoffice了
docker compose up -d

以上就是全部安装过程,如果遇到问题可以参考一下,抛砖引玉,有不对的地方还请谅解。

感谢楼主无私分享,但docker compose pull拉取不了,怎么办?

配置Docker容器镜像加速器
vim /etc/docker/daemon.json

{
  "dns": ["223.5.5.5", "223.6.6.6"],
  "registry-mirrors":
    [
      "https://docker.m.daocloud.io",
      "https://docker-pull.ygxz.in",
      "https://hub.registry-mirrors.top"
    ]
}

感谢兄弟,已经成功拉取。我手动在阿里云申请的ssl证书复制到/etc/caddy/certs/目录下面,但是caddy报错了?如下:
seafile-caddy | {"level":"info","ts":1747306866.310432,"logger":"docker-proxy","msg":"Sending configuration to","server":"localhost"} seafile-caddy | {"level":"info","ts":1747306866.3118134,"logger":"admin.api","msg":"received request","method":"POST","host":"localhost:2019","uri":"/load","remote_ip":"127.0.0.1","remote_port":"43260","headers":{"Accept-Encoding":["gzip"],"Content-Length":["1637"],"Content-Type":["application/json"],"User-Agent":["Go-http-client/1.1"]}} seafile-caddy | {"level":"info","ts":1747306866.3132582,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]} seafile-caddy | {"level":"error","ts":1747306866.3137941,"logger":"admin.api","msg":"request error","error":"loading config: loading new config: loading http app module: provision http: getting tls app: loading tls app module: provision tls: loading certificates: open /etc/caddy/certs/seafile.my.com_public.crt: no such file or directory","status_code":400} seafile-caddy | {"level":"error","ts":1747306866.3140702,"logger":"docker-proxy","msg":"Error response from server","server":"localhost","status code":400,"body":"{\"error\":\"loading config: loading new config: loading http app module: provision http: getting tls app: loading tls app module: provision tls: loading certificates: open /etc/caddy/certs/seafile.my.com_public.crt: no such file or directory\"}\n"} seafile-caddy | {"level":"info","ts":1747306866.315111,"logger":"admin","msg":"stopped previous server","address":"localhost:2019"} seafile-caddy | {"level":"info","ts":1747306866.9046452,"msg":"http: panic serving 127.0.0.1:43276: runtime error: invalid memory address or nil pointer dereference\ngoroutine 411 [running]:\nnet/http.(*conn).serve.func1()\n\tnet/http/server.go:1903 +0xbe\npanic({0x174fbe0?, 0x2b41d70?})\n\truntime/panic.go:770 +0x132\ngithub.com/caddyserver/caddy/v2/modules/metrics.(*AdminMetrics).serveHTTP(...)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/modules/metrics/adminmetrics.go:65\ngithub.com/caddyserver/caddy/v2.AdminHandlerFunc.ServeHTTP(0xc00064f618?, {0x1ee3d88?, 0xc000b4b020?}, 0x6?)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/admin.go:1291 +0x29\ngithub.com/caddyserver/caddy/v2.(*AdminConfig).newAdminHandler.func2.1({0x1ee3d88, 0xc000b4b020}, 0xc000a6bb00)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/admin.go:241 +0x7b\nnet/http.HandlerFunc.ServeHTTP(0x1ee41d8?, {0x1ee3d88?, 0xc000b4b020?}, 0xc000a9f400?)\n\tnet/http/server.go:2171 +0x29\ngithub.com/caddyserver/caddy/v2.(*AdminConfig).newAdminHandler.func1.instrumentHandlerCounter.1({0x1ee41d8?, 0xc000900000?}, 0xc000a6bb00)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/metrics.go:56 +0x6f\nnet/http.HandlerFunc.ServeHTTP(0xc000a61380?, {0x1ee41d8?, 0xc000900000?}, 0x7283bf?)\n\tnet/http/server.go:2171 +0x29\nnet/http.(*ServeMux).ServeHTTP(0xc000a61380?, {0x1ee41d8, 0xc000900000}, 0xc000a6bb00)\n\tnet/http/server.go:2688 +0x1ad\ngithub.com/caddyserver/caddy/v2.adminHandler.serveHTTP({0xc000a61380, 0x0, 0x1, {0xc000498c30, 0x3, 0x3}, 0x0}, {0x1ee41d8, 0xc000900000}, 0xc000a6bb00)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/admin.go:832 +0x55f\ngithub.com/caddyserver/caddy/v2.adminHandler.ServeHTTP({0xc000a61380, 0x0, 0x1, {0xc000498c30, 0x3, 0x3}, 0x0}, {0x1ee41d8, 0xc000900000}, 0xc000a6bb00)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/admin.go:784 +0x7ea\nnet/http.serverHandler.ServeHTTP({0xc000ab06f0?}, {0x1ee41d8?, 0xc000900000?}, 0x6?)\n\tnet/http/server.go:3142 +0x8e\nnet/http.(*conn).serve(0xc0009161b0, {0x1ee7a68, 0xc000ab05a0})\n\tnet/http/server.go:2044 +0x5e8\ncreated by net/http.(*Server).Serve in goroutine 447\n\tnet/http/server.go:3290 +0x4b4"} seafile-caddy | {"level":"info","ts":1747306886.9766183,"msg":"http: panic serving 127.0.0.1:44984: runtime error: invalid memory address or nil pointer dereference\ngoroutine 449 [running]:\nnet/http.(*conn).serve.func1()\n\tnet/http/server.go:1903 +0xbe\npanic({0x174fbe0?, 0x2b41d70?})\n\truntime/panic.go:770 +0x132\ngithub.com/caddyserver/caddy/v2/modules/metrics.(*AdminMetrics).serveHTTP(...)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/modules/metrics/adminmetrics.go:65\ngithub.com/caddyserver/caddy/v2.AdminHandlerFunc.ServeHTTP(0xc000803618?, {0x1ee3d88?, 0xc0004992d8?}, 0x6?)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/admin.go:1291 +0x29\ngithub.com/caddyserver/caddy/v2.(*AdminConfig).newAdminHandler.func2.1({0x1ee3d88, 0xc0004992d8}, 0xc0007f06c0)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/admin.go:241 +0x7b\nnet/http.HandlerFunc.ServeHTTP(0x1ee41d8?, {0x1ee3d88?, 0xc0004992d8?}, 0xc000a45800?)\n\tnet/http/server.go:2171 +0x29\ngithub.com/caddyserver/caddy/v2.(*AdminConfig).newAdminHandler.func1.instrumentHandlerCounter.1({0x1ee41d8?, 0xc0004aafc0?}, 0xc0007f06c0)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/metrics.go:56 +0x6f\nnet/http.HandlerFunc.ServeHTTP(0xc000a61380?, {0x1ee41d8?, 0xc0004aafc0?}, 0x7283bf?)\n\tnet/http/server.go:2171 +0x29\nnet/http.(*ServeMux).ServeHTTP(0xc000a61380?, {0x1ee41d8, 0xc0004aafc0}, 0xc0007f06c0)\n\tnet/http/server.go:2688 +0x1ad\ngithub.com/caddyserver/caddy/v2.adminHandler.serveHTTP({0xc000a61380, 0x0, 0x1, {0xc000498c30, 0x3, 0x3}, 0x0}, {0x1ee41d8, 0xc0004aafc0}, 0xc0007f06c0)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/admin.go:832 +0x55f\ngithub.com/caddyserver/caddy/v2.adminHandler.ServeHTTP({0xc000a61380, 0x0, 0x1, {0xc000498c30, 0x3, 0x3}, 0x0}, {0x1ee41d8, 0xc0004aafc0}, 0xc0007f06c0)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/admin.go:784 +0x7ea\nnet/http.serverHandler.ServeHTTP({0xc00049a270?}, {0x1ee41d8?, 0xc0004aafc0?}, 0x6?)\n\tnet/http/server.go:3142 +0x8e\nnet/http.(*conn).serve(0xc0004f47e0, {0x1ee7a68, 0xc000ab05a0})\n\tnet/http/server.go:2044 +0x5e8\ncreated by net/http.(*Server).Serve in goroutine 447\n\tnet/http/server.go:3290 +0x4b4"} seafile-caddy | {"level":"info","ts":1747306896.3099742,"logger":"docker-proxy","msg":"Sending configuration to","server":"localhost"} seafile-caddy | {"level":"info","ts":1747306896.3107483,"logger":"admin.api","msg":"received request","method":"POST","host":"localhost:2019","uri":"/load","remote_ip":"127.0.0.1","remote_port":"45296","headers":{"Accept-Encoding":["gzip"],"Content-Length":["1637"],"Content-Type":["application/json"],"User-Agent":["Go-http-client/1.1"]}} seafile-caddy | {"level":"info","ts":1747306896.3114996,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]} seafile-caddy | {"level":"error","ts":1747306896.3116972,"logger":"admin.api","msg":"request error","error":"loading config: loading new config: loading http app module: provision http: getting tls app: loading tls app module: provision tls: loading certificates: open /etc/caddy/certs/seafile.my.com_public.crt: no such file or directory","status_code":400} seafile-caddy | {"level":"error","ts":1747306896.3127728,"logger":"docker-proxy","msg":"Error response from server","server":"localhost","status code":400,"body":"{\"error\":\"loading config: loading new config: loading http app module: provision http: getting tls app: loading tls app module: provision tls: loading certificates: open /etc/caddy/certs/seafile.my.com_public.crt: no such file or directory\"}\n"} seafile-caddy | {"level":"info","ts":1747306896.3136718,"logger":"admin","msg":"stopped previous server","address":"localhost:2019"} seafile-caddy | {"level":"info","ts":1747306907.0612442,"msg":"http: panic serving 127.0.0.1:60986: runtime error: invalid memory address or nil pointer dereference\ngoroutine 400 [running]:\nnet/http.(*conn).serve.func1()\n\tnet/http/server.go:1903 +0xbe\npanic({0x174fbe0?, 0x2b41d70?})\n\truntime/panic.go:770 +0x132\ngithub.com/caddyserver/caddy/v2/modules/metrics.(*AdminMetrics).serveHTTP(...)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/modules/metrics/adminmetrics.go:65\ngithub.com/caddyserver/caddy/v2.AdminHandlerFunc.ServeHTTP(0xc000649618?, {0x1ee3d88?, 0xc000211188?}, 0x6?)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/admin.go:1291 +0x29\ngithub.com/caddyserver/caddy/v2.(*AdminConfig).newAdminHandler.func2.1({0x1ee3d88, 0xc000211188}, 0xc0001497a0)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/admin.go:241 +0x7b\nnet/http.HandlerFunc.ServeHTTP(0x1ee41d8?, {0x1ee3d88?, 0xc000211188?}, 0xc0008ffc00?)\n\tnet/http/server.go:2171 +0x29\ngithub.com/caddyserver/caddy/v2.(*AdminConfig).newAdminHandler.func1.instrumentHandlerCounter.1({0x1ee41d8?, 0xc000b12b60?}, 0xc0001497a0)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/metrics.go:56 +0x6f\nnet/http.HandlerFunc.ServeHTTP(0xc000b161a0?, {0x1ee41d8?, 0xc000b12b60?}, 0x7283bf?)\n\tnet/http/server.go:2171 +0x29\nnet/http.(*ServeMux).ServeHTTP(0xc000b161a0?, {0x1ee41d8, 0xc000b12b60}, 0xc0001497a0)\n\tnet/http/server.go:2688 +0x1ad\ngithub.com/caddyserver/caddy/v2.adminHandler.serveHTTP({0xc000b161a0, 0x0, 0x1, {0xc000010a80, 0x3, 0x3}, 0x0}, {0x1ee41d8, 0xc000b12b60}, 0xc0001497a0)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/admin.go:832 +0x55f\ngithub.com/caddyserver/caddy/v2.adminHandler.ServeHTTP({0xc000b161a0, 0x0, 0x1, {0xc000010a80, 0x3, 0x3}, 0x0}, {0x1ee41d8, 0xc000b12b60}, 0xc0001497a0)\n\tgithub.com/caddyserver/caddy/v2@v2.9.1/admin.go:784 +0x7ea\nnet/http.serverHandler.ServeHTTP({0xc0002eb1d0?}, {0x1ee41d8?, 0xc000b12b60?}, 0x6?)\n\tnet/http/server.go:3142 +0x8e\nnet/http.(*conn).serve(0xc0006b0750, {0x1ee7a68, 0xc000ab09c0})\n\tnet/http/server.go:2044 +0x5e8\ncreated by net/http.(*Server).Serve in goroutine 466\n\tnet/http/server.go:3290 +0x4b4"}
另外有时间的话可否出个dns挑战做caddy自动证书申请和续期的教程,惠及俺们这些小白,谢谢

open /etc/caddy/certs/seafile.my.com_public.crt: no such file or directory
证书文件不存在,问题在于你的证书名字和.env中设置的不同,
修改.env文件的CADDY_SSL_CERTIFICATE_CRT= 和 CADDY_SSL_CERTIFICATE_KEY= ,改成你的证书名字。

自动申请证书和续期的话,推荐一个开源项目,https://github.com/usual2970/certimate ,感觉很方便,上手也很容易,网址打不开的话多试几次,或者多换几个时间段试试,这个是没办法的,国内不定时屏蔽。

谢谢推荐,折腾了大半天,果然这个certimate方便。另外请问下

#编辑seahub_settings.py文件,在末尾添加,根据自己的实际情况修改网址及JWT密码
这里的seahub_settings.py这个文件的路径在什么位置。我用find没找到

安装目录/seafile-data/seafile/conf/seahub_settings.py

按楼主的方法折腾了两三天,seafile启动还是有问题,别外请教楼主.env文件是全部照搬你上面的内容还是要基于wget下来的文件参照修改?
麻烦楼主看看问题是出在了哪个

root@debian:/mnt/sdb/seafile# docker logs seafile
*** Running /etc/my_init.d/01_create_data_links.sh...
*** Booting runit daemon...
*** Runit started as PID 21
*** Running /scripts/enterpoint.sh...
2025-05-18 01:43:26 Nginx ready
2025-05-18 01:43:26 This is an idle script (infinite loop) to keep container running.
[2025-05-18 01:43:26] Skip running setup-seafile-mysql.py because there is existing seafile-data folder.
[05/18/2025 01:43:26][upgrade]: The container was recreated, start fix the media symlinks
mv: not replacing '/shared/seafile/seahub-data/avatars/default-non-register.jpg'
mv: not replacing '/shared/seafile/seahub-data/avatars/default.png'
mv: not replacing '/shared/seafile/seahub-data/avatars/groups'
[05/18/2025 01:43:26][upgrade]: Done

Starting seafile server, please wait ...
Seafile server started

Done.

Starting seahub at port 8000 ...
Error:Seahub failed to start.
Please try to run "./seahub.sh start" again
Traceback (most recent call last):
  File "/scripts/start.py", line 94, in <module>
    main()
  File "/scripts/start.py", line 80, in main
    call('{} start'.format(get_script('seahub.sh')))
  File "/scripts/utils.py", line 70, in call
    return subprocess.check_call(*a, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/subprocess.py", line 413, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '/opt/seafile/seafile-pro-server-12.0.13/seahub.sh start' returned non-zero exit status 1.