docker部署seafile(个人详细版本) 1.首先安装docker与dockercompose 在线安装或者离线安装都可以 离线安装docker要使其成为系统级的服务,需要手动编写配置文件才能用systemctl命令对其进行操作
1 vim /etc/systemd/system/docker.service
创建并写入以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 [Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network-online.target firewalld.service Wants=network-online.target [Service] Type=notify ExecStart=/usr/bin/dockerd --selinux-enabled=false -H unix:///var/run/docker.sock ExecReload=/bin/kill -s HUP $MAINPID LimitNOFILE=1048576 LimitNPROC=65536 LimitCORE=infinity TimeoutStartSec=0 Delegate=yes KillMode=process Restart=on-failure StartLimitBurst=3 StartLimitInterval=60s [Install] WantedBy=multi-user.target
创建daemon.json文件:
1 2 3 4 5 6 7 8 9 10 11 # mkdir -p /etc/docker && mkdir -p /dcdata/docker vim /etc/docker/daemon.json # { "data-root": "/dcdata/docker", "bip":"172.31.0.1/24" } # 规定docker内部网络ip段,是因为如果不规定,可能会生成与现在内网ip相同的段
给服务授权:
1 2 chmod 755 /etc/systemd/system/docker.service chmod 755 /etc/docker/daemon.json
以下是配置文件结构说明:(ai)
一、[Unit] 区块:定义服务的元数据和依赖关系
用于描述服务的基本信息、启动顺序和依赖的其他系统组件。
Description=Docker Application Container Engine服务的描述信息,说明这是 Docker 容器引擎服务。
Documentation=https://docs.docker.com指向 Docker 官方文档的链接,便于管理员查阅相关说明。
After=network-online.target firewalld.service定义服务的启动顺序:Docker 必须在 network-online.target(网络完全就绪)和 firewalld.service(防火墙服务)启动之后 才启动,避免因网络未就绪或防火墙未加载导致的问题。
Wants=network-online.target表示 Docker 服务 “希望”network-online.target 启动(但不强制依赖),即使该目标未启动,Docker 仍可尝试启动(软依赖)。
二、[Service] 区块:定义服务的运行规则
核心区块,指定 Docker 守护进程的启动命令、运行参数、资源限制等。
Type=notify服务类型为 notify:表示 dockerd 启动完成后会主动通知 systemd “已就绪”,systemd 收到通知后才会认为服务启动成功(确保服务完全就绪后再继续后续流程)。
ExecStart=/usr/bin/dockerd --selinux-enabled=false -H unix:///var/run/docker.sock启动命令 :指定 Docker 守护进程的执行路径和参数。
/usr/bin/dockerd:Docker 守护进程的可执行文件路径。
--selinux-enabled=false:禁用 SELinux 支持(SELinux 是 Linux 安全模块,部分场景下可能与 Docker 冲突,禁用可简化配置)。
-H unix:///var/run/docker.sock:指定 Docker 守护进程的通信端点为 Unix 套接字(/var/run/docker.sock),Docker 客户端(如 docker 命令)通过该套接字与守护进程通信。
ExecReload=/bin/kill -s HUP $MAINPID重载命令 :当执行 systemctl reload docker 时,通过发送 HUP 信号(挂起信号)给 Docker 主进程($MAINPID),触发守护进程重新加载配置(无需重启服务)。
LimitNOFILE=1048576限制 Docker 进程可打开的最大文件描述符数量(1048576),避免因文件描述符不足导致服务异常。
LimitNPROC=65536限制 Docker 进程可创建的最大进程数(65536),防止进程数过多导致系统资源耗尽。
LimitCORE=infinity允许 Docker 进程生成核心转储文件(core dump)的大小不受限制,便于调试服务崩溃问题(核心转储文件包含进程崩溃时的内存状态)。
TimeoutStartSec=0禁用服务启动超时限制(0 表示无超时),因为 Docker 启动可能需要较长时间(尤其首次启动或容器较多时)。
Delegate=yes允许 Docker 守护进程管理自身的子进程(如容器进程)的资源控制(如 CPU、内存限制),将部分权限委托给 Docker,提升容器资源管理的灵活性。
KillMode=process当执行 systemctl stop docker 时,仅终止 Docker 主进程(dockerd),而不强制终止其所有子进程(容器进程),避免误杀容器(容器可独立于守护进程运行)。
Restart=on-failure定义服务故障时的重启策略:仅当 Docker 守护进程非正常退出(如崩溃)时,systemd 才会自动重启它(正常退出时不重启)。
StartLimitBurst=3限制单位时间内的最大重启次数:60 秒内最多重启 3 次,防止服务陷入无限重启循环。
StartLimitInterval=60s与 StartLimitBurst 配合,定义计数重启次数的时间窗口(60 秒)。
三、[Install] 区块:定义服务的安装配置
指定服务在系统启动时的激活方式(即是否随系统自动启动)。
1 WantedBy=multi-user.target
表示当系统启动到multi-user.target
(多用户命令行模式,非图形界面)时,Docker 服务会被自动激活(随系统启动)。
multi-user.target是 Linux 系统的基本运行级别,确保 Docker 在系统启动早期即可可用。
/opt/seafile目录是默认存储Seafile docker compose文件的目录
可以自己更改
Seafile 使用两个 Docker 卷 来保存其数据库和 Seafile Docker 容器中生成的数据。卷的主机路径分别是/opt/seafile-mysql和/opt/seafile-data
Seafile 和 Nginx(其他反向代理工具也是) 的所有配置和日志文件都存储在 Seafile 容器的卷中。
2.使用wget命令获取各个配置文件的模板 1 2 3 4 wget -O .env https://manual.seafile.com/12.0/repo/docker/ce/env wget https://manual.seafile.com/12.0/repo/docker/ce/seafile-server.yml wget https://manual.seafile.com/12.0/repo/docker/caddy.yml wget https://manual.seafile.com/12.0/repo/docker/seadoc.yml
内网服务器环境可以自己传
关于JWT认证 如果想使用JWT私钥 可以下载pwgen
1 2 3 4 yum install pwgen #centos apt install pwgen #ubuntu pwgen -s 40 1 //是一个用于生成随机密码的命令
之后复制生成的JWT密钥 写在.env这个配置文件里
ps:onlyoffice是单独的一个服务,最好另外再生成一串密钥
之后会在拉取完镜像之后在某个.py的配置脚本里添加(.env中onlyoffice的配置也是要写的)
3 .env与yml配置文件的内容编写 以下是配置文件的详解与具体配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 # 我新建了一个data目录 将容器的数据卷都放在了data目录下(实际编写时不应该写注释) COMPOSE_FILE='seafile-server.yml,caddy.yml,seadoc.yml' COMPOSE_PATH_SEPARATOR=',' SEAFILE_IMAGE=seafileltd/seafile-mc:12.0-latest #指定 Seafile 主服务(含 Web 界面、文件存储核心等)的 Docker 镜像 SEAFILE_DB_IMAGE=mariadb:10.11 #指定 Seafile 所使用的数据库服务镜像 SEAFILE_MEMCACHED_IMAGE=memcached:1.6.29 #指定缓存服务 Memcached 的 Docker 镜像 SEAFILE_CADDY_IMAGE=lucaslorentz/caddy-docker-proxy:2.9-alpine #指定反向代理服务 Caddy 的 Docker 镜像 # OnlyOffice 配置 ONLYOFFICE_IMAGE=onlyoffice/documentserver:7.3.3 ONLYOFFICE_PORT=8082 ONLYOFFICE_JWT_SECRET=MHVRce4bp8g4AyOUT98oEsYrVVexREqfXuUEFYRG SEAFILE_VOLUME=/data/seafile-data #指定 Seafile 主服务的数据存储路径 SEAFILE_MYSQL_VOLUME=/data/seafile-mysql/db #指定 MariaDB 数据库的数据存储路径 SEAFILE_CADDY_VOLUME=/data/seafile-caddy #指定 Caddy 反向代理的数据存储路径 //以下是数据库的参数配置 SEAFILE_MYSQL_DB_HOST=db INIT_SEAFILE_MYSQL_ROOT_PASSWORD=Ew5r********f1CYz SEAFILE_MYSQL_DB_USER=seafile SEAFILE_MYSQL_DB_PASSWORD=Ew5rP******h2f1CYz TIME_ZONE=Asia/Shanghai #时区 JWT_PRIVATE_KEY=FjMDpUVCVpCH7OgLAY5dbmWt0jtaOEZwZMDm6MGH #填写使用工具生成的JWT密钥 SEAFILE_SERVER_HOSTNAME=10.XX.XX.102 #填写真实的IP地址 SEAFILE_SERVER_PROTOCOL=http #web服务的协议 INIT_SEAFILE_ADMIN_EMAIL=admin@xxx.work #默认的管理员邮箱 密码 自定义 INIT_SEAFILE_ADMIN_PASSWORD=se7sw@6N~nlCaN SEADOC_IMAGE=seafileltd/sdoc-server:1.0-latest #指定运行 SeaDoc 服务所使用的 Docker 镜像 SEADOC_VOLUME=/data/seadoc-data #指定SeaDoc服务所使用的存储路径 ENABLE_SEADOC=true #启用 SeaDoc 服务 NOTIFICATION_SERVER_IMAGE=seafileltd/notification-server:12.0-latest #指定运行通知服务器所使用的 Docker 镜像。 NOTIFICATION_SERVER_VOLUME=/data/notification-data #指定通知服务器的数据存储路径
上述配置将seafile的功能全都启用了
另外几个配置文件的数据卷的目录 也要与.env里的一致
这里没有使用统一配置的dockecompose.yml 而是对其进行拆分 再使用.env文件对yml里的参数进行定义 例如下配置文件中的一些参数(从 Seafile Docker 12.0开始,就需要使用四个配置文件.env, seafile-server.yml, caddy.yml和 seadoc.yml 。)
配置caddy.yml(反向代理)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 # 示例配置 与.env 中的数据卷路径配置一致 services: caddy: image: ${SEAFILE_CADDY_IMAGE:-lucaslorentz/caddy-docker-proxy:2.9-alpine} container_name: seafile-caddy restart: unless-stopped ports: - 80:80 - 443:443 environment: - CADDY_INGRESS_NETWORKS=seafile-net volumes: - /var/run/docker.sock:/var/run/docker.sock - ${SEAFILE_CADDY_VOLUME:-/data/seafile-caddy}:/data/caddy 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 services: seadoc: image: ${SEADOC_IMAGE:-seafileltd/sdoc-server:1.0-latest} container_name: seadoc restart: always volumes: - ${SEADOC_VOLUME:-/data/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:-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.@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 networks: - seafile-net networks: seafile-net: name: seafile-net
配置seafile-server.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 services: db: image: ${SEAFILE_DB_IMAGE:-mariadb:10.11} container_name: seafile-mysql restart: always environment: - MYSQL_ROOT_PASSWORD=${INIT_SEAFILE_MYSQL_ROOT_PASSWORD:-} - MYSQL_LOG_CONSOLE=true - MARIADB_AUTO_UPGRADE=1 volumes: - "${SEAFILE_MYSQL_VOLUME:-/data/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.29} container_name: seafile-memcached restart: always entrypoint: memcached -m 256 networks: - seafile-net onlyoffice: image: ${ONLYOFFICE_IMAGE} container_name: onlyoffice restart: always environment: - JWT_ENABLED=true - JWT_SECRET=${ONLYOFFICE_JWT_SECRET} - JWT_HEADER=Authorization ports: - "${ONLYOFFICE_PORT}:80" networks: - seafile-net seafile: image: ${SEAFILE_IMAGE:-seafileltd/seafile-mc:12.0-latest} container_name: seafile restart: always # ports: # - "80:80" volumes: - ${SEAFILE_VOLUME:-/data/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:-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 labels: caddy: ${SEAFILE_SERVER_PROTOCOL:-http}://${SEAFILE_SERVER_HOSTNAME:?Variable is not set or empty} caddy.reverse_proxy: "{{upstreams 80}}" depends_on: db: condition: service_healthy memcached: condition: service_started networks: - seafile-net networks: seafile-net: name: seafile-net
4.容器操作 .拉取所需镜像
1 2 3 4 5 6 7 docker pull seafileltd/seafile-mc:12.0-latest docker pull mariadb:10.11 docker pull memcached:1.6.29 docker pull onlyoffice/documentserver:7.3.3 #onlyoffice docker pull lucaslorentz/caddy-docker-proxy:2.9-alpine #反向代理 docker pull seafileltd/sdoc-server:1.0-latest #文档服务镜像 docker pull seafileltd/notification-server:12.0-latest #拉这个是因为配置了通知服务
在使用docker拉取完所需镜像过后 可以直接使用命令生成所拉取镜像的离线包
1 docker save -o xxxx.tar xxxx
这样在新的机器上部署可以不用配置docker的镜像加速直接上传镜像的离线包导入镜像
要对这些离线包进行归档以后再上传
镜像导入完成后,在配置文件编写的目录启动服务
之后查看容器运行状态
如有问题 启动失败之类的 查看日志 根据日志中具体哪个组件的报错进行分析
1 docker-compose logs -f --tail=200
停止某服务
以上部署好了所有的的功能(包括onlyoffcie)。
注:onlyoffcie设置 再拉取 启动服务之后。挂在数据的目录下会出现这几个目录:
1 seadoc-data seafile seafile-caddy seafile-data seafile-mysql
进入seafile-data目录修改一个配置文件
1 vim /data/seafile-data/seafile/conf/seahub_settings.py
在文件末尾添加以下配置:
1 2 3 4 5 6 7 8 9 ENABLE_ONLYOFFICE = True VERIFY_ONLYOFFICE_CERTIFICATE = False ONLYOFFICE_APIJS_URL = 'http://你部署的服务的机器ip以及onlyoffice服务的端口号/web-apps/apps/api/documents/api.js' ONLYOFFICE_FILE_EXTENSION = ('doc' , 'docx' , 'ppt' , 'pptx' , 'xls' , 'xlsx' ) ONLYOFFICE_EDIT_FILE_EXTENSION = ('docx' , 'pptx' , 'xlsx' ) ONLYOFFICE_JWT_SECRET = '你单独生成的JWT密钥' ONLYOFFICE_JWT_HEADER = 'Authorization'
重启容器:
1 2 docker-compose restart seafile docker-compose restart onlyoffice
登录seafile并使用
ps:如果onlyoffcie提示未授权 检查onlyffcie容器日志输出,一般是JWT密钥配置没有与.env文件中的匹配
(部署完成了一个初步安全可用的seafile)