FileGator v7.16.8 Docker Compose 部署指南

用官方镜像 filegator/filegator:v7.16.8 从零部署 FileGator:compose 全文件、bind mount 初始化排障、首次登录改密、上传/下载/zip 批量下载与多用户隔离全链路验证,全部命令与回显实测(2026-10-30)。

FileGatorFileGator文件分享2026/10/30

FileGator v7.16.8 Docker Compose 部署指南

目标:在一台 Ubuntu 22.04 服务器上,用官方镜像 filegator/filegator:v7.16.8 从零部署 FileGator,完成首次登录、修改默认密码、文件上传、下载与批量打包下载(分享)的全链路验证。全部命令与回显均在 2026-10-30 于 Ubuntu 22.04 实机实测通过。

一、环境信息

本文实测所用的服务器环境与软件版本如下(查询/实测日期 2026-10-30):

  • 操作系统:Ubuntu 22.04(x86_64)
  • FileGator 版本:v7.16.8(官方最新稳定版,来源 GitHub Releases releases/latest 于 2026-10-30 重定向至该版本;部署后经 API GET /?r=/getconfig 返回的 app_version: 7.16.8 交叉确认)
  • 镜像:filegator/filegator:v7.16.8(约 320MB;镜像内 Apache/2.4.69 + PHP/8.3.36,启动日志实测)
  • Docker:24.x 与 Docker Compose v2(docker compose 子命令形态)
  • Web 对外端口:8149(映射到容器内 Apache 的 8080;官方示例为 8080,可按需改映射)
  • 数据目录:部署目录下的 repository/(文件存储根)与 private/(用户库/日志/会话/临时区)两个 bind mount 子目录
  • 默认管理员账号:admin / admin123(官方 README 写明「login as admin/admin123」;注意不是 admin/admin,首启后立即改密)
  • 版本背景与选型对比见 《FileGator 介绍与选型指南》

二、镜像选型说明

FileGator 官方唯一维护的镜像仓库是 Docker Hub 的 filegator/filegator(来源 Docker Hub 实查,2026-10-30)。镜像 tag 有三条流:

tag 流说明本文选择
vX.Y.Z版本定版,对应 GitHub Release(v7.16.8 约 320MB)✅ 采用
latest跟随最新稳定版(2026-10-30 实查指向 v7.16.8 同一构建)可用于尝鲜,生产建议锁版本
vX.Y.Z-multiarch多架构变体(amd64/arm64,约 862MB)需 arm64 时选用

另有 v8.0.0-beta.1(2026-10-27 推送)为下一个大版本预发布,本文不采用。

镜像内部结构(来源官方 Dockerfile 与容器内实查,2026-10-30):

  • 基底 php:8.3-apache(Debian),Apache 监听 8080(镜像内置环境变量 APACHE_PORT=8080),站点根指向 /var/www/filegator/dist/
  • 应用代码位于 /var/www/filegator/,运行用户 www-data(uid/gid 33)
  • 两个声明卷:/var/www/filegator/repository(文件存储根)与 /var/www/filegator/private(用户库 users.json、日志、会话、上传临时区)
  • 镜像内 private/ 预置了三个初始化文件:users.json.blank(内置 admin/guest 两个账号定义)、.htaccess(内容 deny from all,拒绝 Web 直接访问)、.gitignore;首次访问应用时自动复制为 users.json

三、前置条件

  1. 服务器已安装 Docker 与 Docker Compose v2(docker compose version 可执行)。
  2. 对外端口未被占用(本文用 8149):
ss -ltn | grep ':8149' || echo "8149 空闲"

实测回显(2026-10-30):

8149 空闲
  1. 规划数据目录。本文把全部宿主侧产物收敛在 tmp/filegator/ 下的部署目录中(与 compose 文件同目录放 repository/、private/)。
  2. 下载镜像(官方源直连较慢时可走代理,本文实测直连拉取成功):
