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

最新的12版本新增了seadoc并且界面美观,官方的安装教程很简洁,也许有人会使用自己申请的证书来部署网站,参考论坛分享的经验,把自己的配置文件分享给大家。

首先说一下基本网络环境,有公网ip4地址(纯ipv6对seadoc和onlyoffice支持不友好),并且有一个自己的域名,路由器具有端口转发功能,防火墙相应的端口要开放。下面把完整的配置文件贴出来,直接复制保存下来,相对比官方文件做了一些修改,所以这五个文件要全部保存下来,然后根据自己的配置修改 .env 文件中有 # 中文注释的项目。

.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        #此处设置Seafile网站使用 http 还是 https
SEAFILE_SERVER_HOSTNAME=seafile.example.com        #此处设置Seafile服务的域名或IP地址
CADDY_CERT_PATH=$SEAFILE_CADDY_VOLUME/certs
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_JWT_SECRET=密码        #此处密码应与上边的JWT密码相同

############################################
# Additional configurations for extensions #
############################################

### Storage type
SS_STORAGE_TYPE=disk # options: disk (local disk), s3

### Local storage mode
SS_MAX_OBJ_CACHE_SIZE=10GB

### Log
SS_LOG_TO_STDOUT=false
SS_LOG_OUTPUT=true
SS_LOG_LEVEL=info

### S3 mode
SS_S3_USE_V4_SIGNATURE=false
SS_S3_ACCESS_ID=<your access id>
SS_S3_ACCESS_SECRET=<your access secret>
SS_S3_ENDPOINT=s3.us-east-1.amazonaws.com
SS_S3_BUCKET=<your bucket name>
SS_S3_USE_HTTPS=true
SS_S3_PATH_STYLE_REQUEST=true
SS_S3_AWS_REGION=us-east-1
SS_S3_SSE_C_KEY=<your SSE-C key>

### SeaSearch admin user
INIT_SS_ADMIN_USER=$INIT_SEAFILE_ADMIN_EMAIL
INIT_SS_ADMIN_PASSWORD=$INIT_SEAFILE_ADMIN_PASSWORD

caddy.yml

services:

  caddy:
    image: ${SEAFILE_CADDY_IMAGE:-lucaslorentz/caddy-docker-proxy:ci-alpine}
    container_name: seafile-caddy
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
      - ${SEAFILE_SERVER_PORT:-7777}:443
    environment:
      - CADDY_INGRESS_NETWORKS=seafile-net
    labels:
      caddy.auto_https: "disable_certs"
    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
    networks:
      - seafile-net
    healthcheck:
      test: ["CMD-SHELL", "curl --fail http://localhost:2019/metrics || exit 1"]
      start_period: 20s
      interval: 20s
      timeout: 5s
      retries: 3

networks:
  seafile-net:
    name: seafile-net

seadoc.yml

services:

  seadoc:
    image: ${SEADOC_IMAGE:-seafileltd/sdoc-server:1.0-latest}
    container_name: seadoc
    restart: unless-stopped
    volumes:
      - ${SEADOC_VOLUME:-/opt/seadoc-data/}:/shared
    # ports:
    #   - "80:80"
    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:-Asia/Shanghai}
      - JWT_PRIVATE_KEY=${JWT_PRIVATE_KEY:?Variable is not set or empty}
      - NON_ROOT=${NON_ROOT:-false}
      - SEAHUB_SERVICE_URL=${SEAFILE_SERVER_PROTOCOL:-http}://${SEAFILE_SERVER_HOSTNAME:?Variable is not set or empty}:${SEAFILE_SERVER_PORT:?Variable is not set or empty}
    labels:
      caddy: ${SEAFILE_SERVER_PROTOCOL:-http}://${SEAFILE_SERVER_HOSTNAME:?Variable is not set or empty}
      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: "/seadoc/*"
      caddy.2_handle_path.0_rewrite: "* {uri}"
      caddy.2_handle_path.1_reverse_proxy: "{{upstreams 80}}"
    depends_on:
      db:
        condition: service_healthy
    networks:
      - seafile-net

networks:
  seafile-net:
    name: seafile-net

seafile-server.yml

