FileGator v7.16.8 Docker Compose 部署指南
用官方镜像 filegator/filegator:v7.16.8 从零部署 FileGator:compose 全文件、bind mount 初始化排障、首次登录改密、上传/下载/zip 批量下载与多用户隔离全链路验证,全部命令与回显实测(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 重定向至该版本;部署后经 APIGET /?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
三、前置条件
- 服务器已安装 Docker 与 Docker Compose v2(
docker compose version可执行)。 - 对外端口未被占用(本文用 8149):
ss -ltn | grep ':8149' || echo "8149 空闲"
实测回显(2026-10-30):
8149 空闲
- 规划数据目录。本文把全部宿主侧产物收敛在
tmp/filegator/下的部署目录中(与 compose 文件同目录放repository/、private/)。 - 下载镜像(官方源直连较慢时可走代理,本文实测直连拉取成功):
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 volumerepository:/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/repository | bind mount ./repository | 全部上传/创建的文件 |
| 用户库 | /var/www/filegator/private/users.json | bind 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_PORT | 8080 | Apache 监听端口(改它需同时改 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 均在宿主目录,跨小版本升级无损。
十二、常见问题
-
启动即报
Folder not writable: /private/logs/bind mount 覆盖了镜像内 private 初始化文件。按 4.3 补建logs/、sessions/、tmp/子目录并恢复users.json.blank等文件,属主 33:33。 -
页面 502/连接拒绝 确认映射的是容器内 8080(镜像固定监听口),不是 80;
docker compose ps看 PORTS 列应为0.0.0.0:8149->8080/tcp(实测形态)。 -
API POST 返回 HTTP 200 但空响应体 CSRF token 缺失或过期。每次 GET 后从响应头取最新
X-CSRF-Token并在 POST 回带;登录后必须重新取(会话已迁移)。应用日志private/logs/app.log会记录Csrf token not valid。 -
/login直接访问 404 官方镜像未带 URL 重写规则,API 一律走/?r=/端点查询参数形态(GET /?r=/getconfig实测 200)。这是配置services.Router.query_param的默认值。 -
上传报
Error storing file命令行直传缺少resumable*分块参数(前端协议必带),按 6.2 参数组补全。 -
zip/解压/新建文件返回 Failed 但结果已生效 v7.16.8 已知缺陷(控制器把无返回值的适配器调用判为失败),用
getdir或宿主目录复核真实结果;写自动化时按「返回值不可信、查目录为准」处理。 -
忘记 admin 密码 停栈后编辑宿主
private/users.json,把 password 字段整体删除恢复为users.json.blank的原始 hash(即 admin123),或直接用users.json.blank覆盖users.json后重启,再用默认密码登录改密。
十三、参考链接
- 官方仓库与 README(Quick start、默认账号说明):https://github.com/filegator/filegator (查询日期 2026-10-30)
- 官方 Dockerfile(镜像结构/端口/卷定义):https://github.com/filegator/filegator/blob/master/Dockerfile (查询日期 2026-10-30)
- 上游 compose 范式:https://github.com/filegator/filegator/blob/master/docker-compose.yml (查询日期 2026-10-30)
- Docker Hub tags:https://hub.docker.com/r/filegator/filegator/tags (查询日期 2026-10-30)
- 本专栏姊妹篇:《FileGator 介绍与选型指南》、《FileGator v7.16.8 配置参数详解》、《FileGator v7.16.8 API 使用详解》