Flarum是我用过的众多论坛程序里最有“现代感”的一个,轻量、优雅、扩展机制清晰,社区活跃度也一直在线。之前我在一台旧服务器上部署了它,用了大概两年多,数据和附件积累了不少,后来因为机房迁移和配置升级,不得不把整套环境搬到新机器上。当时就想着,与其手动装一遍PHP、Nginx、MySQL再慢慢调,不如直接走Docker,把构建、部署、迁移全部变成可复现的流程。这趟折腾下来,踩了一些坑,也总结出一套还算顺手的方案,今天把这套搭建加迁移的完整过程记录下来,给同样打算用Flarum建站、或者正在愁怎么搬家的人做个参考。
1. Flarum项目整体情况与Docker选型思路
1.1 Flarum本身是什么,它适合怎样的使用场景
Flarum是下一代论坛软件,国内用户喜欢叫它“流光论坛”,它的界面风格偏向Discourse那种现代扁平设计,但比Discourse轻得多。官方定位是“简洁、快速、响应式”,不追求大而全的功能堆砌,而是通过扩展机制来按需加功能。它基于PHP和MySQL/MariaDB,后端用了Laravel框架,前端是Mithril组件化的SPA架构,所以实际用起来会有一种很流畅的单页应用体验,切换版块、加载帖子的体感要比传统论坛舒服很多。
它的组织形式和传统论坛类似,有版块(Tags)、讨论帖(Discussions)、回复(Posts),但交互和权限设计更现代。适合的场景包括:技术社区、兴趣小组、企业内部交流平台、开源项目的用户论坛。如果你之前用过phpBB或Discuz,再来看Flarum,会觉得它是“现代化的那一种”。
我当初选它的原因主要有三个。第一,界面原生支持中文,不需要汉化包,而且对中文搜索的支持比很多轻量论坛好。第二,扩展机制非常成熟,从登录方式到SEO优化,从编辑器增强到数据统计,官方和社区都有大量现成插件。第三,它本身就推荐Composer来管理代码和扩展,这意味着整个站点可以用纯代码描述出来,配合Docker就能做到极致的可移植性。
1.2 为什么用Docker来跑Flarum,而不是直接在宿主机上装
很多人在接触Docker之前都会问一个问题:我直接apt install php-nginx mysql不就好了吗?为什么非要绕一层容器?我当时的答案是:因为你迟早要迁移、要升级、要重装系统,而Docker把这些都变成了“恢复备份再启动容器”这种简单的操作。
具体到Flarum这个项目,用Docker跑的优势非常明显。Flarum对运行环境不是没有要求,它需要PHP 8.1以上、需要pdo_mysql、gd、fileinfo、exif等一批扩展;需要Composer来管理核心代码和第三方扩展;需要Nginx或Apache做伪静态。如果你手动装,一套环境折腾下来少说也要一两个小时,而且不同Linux发行版的PHP包结构还有差异。而用Docker镜像,比如我用的flarum社区镜像,或自己基于php:8.1-fpm-alpine构建,这些依赖关系在镜像里就锁定了,宿主机只要装好Docker和Compose就行。
另外,Docker在迁移场景里更是把复杂度收敛了。旧服务器的数据库、附件、环境配置,迁移时只需要导出数据库、打包assets目录、把compose文件和nginx配置带过去,新服务器上执行两条命令就能恢复。这不只省时间,还减少了“手动装环境时漏了一个扩展导致论坛白屏”这类低级事故。
1.3 整体架构设计:哪些服务放进容器,哪些不放进容器
我的Flarum部署架构很简单,一共三个容器:Nginx负责HTTP服务和伪静态解析,PHP-FPM容器跑Flarum代码,MySQL容器存数据。另外加了一个Redis容器做缓存,以及一个Cron容器用来执行定时任务。
这里展开说说为什么这样拆。Nginx和PHP分离是PHP应用的标准做法,Flarum的请求流程是Nginx把PHP请求转发给FPM,PHP执行Laravel框架并访问MySQL,最终返回HTML或JSON。把Nginx单独放一个容器,方便独立改配置和调SSL证书。php-fpm容器单独放,是因为Flarum的PHP扩展要求比较特殊,装在一个容器里避免影响宿主机PHP版本。
MySQL用Docker跑有一个好处是数据目录用Volume挂载出来,备份时直接复制文件或者用mysqldump都能搞定。Redis在这里主要承担两件事:一是接管Flarum的缓存数据,二是给Session提供存储。Flarum官方支持Redis作为缓存驱动,配置好之后,页面响应速度会有明显提升。
Cron容器则是用来跑Flarum的定时任务的,这个很多人容易忽略。Flarum有些扩展依赖定时任务,比如邮件队列、搜索引擎索引更新。如果你不启动Cron,这些功能就会悄悄失效。
code复制容器服务结构:
- nginx(端口80/443,挂载站点目录与证书)
- php-fpm(运行Flarum代码与PHP扩展)
- mysql(数据持久化,挂载数据目录)
- redis(缓存与session)
- cron(定期任务)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Docker化部署Flarum的完整实操过程
2.1 准备目录结构与docker-compose配置
部署的第一步,我先在服务器上建好目录骨架。这个看起来不起眼,但目录结构设计得好,后面迁移和排查会省很多事。我的建议是按“应用名/服务名”来分,类似这样:
bash复制/data/flarum
├── compose.yaml
├── nginx/
│ ├── conf.d/
│ │ └── flarum.conf
│ └── ssl/ # 证书存放
├── php-fpm/
│ └── php.ini # 自定义PHP配置
├── app/ # Flarum代码
├── db/
│ └── data/ # MySQL数据卷
├── redis/
│ └── data/ # Redis持久化
└── backups/ # 备份输出目录
compose.yaml是整套Docker部署的核心文件。这里我选用了一个比较稳定的镜像组合:PHP用php:8.1-fpm-alpine作为基础镜像,Flarum代码通过Composer安装在app目录里。Nginx直接用官方镜像,MySQL用mysql:8.0,Redis用redis:7-alpine。
yaml复制services:
nginx:
image: nginx:1.27-alpine
container_name: flarum-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./app:/var/www/flarum:ro
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
depends_on:
- php-fpm
networks:
- flarum-net
php-fpm:
build:
context: .
dockerfile: Dockerfile
container_name: flarum-php
volumes:
- ./app:/var/www/flarum
environment:
- DB_HOST=mysql
- DB_PORT=3306
- DB_NAME=flarum
- DB_USER=flarum
- DB_PASSWORD=xxx
- REDIS_HOST=redis
depends_on:
- mysql
networks:
- flarum-net
mysql:
image: mysql:8.0
container_name: flarum-mysql
volumes:
- ./db/data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=xxx
- MYSQL_DATABASE=flarum
- MYSQL_USER=flarum
- MYSQL_PASSWORD=xxx
command:
- "--character-set-server=utf8mb4"
- "--collation-server=utf8mb4_unicode_ci"
networks:
- flarum-net
redis:
image: redis:7-alpine
container_name: flarum-redis
command: redis-server --appendonly yes
volumes:
- ./redis/data:/data
networks:
- flarum-net
cron:
image: flarum/flarum:latest
container_name: flarum-cron
volumes:
- ./app:/var/www/flarum
entrypoint: ["/bin/sh", "-c"]
command:
- |
while true; do
php /var/www/flarum/flarum schedule:run
sleep 300
done
depends_on:
- php-fpm
networks:
- flarum-net
volumes:
flarum-db:
driver: local
networks:
flarum-net:
driver: bridge
这里有几个细节必须特别说明。PHP容器我没有直接用现成镜像,而是写了一个Dockerfile,因为Flarum需要的PHP扩展比较多,有些扩展在官方镜像里没有,需要自己装。Dockerfile大概长这样:
dockerfile复制FROM php:8.1-fpm-alpine
RUN apk add --no-cache \
$PHPIZE_DEPS \
libpng libpng-dev \
libjpeg-turbo libjpeg-turbo-dev \
libwebp libwebp-dev \
freetype freetype-dev \
libzip libzip-dev \
oniguruma oniguruma-dev \
git unzip curl \
&& docker-php-ext-install pdo_mysql mysqli mbstring exif pcntl bcmath gd zip intl \
&& docker-php-ext-enable pdo_mysql opcache \
&& apk del $PHPIZE_DEPS
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/flarum
EXPOSE 9000
CMD ["php-fpm"]
建议把opcache开起来,Flarum在生产环境强烈建议启用OPcache扩展,它能把PHP中间码缓存在内存里,大幅提升并发处理能力。另外intl扩展在Flarum 1.8以上版本是必须的,如果你用的是旧教程,很可能漏了它。
我给Nginx配置伪静态规则,Flarum的要求是所有非静态文件请求都走index.php。这里直接给出我用的配置:
nginx复制server {
listen 80;
server_name your-domain.com;
root /var/www/flarum/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
expires 365d;
add_header Cache-Control "public, immutable";
try_files $uri =404;
}
}
2.2 构建镜像并安装Flarum核心代码
Deployment的第二步是用Composer安装Flarum核心代码。这一步有两个思路,你可以直接在docker-compose的php-fpm容器里用docker compose exec php-fpm composer create-project flarum/flarum /var/www/flarum来装,也可以像我这样先在本地装好再传到服务器上。考虑到国内网络环境,直接在服务器容器里执行Composer比较方便,你就用composer官方镜像或者容器里自带的composer,指定中国镜像源来加速。
bash复制docker compose build
docker compose run --rm php-fpm composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
docker compose run --rm php-fpm composer create-project flarum/flarum /var/www/flarum --stability=beta --prefer-dist
如果你遇到Composer下载慢或者包校验失败的情况,其实是镜像源不稳定导致的,换一下镜像源就能解决。安装完成后,Flarum会给出一段提示,需要你先在浏览器里打开域名执行安装向导,填写数据库信息和管理员账号。
但是注意,这里的“数据库信息”不要直接在安装向导里填Docker容器的IP或容器名,因为向导运行在浏览器端,它不知道容器内部的网络地址。这里有个小技巧,你需要在MySQL容器里先创建一个用户,或者使用你在compose里定义好的MYSQL_USER,然后在安装向导里填localhost或者你宿主机上映射出来的MySQL端口。我当时的做法是将MySQL的3306端口映射到宿主机127.0.0.1:3306,并在向导里填127.0.0.1,安装完成后把映射去掉。
这样做的好处是安装向导能顺利完成,但应用实际运行时还是要通过容器网络访问MySQL,所以安装完成后要把config.php里的数据库地址改成mysql。手动改一下/data/flarum/app/config.php即可,注意改完清一下缓存。
2.3 配置扩展、优化项与日常维护
Flarum装好后,安装扩展推荐用Composer命令来做。比如你想加一个“登录保护”插件,就执行:
bash复制docker compose exec php-fpm composer require flarum-auth-jwt
docker compose exec php-fpm php flarum migrate
docker compose exec php-fpm php flarum cache:clear
为什么每次装完扩展都要执行migrate?因为很多扩展会在数据库里建表或者修改字段,migrate命令就是执行这些数据库变更的。如果跳过这步,扩展虽然装上了,但实际使用时会报错。
日常维护里比较重要的一点是定期清理Flarum的缓存。Flarum的缓存机制是先把配置、路由、视图等编译成PHP文件存到storage目录,当你在后台修改配置、装扩展、改语言包之后,如果不清理缓存,前台往往不会即时生效。所以我把php flarum cache:clear记成了一条固定操作,改任何东西后都跑一遍。
另外建议给PHP设置一个合适的内存限制。Flarum本身不算很吃内存,但Composer安装扩展时如果memory_limit设置得太低会报“Allowed memory size of xxx bytes exhausted”错误,我直接把memory_limit=1G写到php.ini里,避免Composer和后台某些批量操作受到影响。
3. 关键数据备份与迁移实施记录
3.1 迁移前要明确“需要搬走什么”与“哪些数据容易漏”
这次迁移踩过最大的坑就是一开始想当然地以为“把整个app目录打包带走就行”,结果漏掉了数据库,幸好及时发现。实际上Flarum站点有三块数据需要分别处理,缺一样都不行。
第一块是MySQL数据库,里面存了用户、帖子、版块、权限、扩展配置这些核心内容。第二块是public/assets目录,存放用户上传的头像、附件、编辑器图片等。第三块是config.php和storage目录里的缓存文件,其中config.php记录了数据库连接信息、密钥和各个扩展的配置项。
这里特别要提醒的是public/assets极易漏掉。很多人打包时会习惯性地排除public目录,因为里面还有index.php这样的入口文件,总觉得不应该一起打包。但实际上Flarum的用户文件全部在public/assets下面,如果漏了它,迁移后论坛能打开、能登录,但所有历史附件都会404,用户的头像也会全部消失。这个恢复起来很难补,所以打包前一定要确认。
3.2 数据库备份与全量文件打包
数据库备份我用的方式是mysqldump,因为Flarum的数据库不算特别大,mysqldump生成的SQL文件可读性强,出了问题也容易排查。命令如下:
bash复制docker compose exec mysql sh -c 'mysqldump -uflarum -p"$MYSQL_PASSWORD" flarum' > backup_flarum_$(date +%Y%m%d).sql
注意上面命令里$MYSQL_PASSWORD是在容器环境里读取的,宿主机上不需要也不能手动填密码,否则密码会以明文形式出现在命令历史里。执行完检查一下SQL文件大小,如果是0字节,多半是容器内的shell变量没有传进去,改用-e方式执行。
文件备份我用tar直接打包整个app目录,但排除掉storage/cache、storage/tmp这些可以直接重建的缓存内容:
bash复制tar --exclude='app/storage/cache' \
--exclude='app/storage/tmp' \
-czf flarum_app_$(date +%Y%m%d).tar.gz -C /data/flarum app
把这些备份文件和数据库SQL文件放在同一个backups目录,再一起传走。传文件的工具我用的rsync而非scp,因为rsync支持断点续传,中途网络断了重新跑一遍就能继续,不必从头再来。对于迁移大目录如assets,这个特性极其重要。
3.3 新服务器上的恢复流程
新服务器上先安装好Docker和Compose,然后按2.1节相同的目录结构建好骨架。这里有个经验:compose文件、nginx配置这些尽量保持和旧服务器一致,不要在新机器上临时改端口或改路径,否则很容易把自己绕晕。恢复步骤如下:
- 把备份的SQL文件和tar包上传到新服务器的
/data/flarum/backups/ - 解压代码包到app目录
- 启动MySQL容器并导入数据库
- 启动php-fpm和nginx容器
- 修改config.php里的数据库地址和站点URL
- 清理缓存并确认站点正常
导入数据库这步我踩过一次坑。MySQL容器第一次启动时会自动创建数据库,但是这时候数据库是空的。如果你直接把SQL文件用docker compose exec -T mysql mysql flarum < backup.sql导入,没问题;但如果你是先登录容器再执行source命令,容器内可能找不到SQL文件,因为路径没挂载进去。所以我改成用标准输入方式:
bash复制docker compose exec -T mysql sh -c 'exec mysql -uflarum -p"$MYSQL_PASSWORD" flarum' < backup_flarum_20250101.sql
导入完成后,启动所有容器:
bash复制docker compose up -d
docker compose exec php-fpm php flarum cache:clear
这个时候打开网站应该已经能访问了,但我还建议做一件事:检查一下public/assets目录的属主和权限。如果新服务器上PHP容器内的uid和宿主机uid不一致,会出现附件目录不可写的情况。最简单的办法是统一以宿主机当前用户的uid运行php-fpm容器,或者在Dockerfile里使用--user参数。
3.4 域名和证书的迁移细节
如果论坛域名换了,迁移后需要改两处地方。第一处是config.php里的url配置,这个参数直接决定Flarum生成帖子和头像的绝对URL。第二处是后台的“基本设置”里的论坛地址。
code复制/config.php 中需要检查的项:
'url' => 'https://new-domain.com',
'database' => ['host' => 'mysql', 'database' => 'flarum', 'username' => 'flarum', 'password' => 'xxx'],
还有一个非常容易忽略的地方是Nginx的SSL证书路径。我旧服务器的证书是用certbot申请的,新服务器上我重新申请了证书,没有沿用旧证书,省去了证书过期和域名校验的问题。如果你不换域名,那直接把旧证书和私钥文件复制到/data/flarum/nginx/ssl/目录即可,注意保持文件名一致。
3.5 迁移后验证的关键指标
迁移后至少要验证以下几项,我一般会列一个清单照着打勾:
- 首页能否正常打开,样式和图片是否完整
- 登录旧账号是否成功,权限是否正常
- 发一条测试帖,看附件能不能传
- 检查后台设置里附件路径是否生效
- 查看旧帖子的头像和图片是否显示
- 检查邮件发送功能,因为有些邮件服务商的配置在迁移后会失效
其中附件上传和旧图片显示是排查重点。如果上传报错,优先看storage目录权限;如果旧图片404,优先看assets目录是否完整以及Nginx的伪静态配置是否正确。
4. 常见问题与排查技巧实录
4.1 数据库连接失败:SQLSTATE[HY000] [2002] Connection refused
这个问题在容器部署里非常常见,几乎每个从物理机转Docker的人都会遇到。原因是Flarum安装好后,config.php里记录的数据库地址还是安装向导里填的那个值,而迁移后容器网络环境变了,这个地址就失效了。
排查思路分三步。先docker compose exec php-fpm php -m确认PDO扩展存在,再docker compose exec php-fpm php -r "var_dump(@fsockopen('mysql', 3306));"检查容器是否能连通mysql宿主名,最后看compose文件里两个服务是否在同一个网络里。
如果确认是网络问题,多半是compose文件里没有为php-fpm和mysql添加同一个networks,或者MySQL容器的健康检查失败导致依赖没就绪。我在compose里给MySQL加了一个healthcheck,然后php-fpm通过depends_on.condition: service_healthy来等待数据库就绪,避免启动顺序问题。
4.2 迁移后页面白屏或提示“No such file or directory”
Flarum迁移后白屏,90%和storage目录有关。Flarum会把编译后的视图和缓存写到storage目录下,如果这个目录不可写,整个页面就会直接白掉,连错误信息都不显示。
这时候不要慌着改代码,先执行一下:
bash复制docker compose exec php-fpm sh -c 'chown -R www-data:www-data /var/www/flarum/storage'
docker compose exec php-fpm sh -c 'chmod -R 775 /var/www/flarum/storage'
如果还不行,改一下php-fpm容器的工作目录和启动用户,确保当前用户对app目录有完整读写权限。另一个容易忽略的是assets目录的storage/model子目录,这个在Flarum里存放的是文件上传时生成的小尺寸缩略图,迁移后如果不复现,会导致图片显示异常。
4.3 扩展安装后报错,是否应该回滚
Flarum扩展装多了,偶尔会碰到某个扩展不兼容当前版本的情况。我遇到的典型例子是装了一个旧的“Google Analytics”扩展后,后台直接白屏。这时候不要急,进入容器禁用掉这个扩展即可:
bash复制docker compose exec php-fpm php flarum extension:disable 扩展包名
docker compose exec php-fpm php flarum cache:clear
如果你记不住扩展包名,可以用php flarum extension:list查看已安装扩展列表。如果连命令行都跑不了,那就只能编辑config.php里的extensions数组,把出问题的扩展移除,删掉对应的php flarum migrate记录,再把备份的原始config.php恢复回去。
我的建议是生产环境上不要安装太多非必要扩展,尤其不要轻易装那种“最近两个月内没有更新”的扩展,因为Flarum的迭代速度很快,扩展API变化也快,旧扩展很容易出问题。实在要用,先在staging环境测过再上生产。
4.4 Docker镜像下载慢或拉取失败的处理
Flarum相关的几个镜像体积都不小,php:8.1-fpm-alpine大概100多MB,mysql:8.0大概500多MB。在服务器上第一次拉取时,如果发现速度慢得像蜗牛,多半是默认拉取的是官方Docker Hub镜像源。
解决办法是配置镜像加速器。Docker daemon的配置文件在/etc/docker/daemon.json,往里面加一段加速地址:
json复制{
"registry-mirrors": ["https://docker.m.daocloud.io"]
}
改完重启Docker服务:
bash复制sudo systemctl restart docker
这一步只对后续拉取生效,之前已经下载了一半的镜像建议删掉重新拉。另外我建议把常用镜像通过docker pull预先拉到服务器上,构建时用FROM引用本地镜像,这样即使后续网络出问题也不会影响部署。
4.5 迁移后论坛时区不对、定时任务不执行
Flarum默认时区是UTC,如果你不设置,论坛时间显示会比北京时间早8个小时。配置方式是在后台的“通用”设置里把时区改为Asia/Shanghai,同时PHP容器里的时区也要改。我是在Dockerfile里直接设置了时区环境变量:
dockerfile复制ENV TZ=Asia/Shanghai
RUN apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone
定时任务不执行则要检查Cron容器是否在运行。我用的方式比较直接,在compose里加了一个独立的cron容器,循环每300秒执行一次php flarum schedule:run。如果你发现有些定时任务没生效,用docker compose logs cron查看日志,看是不是PHP环境变量缺失导致脚本报错。
4.6 常见问题速查表
为了方便查阅,我把遇到过的问题整理成一个速查表:
| 症状 | 可能原因 | 排查/解决方法 |
|---|---|---|
| 页面白屏 | storage目录不可写 | chown/chmod storage目录 |
| 数据库连接失败 | config.php地址不对 | 改为mysql容器名并清缓存 |
| 附件404 | assets目录缺失 | 恢复public/assets目录 |
| 图片上传失败 | 目录权限/存储驱动不对 | 检查storage/model及权限 |
| 扩展装完报错 | 版本不兼容 | 用extension:disable禁用并清缓存 |
| 定时任务不执行 | cron容器未启动 | 检查cron容器和日志 |
| 时间显示不对 | 时区配置缺失 | 设置TZ环境变量和后台时区 |
| 镜像拉取慢 | 镜像源问题 | 配置registry-mirrors加速 |
| PHP内存不足 | memory_limit过低 | php.ini设memory_limit=1G |
| Composer超时 | 镜像源不稳定 | 换国内composer镜像源 |
5. 迁移和容灾的一些后续优化建议
5.1 把备份做成自动化定时任务
这次手动迁移之后,我明显感觉到备份这件事不能靠“记住了才做”。Flarum站点虽然轻量,但丢了数据依然会很痛苦。所以后来我把备份做成了宿主机上的一个定时脚本,每天凌晨执行一次数据库备份,每周执行一次全量备份,然后通过rsync同步到另一台机器或对象存储。
bash复制#!/bin/bash
BACKUP_DIR=/data/flarum/backups
DATE=$(date +%Y%m%d)
docker compose exec -T mysql sh -c 'exec mysqldump -uflarum -p"$MYSQL_PASSWORD" flarum' > "$BACKUP_DIR/db_$DATE.sql"
find "$BACKUP_DIR" -name "db_*.sql" -mtime +7 -delete
脚本里用find -mtime +7 -delete自动清理7天前的旧备份,避免备份文件无限膨胀。如果你的磁盘空间够大,也可以把保留周期拉长到30天。
5.2 善用Docker标签锁定版本
Flarum本身升级比较频繁,但迁移到新环境后,我特意把compose里所有镜像都加上了具体的版本标签,而不是用latest。因为latest镜像每次拉取可能会变,今天部署的Flarum和明天部署的可能就是两个不同的版本,迁移时不容易复现。
版本锁定后,升级时只需要更新一下compose文件里的镜像标签,再重新构建php-fpm容器,然后执行php flarum migrate清理并检查扩展兼容性,升级过程就变得非常可控。这个习惯是踩过一次坑才养成的,之前用latest,某天拉了一个新版本镜像,结果和已装的旧扩展完全不兼容,赶紧回滚才恢复正常。
5.3 善用Docker标签锁定版本
另外还想提一个关于磁盘规划的问题。很多人部署时习惯把Docker的数据目录放在系统盘上,比如/var/lib/docker,但系统盘空间往往有限,一旦MySQL数据目录和assets目录增长起来,很容易把系统盘塞满。我这次迁移时特意把整个Flarum的数据目录挂到了单独的数据盘上,这样即使系统崩溃,数据也还有救。
具体做法是修改Docker的data-root配置,或者直接把compose里的volume路径指向数据盘挂载点。我选的后者,因为更直观,也方便备份。迁移后我建议你检查一下df -h,确认宿主机磁盘空间充足,再跑几次大附件上传测试,看看有没有“磁盘空间不足”的隐患。
5.4 给容灾留一条后路
最后说一个关于“容灾后路”的话题。Docker部署最大的一个好处就是迁移成本低,所以不要满足于“迁移成功”这一个结果,建议你顺便验证一下“从零恢复”的流程。做法很简单:找一台干净的机器,把backups目录里的文件拖过去,按第3.3节的步骤重新部署一遍,看看能不能恢复出一个能正常访问的站点。
我当时做了一次模拟恢复,意外发现assets目录里有个隐藏的.htaccess文件在打包时被漏掉了,还有storage/formatter目录里的缓存需要特殊处理。如果没有提前做模拟恢复,真到需要灾备的那一天才暴露问题,就晚了。所以,强烈建议你完成迁移后花一小时做一次“恢复演练”,这样可以确保备份方案是真实有效的,而不是只是形式主义。
回看这趟Flarum的Docker化部署和迁移经历,最深的体会是:容器化解决的是环境一致性问题,而数据备份解决的是安全性的问题。这两个问题分开看都不难,但组合在一起就成了论坛运维里的核心命题。我现在已经习惯把“改配置、清缓存、查日志”这三步当成任何一次Flarum操作的固定节奏,迁移后验证也不再只看首页能不能开,而是认真走一遍发帖传图、登录改密、后台设置这些完整链路。另外,回到开头提到的那个问题——为什么选Docker,我在这次迁移后更坚定了答案:Docker给了站点一把“复制”的钥匙,只要镜像、代码、数据三者齐备,任何一个地方都能快速再搭建出一个同样的论坛。最后分享一个小技巧,如果你也跟我一样要搬家,记得先在旧服务器上把docker compose exec php-fpm php flarum cache:clear执行一遍再打包代码,清掉缓存后的代码包体积更小,而且恢复时能避免很多莫名其妙的旧缓存冲突。