services:
  db:
    image: ${SEAFILE_DB_IMAGE:-mariadb:10.11.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"
    networks:
      - seafile-net
    healthcheck:
      test:
        [
          "CMD",
          "/usr/local/bin/healthcheck.sh",
          "--connect",
          "--mariadbupgrade",
          "--innodb_initialized",
        ]
      interval: 20s
      start_period: 30s
      timeout: 5s
      retries: 10

  memcached:
    image: ${SEAFILE_MEMCACHED_IMAGE:-memcached:1.6.38}
    container_name: seafile-memcached
    restart: unless-stopped
    entrypoint: memcached -m 256
    networks:
      - seafile-net

  elasticsearch:
    image: ${SEAFILE_ELASTICSEARCH_IMAGE:-elasticsearch:8.18.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"
    networks:
      - seafile-net

  seafile:
    image: ${SEAFILE_IMAGE:-seafileltd/seafile-pro-mc:12.0-latest}
    container_name: seafile
    restart: unless-stopped
    # ports:
      # - "80:80"
      # - "443:443"
    volumes:
      - ${SEAFILE_VOLUME:-/opt/seafile-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_ROOT_PASSWD=${INIT_SEAFILE_MYSQL_ROOT_PASSWORD:-}
      - 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:-Asia/Shanghai}
      - 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_PORT:?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}:${SEAFILE_SERVER_PORT:?Variable is not set or empty}/seadoc
      - INIT_S3_STORAGE_BACKEND_CONFIG=${INIT_S3_STORAGE_BACKEND_CONFIG:-false}
      - INIT_S3_COMMIT_BUCKET=${INIT_S3_COMMIT_BUCKET:-}
      - INIT_S3_FS_BUCKET=${INIT_S3_FS_BUCKET:-}
      - INIT_S3_BLOCK_BUCKET=${INIT_S3_BLOCK_BUCKET:-}
      - INIT_S3_KEY_ID=${INIT_S3_KEY_ID:-}
      - INIT_S3_SECRET_KEY=${INIT_S3_SECRET_KEY:-}
      - INIT_S3_USE_V4_SIGNATURE=${INIT_S3_USE_V4_SIGNATURE:-true}
      - INIT_S3_AWS_REGION=${INIT_S3_AWS_REGION:-us-east-1}
      - INIT_S3_HOST=${INIT_S3_HOST:-us-east-1}
      - INIT_S3_USE_HTTPS=${INIT_S3_USE_HTTPS:-true}
    labels:
      caddy: ${SEAFILE_SERVER_PROTOCOL:-http}://${SEAFILE_SERVER_HOSTNAME:?Variable is not set or empty}
      caddy.tls: /etc/caddy/certs/${CADDY_SSL_CERTIFICATE_CRT} /etc/caddy/certs/${CADDY_SSL_CERTIFICATE_KEY} 
      caddy.reverse_proxy: "{{upstreams 80}}"
    depends_on:
      db:
        condition: service_healthy
      memcached:
        condition: service_started
      elasticsearch:
        condition: service_started
    networks:
      - seafile-net

networks:
  seafile-net:
    name: seafile-net

onlyoffice.yml

services:

  onlyoffice:
    image: ${ONLYOFFICE_IMAGE:-onlyoffice/documentserver:latest}
    container_name: onlyoffice
    restart: unless-stopped
    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}
      - TIME_ZONE=${TIME_ZONE:-Asia/Shanghai}
      - JWT_ENABLED=true
      - JWT_SECRET=${ONLYOFFICE_JWT_SECRET:?Variable is not set or empty}
    ports:
      - ${ONLYOFFICE_PORT:-6233}:443
    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
      - ${ONLYOFFICE_VOLUME:-/opt/onlyoffice}/db:/var/lib/postgresql
    networks:
      - seafile-net

networks:
  seafile-net:
    name: seafile-net

根据自己的配置修改 .env 文件中的项目,准备工作完成,开始部署

docker compose pull      #拉取或更新镜像
docker compose up -d
######################################################

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

# 复制自己的ssl证书到onlyoffice目录,必须重命名为onlyoffice.crt和onlyoffice.key
mkdir /opt/seafile-12/onlyoffice/data/certs
cp 证书.crt /opt/seafile-12/onlyoffice/data/certs/onlyoffice.crt
cp 证书.key /opt/seafile-12/onlyoffice/data/certs/onlyoffice.key
chmod 400 /opt/seafile-12/onlyoffice/data/certs/onlyoffice.key

