Skip to main content

文档|Seafile 13 搭建记录

几年前搭建过一次nextcloud,php写的感觉很臃肿,印象不太好,前两天试用了一下Cloudreve,go语言写的,页面也很简洁,功能感觉一般般,安卓没有客户端,只有IOS有。听很多人推荐Seafile,在版本控制上功能很强大,就开始尝试搭建,我以为像Cloudreve一样docker一键运行,没想到花了我这么多时间。过程不易,记录一下搭建过程中遇到的问题。

目前的docker社区版的最新版本是13.0.8,官方搭建教程

数据库问题

因为我的服务器上已经有一个mysql服务了,版本是v9.3.0,所以不想再多冗余一个数据库,然后按照官方给的例子改,改了好几次,也确保正常连上数据库了,但是每次在启动的时候会报错,报错信息:

 Error happened during creating seafile admin.

然后我尝试使用官方给的创建管理员账户的命令:

peng@v2202506263508356183:~/app/seafile$ docker exec -it seafile /opt/seafile/seafile-server-latest/reset-admin.sh
Traceback (most recent call last):
File "/opt/seafile/seafile-server-13.0.8/seahub/manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/opt/seafile/seafile-server-13.0.8/seahub/thirdpart/django/core/management/__init__.py", line 442, in execute_from_command_line
utility.execute()
File "/opt/seafile/seafile-server-13.0.8/seahub/thirdpart/django/core/management/__init__.py", line 436, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/opt/seafile/seafile-server-13.0.8/seahub/thirdpart/django/core/management/base.py", line 412, in run_from_argv
self.execute(*args, **cmd_options)
File "/opt/seafile/seafile-server-13.0.8/seahub/thirdpart/django/core/management/base.py", line 458, in execute
output = self.handle(*args, **options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/seafile/seafile-server-13.0.8/seahub/seahub/base/management/commands/createsuperuser.py", line 88, in handle
User.objects.get(email=default_username)
File "/opt/seafile/seafile-server-13.0.8/seahub/seahub/base/accounts.py", line 259, in get
emailuser = ccnet_threaded_rpc.get_emailuser(email)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/seafile/seafile-server-13.0.8/seafile/lib/python3/site-packages/pysearpc/client.py", line 127, in newfunc
return fret(ret_str)
^^^^^^^^^^^^^
File "/opt/seafile/seafile-server-13.0.8/seafile/lib/python3/site-packages/pysearpc/client.py", line 65, in _fret_obj
raise SearpcError(dicts['err_msg'])
pysearpc.common.SearpcError: Database error

页面可以进,但是输入账户密码之后,就会出现错误。

最后用了官方配置里的mariadb:10.11。

https访问问题

落地服务器使用的是德国的,国内访问不是很稳定,所以我打算用西美的DMIT反代一下,提供相对稳定的访问速度。

  1. 使用默认的caddy

Seafile默认提供了caddy代理,也支持配置域名,一开始我配置了http,然后通过西美nginx提供https访问,但是登录的时候会出现跨域错误:

Forbidden (403)
CSRF verification failed. Request aborted.

More information is available with DEBUG=True.

折腾了好几次都不行,也许改seahub_settings.py配置和nginx配置可以解决,没有试我就换别的方案了。

  1. 去除caddy,直接使用nginx

按照官方的说明,去除了官方默认提供的caddy,直接将端口暴露出来,然后配合官方给的nginx配置进行修改。修改后任然出现跨域问题。

在社区论坛找到两种修复方法。

  1. 修改seahub_settings.py
# 进入容器
docker exec -it seafile /bin/bash
cd conf
seahub_settings.py
# -*- coding: utf-8 -*-
SECRET_KEY = "iwr_y$ac1=6*6%0h8$qnjee2zeql!)0o4%n2ggxc*l=vkkzxl2"

TIME_ZONE = 'Etc/UTC'

CSRF_TRUSTED_ORIGINS = ["https://pan.example.com"]

最后一行加上CSRF_TRUSTED_ORIGINS。

  1. 修改nginx配置
location / {
proxy_pass http://192.168.31.1:8084;
proxy_read_timeout 310s;
proxy_set_header Host $host:8084;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection "";
proxy_http_version 1.1;


client_max_body_size 0;
}

proxy_set_header Host $host:8084;上需要加上端口

修改后解决了跨域问题。

Seafile 13部署完整配置

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

## Images
SEAFILE_IMAGE=seafileltd/seafile-mc:13.0.8
SEAFILE_DB_IMAGE=mariadb:10.11
SEAFILE_REDIS_IMAGE=redis
SEADOC_IMAGE=seafileltd/sdoc-server:2.0-latest
NOTIFICATION_SERVER_IMAGE=seafileltd/notification-server:13.0-latest
MD_IMAGE=seafileltd/seafile-md-server:13.0-latest

## Persistent Storage
BASIC_STORAGE_PATH=/home/peng/app/seafile
SEAFILE_VOLUME=$BASIC_STORAGE_PATH/seafile-data
SEAFILE_MYSQL_VOLUME=$BASIC_STORAGE_PATH/seafile-mysql/db
SEADOC_VOLUME=$BASIC_STORAGE_PATH/seadoc-data

#################################
# Startup parameters #
#################################
SEAFILE_SERVER_HOSTNAME=pan.example.com
SEAFILE_SERVER_PROTOCOL=https
TIME_ZONE=Etc/UTC
JWT_PRIVATE_KEY=Jb&^WaHhpPG&1Z$2e0qa&#yvO&zSF@zc

#####################################
# Third-party service configuration #
#####################################

## Database
SEAFILE_MYSQL_DB_HOST=db
SEAFILE_MYSQL_DB_USER=seafile
SEAFILE_MYSQL_DB_PASSWORD=PASSWORD
SEAFILE_MYSQL_DB_CCNET_DB_NAME=ccnet_db
SEAFILE_MYSQL_DB_SEAFILE_DB_NAME=seafile_db
SEAFILE_MYSQL_DB_SEAHUB_DB_NAME=seahub_db

## Cache
CACHE_PROVIDER=redis # or memcached

### Redis
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=

### Memcached
MEMCACHED_HOST=memcached
MEMCACHED_PORT=11211

######################################
# Initial variables #
# (Only valid in first-time startup) #
######################################

## Database root password, Used to create Seafile users
INIT_SEAFILE_MYSQL_ROOT_PASSWORD=PASSWORD

## Seafile admin user
INIT_SEAFILE_ADMIN_EMAIL=me@example.com
INIT_SEAFILE_ADMIN_PASSWORD=PASSWORD

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

## SeaDoc service
ENABLE_SEADOC=true

## Notification
ENABLE_NOTIFICATION_SERVER=false
NOTIFICATION_SERVER_URL=

## Seafile AI
ENABLE_SEAFILE_AI=false
SEAFILE_AI_LLM_URL=
SEAFILE_AI_LLM_KEY=

## Metadata server
MD_FILE_COUNT_LIMIT=100000
seafile-server.yml
services:
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"
networks:
- seafile-net
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:-}
networks:
- seafile-net

seafile:
image: ${SEAFILE_IMAGE:-seafileltd/seafile-mc:13.0-latest}
container_name: seafile
restart: unless-stopped
ports:
- "8084:80"
volumes:
- ${SEAFILE_VOLUME:-/opt/seafile-data}:/shared
environment:
- 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}
- INIT_SEAFILE_MYSQL_ROOT_PASSWORD=${INIT_SEAFILE_MYSQL_ROOT_PASSWORD:-}
- 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}
- 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}
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
networks:
- seafile-net

networks:
seafile-net:
name: seafile-net
seadoc.yml
services:

seadoc:
image: ${SEADOC_IMAGE:-seafileltd/sdoc-server:2.0-latest}
container_name: seadoc
volumes:
- ${SEADOC_VOLUME:-/opt/seadoc-data/}:/shared
ports:
- "8085: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:-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}
depends_on:
db:
condition: service_healthy
networks:
- seafile-net

networks:
seafile-net:
name: seafile-net