docker pull filegator/filegator:v7.16.8

实测回显(节选):

Status: Downloaded newer image for filegator/filegator:v7.16.8
docker.io/filegator/filegator:v7.16.8

四、部署步骤

4.1 Compose 全文件

在部署目录创建 docker-compose.yml(显式 name 项目名,避免与其他栈同名互删):

name: filegator-v7.16.8-stack

services:
  filegator:
    image: filegator/filegator:v7.16.8
    container_name: filegator-v7.16.8-web
    restart: unless-stopped
    ports:
      - "8149:8080"
    volumes:
      - ./repository:/var/www/filegator/repository
      - ./private:/var/www/filegator/private
    networks:
      - filegator-net

networks:
  filegator-net:
    name: filegator-v7.16.8-net
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.56.0/24

文件要点:

  • 端口映射 8149:8080:宿主 8149 是对外入口,8080 是镜像内 Apache 固定监听口。
  • 两个 bind mount 对应镜像声明的两个卷;相比上游官方 compose 的 named volume 写法,bind mount 便于直接在宿主侧查看与备份文件(两种写法均官方支持,上游 docker-compose.yml 用 named volume repository:/private:)。
  • 容器以 www-data(uid 33)运行,宿主侧目录属主要同步改为 33,否则启动即报权限错误(见 4.3)。

4.2 启动与状态确认

mkdir -p repository private
chown -R 33:33 repository private
docker compose up -d
docker compose ps

实测回显(2026-10-30):

 Network filegator-v7.16.8-net Created
 Container filegator-v7.16.8-web Creating
 Container filegator-v7.16.8-web Created
 Container filegator-v7.16.8-web Starting
 Container filegator-v7.16.8-web Started
NAME                    IMAGE                         COMMAND                  SERVICE     CREATED         STATUS         PORTS
filegator-v7.16.8-web   filegator/filegator:v7.16.8   "docker-php-entrypoi…"   filegator   6 seconds ago   Up 6 seconds   80/tcp, 0.0.0.0:8149->8080/tcp, [::]:8149->8080/tcp

启动日志确认 PHP 运行时:

[Fri Oct 30 06:26:42.093803 2026] [mpm_prefork:notice] [pid 1:tid 1] AH00163: Apache/2.4.69 (Debian) PHP/8.3.36 configured -- resuming normal operations

4.3 首启排障:bind mount 覆盖初始化文件(重要)

使用 bind mount 时,空的宿主目录会覆盖镜像内 private/ 的预置文件,首次访问报错(实测):

Folder not writable: /private/logs/

补齐镜像内的初始化结构后恢复正常——创建 logs/、sessions/、tmp/ 三个子目录,并把镜像内的 users.json.blank、.htaccess、.gitignore 拷到宿主 private/:

mkdir -p private/logs private/sessions private/tmp
docker run --rm filegator/filegator:v7.16.8 cat /var/www/filegator/private/users.json.blank > private/users.json.blank
docker run --rm filegator/filegator:v7.16.8 cat /var/www/filegator/private/.htaccess      > private/.htaccess
docker run --rm filegator/filegator:v7.16.8 cat /var/www/filegator/private/.gitignore     > private/.gitignore
chown -R 33:33 private

users.json.blank 内容(镜像内实查,2026-10-30)内置两账号:

{"1":{"username":"admin","name":"Admin","role":"admin","homedir":"\/","permissions":"read|write|upload|download|batchdownload|zip|chmod","password":"$2y$10$Nu35w4pteLfc7BDCIkDPkecjw8wsH8Y2GMfIewUbXLT7zzW6WOxwq"},"2":{"username":"guest","name":"Guest","role":"guest","homedir":"\/","permissions":"","password":""}}