# 赋予 elasticsearch 的 data 目录 777 权限,否则搜索功能失效
chmod 777 -R /opt/seafile-12/seafile-elasticsearch/data

######################################################

编辑 /opt/seafile-12/seafile-data/seafile/conf/seahub_settings.py 文件,添加以下内容,并根据自己的配置修改seafile.example.com和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密码'

######################################################

docker compose stop
docker compose up -d
docker exec onlyoffice supervisorctl start ds:example

部署完成,顺利的话现在就可以访问你的Seafile网站了。

感谢楼主无私分享,但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.

你这个一定是配置目录出现了问题,需要参照修改的,我重新编辑了贴子,不用wget下载官方的了,直接复制我的配置内容保存修改对应的项目就可以了,你再试试。

感谢楼主的耐心指导,终于是可以在web使用https访问了web页面了但是有个问题:就是在公网上web页面上传文件的时候会提示网络错误。并且web配置页上的头像图标显示也是异常的,下载文件也是会提示:拒绝连接这是怎么回事?
但是在内网环境的话在路由器上做个域名转内网地址解析的话就正常了。
之前在旧版seafile上可以在web的配置页修改端口号,这12版的应该怎么弄?

不清楚你的具体配置,不过看你的描述应该是内外网混用的,这个情况caddy不好配置,最好是只配置公网域名,内网访问依赖路由器的nat环回来实现。
修改端口也是在 安装目录/seafile-data/seafile/conf/seahub_settings.py 文件中

是内外网混用的环境。配置文件的配置全是用的公网域名。你可以理解为就算不要内网,公网上现在不正常

那上传不正常唯一的可能就是上传地址不正确了,看看seahub_settings.py中的地址和你配置的是否一样,另外你重新部署的时候原来的文件夹删除了吗?还是覆盖安装的?

原来的都删除了的。这里以我的知识也是没发现有问题

root@debian:/mnt/sdb/seafile-12/seafile-data/seafile/conf# cat seahub_settings.py
# -*- coding: utf-8 -*-
SECRET_KEY = "我的密钥"
SERVICE_URL = "http://我的域名.com:"

ENABLE_ONLYOFFICE = True
ONLYOFFICE_APIJS_URL = 'https://我的域名.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 = '我的key"
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'seahub_db',
        'USER': 'seafile',
        'PASSWORD': '我的密码',
        'HOST': 'db',
        'PORT': '3306',
        'OPTIONS': {'charset': 'utf8mb4'},
    }
}


CACHES = {
    'default': {
        'BACKEND': 'django_pylibmc.memcached.PyLibMCCache',
        'LOCATION': 'memcached:11211',
    },
    'locmem': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
    },
}
COMPRESS_CACHE_BACKEND = 'locmem'

TIME_ZONE = 'Asia/Shanghai'
FILE_SERVER_ROOT = 'https://我的域名.com:/seafhttp'
root@debian:/mnt/sdb/seafile-12/seafile-data/seafile/conf#

FILE_SERVER_ROOT = ‘https://我的域名.com:/seafhttp’
很明显多了一个:号,这种情况是因为你用的443端口,比较高级,一般域名都不给开放443端口的,那你修改一下.env的
SEAFILE_SERVER_HOSTNAME=seafile.example.com:$SEAFILE_SERVER_PORT
把后边的:$SEAFILE_SERVER_PORT删除,注意那个:号,然后注释掉SEAFILE_SERVER_PORT=这一项即可。

或者你直接把 FILE_SERVER_ROOT = 'https://我的域名.com:/seafhttp’修改成
FILE_SERVER_ROOT = 'https://我的域名.com/seafhttp’也可以,其他配置应该没有影响。

没有,我是按你的配置文件改了一些自己个性的东西的,我的443也是被封的,行,我把这个冒号先去掉再试试,谢谢

那你的FILE_SERVER_ROOT = ‘https://我的域名.com:/seafhttp’,这一项中为什么没有端口号呢,我刚才重新部署了一次,没有问题的,这一项应该有端口号

把几个配置文件都检查了下,发现是在.env里面多的这个冒号。已经删除,并且把容器down掉后再启动了,还是不行,请问是否需要把seaffile-data seafyle-mysql 这两个目录删除再部署?

最好是把整个目录都删除掉然后重新部署,感觉 docker compose 不会覆盖已存在的文件