💡 技术拓展:bind mount 与 named volume 的这一差异值得记住——named volume 首次挂载时会把镜像内该路径的既有文件「播种」到卷里,而 bind mount 直接以宿主目录内容为准、不播种。对 FileGator 这类「镜像内预置初始化文件」的应用,用 named volume 更省心;用 bind mount 则要像上面那样手动补种一次(一次性动作,之后 users.json 等都在宿主目录里可管理)。

4.4 首页验证

curl -s -o /dev/null -w "HTTP:%{http_code} bytes:%{size_download}\n" http://127.0.0.1:8149/

实测回显:

HTTP:200 bytes:653

返回的 HTML 即 Vue 前端入口(<title>FileGator</title>),浏览器打开 http://<服务器IP>:8149 进入登录页。

五、首次登录与改密

5.1 默认账号登录

浏览器访问 http://<服务器IP>:8149,用 admin / admin123 登录(官方 README 明确写法)。命令行等价验证(先 GET 拿 CSRF token,再 POST 登录):

TOKEN=$(curl -s -i -c cookies.txt "http://127.0.0.1:8149/?r=/getuser" | grep -i 'x-csrf-token' | tr -d '\r' | awk '{print $2}')
curl -s -b cookies.txt -c cookies.txt -X POST "http://127.0.0.1:8149/?r=/login" \
  -H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" \
  -d '{"username":"admin","password":"admin123"}'

实测回显:

{"data":{"role":"admin","permissions":["read","write","upload","download","batchdownload","zip","chmod"],"homedir":"\/","username":"admin","name":"Admin"}}

5.2 修改密码为强口令

登录态下(浏览器右上角菜单 → Change password;命令行如下):

TOKEN=$(curl -s -i -b cookies.txt -c cookies.txt "http://127.0.0.1:8149/?r=/getuser" | grep -i 'x-csrf-token' | tr -d '\r' | awk '{print $2}')
curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/changepassword" \
  -H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" \
  -d '{"oldpassword":"admin123","newpassword":"q1w2e3r4"}'

实测回显(成功返回当前用户对象):

{"data":{"role":"admin","permissions":["read","write","upload","download","batchdownload","zip","chmod"],"homedir":"\/","username":"admin","name":"Admin"}}

同时宿主侧 private/users.json 的 password 字段变为新 bcrypt 串($2y$10$CLGlz4ODG4TW3...,实测变化),验证改密已落盘。用旧密码登录返回 {"data":"Login failed, please try again"}、新密码登录成功,双向确认。

⚠️ 命令行调 API 有个坑:登录会刷新会话(session migrate),改密前必须在登录后的同一会话上重新 GET 一次拿新 CSRF token,否则请求返回 HTTP 200 但空响应体、日志记 Csrf token not valid。

六、上传、下载与分享验证

6.1 建文件与写内容(savecontent)

curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/savecontent" \
  -H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" \
  -d '{"directory":"/","name":"hello.md","content":"# FileGator 实测文件\n这是 B2 部署验证写入的内容。\n"}'

实测回显 {"data":"Done"};getdir 列目录确认:

{"data":{"location":"\/","files":[{"type":"file","path":"\/hello.md","name":"hello.md","size":66,"time":1793341898,"permissions":644}]}}

6.2 上传文件(分块协议参数)

FileGator 前端用 resumable.js 风格的分块上传协议,命令行模拟时需要带全 resumable* 参数:

printf 'upload test file for FileGator B2 verification.\nline2: 2026-10-30\n' > upload-test.txt
curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/upload" \
  -H "X-CSRF-Token: $TOKEN" \
  -F 'file=@upload-test.txt' \
  -F 'resumableFilename=upload-test.txt' \
  -F 'resumableRelativePath=/' \
  -F 'resumableChunkNumber=1' \
  -F 'resumableTotalChunks=1' \
  -F 'resumableTotalSize=52' \
  -F 'resumableIdentifier=uploadtesttxt52jpeg'

实测回显:

{"data":"Stored"}

宿主侧 repository/upload-test.txt(66 字节)同步可见。漏掉 resumable* 参数直接 -F file=@... 会报 {"data":"Error storing file"}(实测踩坑)。

6.3 下载(base64 path)

下载端点的 path 参数是 base64 编码的文件路径:

B64=$(printf '/upload-test.txt' | base64 -w0)
curl -s -b cookies.txt -o dl-out.txt -w "HTTP:%{http_code} bytes:%{size_download} type:%{content_type}\n" \
  "http://127.0.0.1:8149/?r=/download&path=$B64"
cat dl-out.txt

实测回显:

HTTP:200 bytes:66 type:text/plain;charset=UTF-8
upload test file for FileGator B2 verification.
line2: 2026-10-30

传未编码参数(如 ?file=/upload-test.txt)会 302 重定向回首页(实测)。

6.4 打包下载(zip)与批量下载分享

多选文件打包 zip:

curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/zipitems" \
  -H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" \
  -d '{"items":[{"type":"file","path":"/hello.md"},{"type":"file","path":"/upload-test.txt"}],"destination":"/","name":"archive.zip"}'

批量下载(先 POST 建 archive 拿 uniqid,再 GET 拉取 zip):

curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/batchdownload" \
  -H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" \
  -d '{"items":[{"type":"file","path":"/hello.md"},{"type":"file","path":"/upload-test.txt"}]}'

实测回显:

{"data":{"uniqid":"8ec8dc043ce18598179884728d72fa942237dfcdefdfa72918bbe5ce68d6d7be"}}
curl -s -b cookies.txt -o batch-out.zip -w "HTTP:%{http_code} bytes:%{size_download} type:%{content_type}\n" \
  "http://127.0.0.1:8149/?r=/batchdownload&uniqid=8ec8dc043ce18598179884728d72fa942237dfcdefdfa72918bbe5ce68d6d7be"
file batch-out.zip

实测回显:

HTTP:200 bytes:351 type:application/octet-stream
batch-out.zip: Zip archive data, at least v2.0 to extract, compression method=store

⚠️ 两个实测边角(写自动化脚本时注意):① items 必须是对象数组([{"type","path"}...]),传纯路径字符串数组会触发 PHP Warning 甚至 Fatal;② v7.16.8 的 zipitems/unzipitem/createnew(file) 返回 {"data":"Failed"} 但操作实际已成功(zip 文件生成、文件已创建/解压)——这是该版本控制器对无返回值函数取反的缺陷,以 getdir 复核结果为准。

6.5 多用户隔离验证(管理员建号)

curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/storeuser" \
  -H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" \
  -d '{"username":"dev1","name":"Dev One","role":"user","homedir":"/docs","permissions":["read","write","upload","download"],"password":"q1w2e3r4"}'

实测回显:

{"data":{"role":"user","permissions":["read","write","upload","download"],"homedir":"\/docs","username":"dev1","name":"Dev One"}}

用 dev1 登录后 getdir 只能看到 /docs 内文件(homedir 隔离实测生效),且 listusers 等管理端点对其返回无权限。

七、数据持久化说明

数据位置持久化方式说明
文件存储/var/www/filegator/repositorybind mount ./repository全部上传/创建的文件
用户库/var/www/filegator/private/users.jsonbind mount ./private改密/建号即写此文件(实测改密后 hash 变化)
日志/var/www/filegator/private/logs/app.log同上登录失败/CSRF 拒绝/异常堆栈
会话与临时区/var/www/filegator/private/sessions、private/tmp同上分块上传临时件与打包临时件(默认 2 天 GC)

备份策略:停写窗口内直接打包这两个宿主目录即可整体迁移(tar czf filegator-backup.tgz repository private);恢复即解包还原属主 chown -R 33:33。

八、环境变量表

官方镜像无需必填环境变量,内置变量仅控制 Apache 行为(来源 Dockerfile,2026-10-30):

变量默认值作用
APACHE_PORT8080Apache 监听端口(改它需同时改 ports 映射,一般不动)
APACHE_DOCUMENT_ROOT/var/www/filegator/dist/站点根(固定指向前端构建产物)

应用行为全部由 configuration.php 控制(见下节),不走环境变量。

九、配置文件挂载

配置文件是 /var/www/filegator/configuration.php。镜像首启时若发现该文件不存在,会自动从 configuration_sample.php 复制一份(源码 dist/index.php 内置逻辑,实测确认)。要自定义配置时,把样例文件落到宿主目录再整体挂载覆盖:

    volumes:
      - ./configuration.php:/var/www/filegator/configuration.php:ro
      - ./repository:/var/www/filegator/repository
      - ./private:/var/www/filegator/private

生成初始样例(从容器里拷出):

docker run --rm filegator/filegator:v7.16.8 cat /var/www/filegator/configuration.php > configuration.php
chown 33:33 configuration.php

逐域参数详解见 《FileGator v7.16.8 配置参数详解》。

十、等价 docker run

与上述 compose 等价的单命令(临时验证用,--rm 退出即删):

docker run -d --name filegator-v7.16.8-web \
  -p 8149:8080 \
  -v /opt/data/quzuo/tmp/filegator/filegator-v7.16.8-stack/repository:/var/www/filegator/repository \
  -v /opt/data/quzuo/tmp/filegator/filegator-v7.16.8-stack/private:/var/www/filegator/private \
  filegator/filegator:v7.16.8

注意单独 docker run 不会创建 compose 网络,多服务编排或固定子网诉求仍建议用 compose 文件管理。

十一、常用运维命令

均在部署目录(含 docker-compose.yml)执行,以下为实测可用命令清单:

docker compose ps                  # 栈状态(实测 STATUS Up)
docker compose logs --tail 50      # 最近日志(Apache 访问日志在此可见)
docker compose restart             # 重启应用(会话失效,数据不受影响)
docker compose down                # 停栈并删网络(bind mount 数据保留在宿主目录)
docker compose up -d               # 再次拉起

升级到新版(示例 v7.16.9 发布后):改 docker-compose.yml 的 image tag → docker compose pull && docker compose up -d;users.json 与 repository 均在宿主目录,跨小版本升级无损。

十二、常见问题

  1. 启动即报 Folder not writable: /private/logs/ bind mount 覆盖了镜像内 private 初始化文件。按 4.3 补建 logs/、sessions/、tmp/ 子目录并恢复 users.json.blank 等文件,属主 33:33。

  2. 页面 502/连接拒绝 确认映射的是容器内 8080(镜像固定监听口),不是 80;docker compose ps 看 PORTS 列应为 0.0.0.0:8149->8080/tcp(实测形态)。

  3. API POST 返回 HTTP 200 但空响应体 CSRF token 缺失或过期。每次 GET 后从响应头取最新 X-CSRF-Token 并在 POST 回带;登录后必须重新取(会话已迁移)。应用日志 private/logs/app.log 会记录 Csrf token not valid。

  4. /login 直接访问 404 官方镜像未带 URL 重写规则,API 一律走 /?r=/端点 查询参数形态(GET /?r=/getconfig 实测 200)。这是配置 services.Router.query_param 的默认值。

  5. 上传报 Error storing file 命令行直传缺少 resumable* 分块参数(前端协议必带),按 6.2 参数组补全。

  6. zip/解压/新建文件返回 Failed 但结果已生效 v7.16.8 已知缺陷(控制器把无返回值的适配器调用判为失败),用 getdir 或宿主目录复核真实结果;写自动化时按「返回值不可信、查目录为准」处理。

  7. 忘记 admin 密码 停栈后编辑宿主 private/users.json,把 password 字段整体删除恢复为 users.json.blank 的原始 hash(即 admin123),或直接用 users.json.blank 覆盖 users.json 后重启,再用默认密码登录改密。

十三、参考链接