SMF 2.1.8 Docker Compose 部署指南
用 Docker Compose(php-apache + MariaDB)部署 SMF 2.1.8 全程实测:下载与包布局修正、安装向导五步、登录发帖验证、安全收尾与维护模式,含 FAQ。
SMF 2.1.8 Docker Compose 部署指南
目标:在装有 Docker 的服务器上以 Docker Compose 部署 SMF(Simple Machines Forum)2.1.8 论坛,覆盖自建运行环境镜像、官方安装向导、数据库初始化、数据持久化与日常运维命令。已在 Ubuntu 24.04.5 LTS(x86_64)+ Docker 29.9.2 + Docker Compose v5.6.1 环境实测通过(2026-11-02)。
一、环境信息
- 操作系统:Ubuntu 24.04.5 LTS(x86_64)
- Docker:29.9.2(
docker --version) - Docker Compose:v5.6.1(
docker compose version) - 软件版本:SMF 2.1.8(官方最新稳定版,GitHub tag
v2.1.8,2026-10-11 发布,2026-11-02 查询) - 运行环境:自建镜像
smf-web:2.1.8(基础镜像php:8.2-apache,实测 PHP 8.2.35)+ 官方镜像mariadb:11.4(实测 11.4.13-MariaDB-ubu2404) - 服务器 IP:192.168.1.172(示例环境实际地址,下同)
- 端口规划:宿主机 8138 → Web 服务 80
- 部署目录:
/opt/smf/(compose 文件、Dockerfile 与论坛源码目录html/同置) - 自定义网络:
smf-net,显式子网10.89.64.0/24 - compose 项目名:
name: smf-2.1.8-stack(注意:Compose 会把项目名中的点号剥掉,实际项目名落地为smf-218-stack,网络/卷前缀随之,见「十一、常见问题」Q1) - 演示账号:论坛管理员
admin,密码q1w2e3r4,邮箱admin@quzuo.net
二、镜像选型说明
SMF 官方不发布任何 Docker 镜像,官网只提供 PHP 源码包(zip/tar.gz)。社区镜像仓库中存在若干第三方 SMF 镜像,但更新节奏滞后于官方 2.1.x 补丁线、且多绑定旧版 PHP。因此本文采用「自建 php-apache 运行环境镜像 + 官方源码包 bind mount」的形态:
| 组件 | 镜像 | 理由 |
|---|---|---|
| Web/PHP | 自建 smf-web:2.1.8(FROM php:8.2-apache) | 官方源码包是纯 PHP,只需带齐 SMF 需要的扩展;PHP 8.2 处于官方支持矩阵(2.1.5+ 支持 7.1.0–8.4.0) |
| 数据库 | 官方 mariadb:11.4 | SMF 2.1 支持 MySQL/MariaDB/Percona,MariaDB LTS 镜像维护活跃 |
自建镜像只装运行环境,不把源码打进镜像——SMF 的升级、后台「软件包」安装都会直接改写源码目录,bind mount 形态才允许这些操作落盘持久化。
SMF 2.1.8 对运行环境的硬性要求(来自官方包 other/requirements.md,2026-11-02 查询):
- PHP ≥ 7.1.0(2.1.5 起支持至 8.4.0);
- 必需扩展:
mysqli(或pgsql)、pcre、json、session;推荐扩展:gd(头像/缩略图)、curl/openssl(包服务器与外链预览)、zip、zlib; - 数据库:MySQL 5.6+ / MariaDB 10+ / PostgreSQL(2.1 支持但非主流路径,本文用 MariaDB)。
三、前置条件
- 服务器已安装 Docker 与 Compose 插件:
docker --version
docker compose version
实测回显:
Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1
- 宿主机 8138 端口未被占用(
ss -ltn | grep 8138无输出); - 服务器可拉取 Docker Hub 镜像(本文环境守护进程已配置代理,见下文下载说明)。
四、部署步骤
4.1 获取 SMF 2.1.8 源码包
官方发布包由 download.simplemachines.org 提供,但该端点对非浏览器请求返回 403(Cloudflare 拦截),curl 直取不可行。可用的等价渠道是官方 GitHub 仓库的 tag 归档(内容与发布包同源,仓库即 SimpleMachines/SMF):
mkdir -p /opt/smf && cd /opt/smf
# 直连 GitHub 超时,本环境经代理下载成功(实测 1.9s):
curl -fsSL -x http://192.168.1.72:7897 -m 180 \
-o SMF_2.1.8.tar.gz https://github.com/SimpleMachines/SMF/archive/refs/tags/v2.1.8.tar.gz
ls -lh SMF_2.1.8.tar.gz
sha256sum SMF_2.1.8.tar.gz
实测回显:
-rw-r--r-- 1 root root 3.2M Nov 2 17:16 SMF_2.1.8.tar.gz
e71819b5d9516c4ecea5e46957c13a37d6a751908c36ad6715e54636917862bc SMF_2.1.8.tar.gz
⚠️ 网络说明:2026-11-02 实测本环境直连 GitHub 120s 超时、任务书给定代理 192.168.1.62:7897 不可达,最终经代理 192.168.1.72:7897 下载成功。服务器网络不受限时可去掉
-x参数直连。
4.2 解压并整理为「发布包布局」
GitHub tag 归档是开发仓库布局:安装向导 install.php、升级脚本 upgrade.php、配置模板 Settings.php 等位于 other/ 子目录;而官方发布包(官网下载)把这些文件放在论坛根目录。为与官方发布包一致(也便于安装向导按根目录找 SQL 脚本),解压后需要把 other/ 中 6 个文件复制到根:
tar xzf SMF_2.1.8.tar.gz
mv SMF-2.1.8 html
cd html
cp other/install.php other/upgrade.php other/Settings.php other/Settings_bak.php \
other/install_2-1_mysql.sql other/install_2-1_postgresql.sql .
# 剔除仅开发用的仓库文件
rm -rf .github .gitattributes .gitignore .editorconfig .scrutinizer.yml
ls *.php *.sql
实测回显:
cron.php index.php install_2-1_postgresql.sql proxy.php Settings_bak.php ssi_examples.php subscriptions.php
install.php install_2-1_mysql.sql Settings.php SSI.php ssi_examples.php upgrade.php
💡 技术拓展:
Settings.php与Settings_bak.php的区别——前者是模板(占位值,安装向导读取它生成真实配置),后者是备份模板(供手工恢复配置时参考)。真实配置由安装向导写入根目录Settings.php,详解见本专栏《SMF 2.1.8 配置参数详解》。
4.3 编写 Dockerfile
/opt/smf/Dockerfile:
FROM php:8.2-apache
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
libpng-dev libjpeg-dev libfreetype6-dev libzip-dev unzip \
&& rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-configure gd --with-jpeg --with-freetype \
&& docker-php-ext-install -j"$(nproc)" mysqli gd zip opcache
RUN { \
echo 'upload_max_filesize = 10M'; \
echo 'post_max_size = 12M'; \
echo 'memory_limit = 256M'; \
echo 'max_execution_time = 120'; \
} > /usr/local/etc/php/conf.d/smf.ini
要点:mysqli 连接 MariaDB、gd 处理头像与附件缩略图、zip 供后台「软件包」解包、opcache 提升 PHP 模板渲染性能;smf.ini 抬高附件上传相关的 PHP 限制(默认 2M 不够用)。
4.4 编写 docker-compose.yml
/opt/smf/docker-compose.yml:
name: smf-2.1.8-stack
services:
db:
image: mariadb:11.4
container_name: smf-2.1.8-db
restart: unless-stopped
environment:
MARIADB_ROOT_PASSWORD: q1w2e3r4
MARIADB_DATABASE: smf
MARIADB_USER: smf
MARIADB_PASSWORD: q1w2e3r4
volumes:
- smf-db-data:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 5s
timeout: 3s
retries: 20
networks:
- smf-net
web:
build:
context: .
dockerfile: Dockerfile
image: smf-web:2.1.8
container_name: smf-2.1.8-web
restart: unless-stopped
ports:
- "8138:80"
volumes:
- ./html:/var/www/html
depends_on:
db:
condition: service_healthy
networks:
- smf-net
networks:
smf-net:
driver: bridge
ipam:
config:
- subnet: 10.89.64.0/24
volumes:
smf-db-data:
要点:
- 数据库口令为演示值
q1w2e3r4;生产环境请改密并同步修改安装向导里填写的口令; healthcheck+depends_on: condition: service_healthy保证 Web 启动时 MariaDB 已可连接(首次初始化数据目录需要数秒);- 论坛全部文件(源码、附件、头像、缓存、Settings.php)都在 bind mount 的
./html中;数据库落在命名卷smf-db-data。
4.5 构建并启动
cd /opt/smf
chown -R 33:33 html # www-data(php:8.2-apache 内 UID 33)需可写论坛目录
docker compose build
docker compose up -d
docker compose ps
构建尾部与启动实测回显(节选):
#10 resolving provenance for metadata file
#10 DONE 0.0s
Image smf-web:2.1.8 Built
Container smf-2.1.8-db Started
Container smf-2.1.8-db Waiting
Container smf-2.1.8-db Healthy
Container smf-2.1.8-web Starting
Container smf-2.1.8-web Started
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
smf-2.1.8-db mariadb:11.4 "docker-entrypoint.s…" db 9 seconds ago Up 8 seconds (healthy) 3306/tcp
smf-2.1.8-web smf-web:2.1.8 "docker-php-entrypoi…" web 9 seconds ago Up 3 seconds 0.0.0.0:8138->80/tcp, [::]:8138->80/tcp
确认 PHP 扩展就位:
docker exec smf-2.1.8-web php -m | grep -iE 'mysqli|gd|zip|opcache|session'
实测回显:
gd
mysqli
session
Zend OPcache
zip
4.6 运行官方安装向导
浏览器访问 http://192.168.1.172:8138/install.php,向导共 5 步(实测按 step=0~step=5 递进,每步一个「Continue」按钮):
| 步骤 | 页面 | 填写项(本文实测值) |
|---|---|---|
| 1 | 欢迎页/语言选择 | 语言 Install.english.php(UTF-8),点 Continue |
| 2 | Database Server Settings | db_type=mysql,db_server=db(compose 服务名),db_port 留默认,db_user=smf,db_passwd=q1w2e3r4,db_name=smf,db_prefix=smf_ |
| 3 | Forum Settings | mbname=My Community,boardurl=http://192.168.1.172:8138,reg_mode(注册模式)按需,勾选 compress(数据库存储帖子压缩)、dbsession(会话存库)、stats(匿名统计) |
| 4 | Populated Database | 自动建表,确认后 Continue |
| 5 | Create your account | username=admin,password1/password2=q1w2e3r4,email=admin@quzuo.net,server_email=admin@quzuo.net |
⚠️ 注意:
boardurl必须填外界可达的完整地址(协议+IP/域名+端口)。它会被写入Settings.php的$boardurl并用于生成全部站内链接;填错会导致样式/链接指向不可达地址,需改Settings.php后刷新。
向导完成页实测标题:
Congratulations, the installation process is complete!
若宿主机不便开浏览器,向导是纯表单交互,也可用 curl 携带 cookie 逐步 POST 完成(字段名与上表一致,每步 contbutt=Continue)。
4.7 安装结果验证
# 1) 配置文件已生成
grep -E '^\$(boardurl|db_server|db_name|db_user|db_prefix|maintenance)' html/Settings.php
# 2) 数据库表已创建
docker exec smf-2.1.8-db mariadb -usmf -pq1w2e3r4 smf -e \
"SELECT COUNT(*) AS tables_cnt FROM information_schema.tables WHERE table_schema='smf';"
# 3) 管理员账号已写入
docker exec smf-2.1.8-db mariadb -usmf -pq1w2e3r4 smf -e \
"SELECT member_name, email_address, id_group FROM smf_members;"
# 4) 首页可访问
curl -s http://192.168.1.172:8138/index.php | grep -oE '<title>[^<]*'
实测回显:
$maintenance = 0;
$boardurl = 'http://127.0.0.1:8138';
$db_server = 'db';
$db_name = 'smf';
$db_user = 'smf';
$db_prefix = 'smf_';
tables_cnt
73
member_name email_address id_group
admin admin@quzuo.net 1
<title>My Community - Index
💡 说明:实测环境
boardurl为http://127.0.0.1:8138(在宿主机本机跑 curl 时按 127.0.0.1 填写);对外部署请按 4.6 的 ⚠️ 填真实地址。id_group=1即「Administrator」组。
登录验证(表单字段 user/passwrd + 页面内动态生成的会话校验域,浏览器直接登录即可;实测登录成功跳转 302,首页出现「Welcome to SMF!」管理条)。进入 index.php?action=admin 时 SMF 会要求再输入一次密码(后台二次确认,防会话劫持),输入 q1w2e3r4 后标题变为:
<title>Administration Center
发一帖验证写入链路(浏览器发帖或按表单 POST action=post2;board=1),数据库侧核对:
docker exec smf-2.1.8-db mariadb -usmf -pq1w2e3r4 smf -e \
"SELECT id_topic, id_msg, subject FROM smf_topics JOIN smf_messages USING(id_topic);"
id_topic id_msg subject
2 2 SMF 2.1.8 部署验证帖
4.8 删除安装脚本(必做)
安装完成后,后台任意页面顶部会出现红色安全告警(实测原文):
MAJOR SECURITY RISK:
You have not removed install.php!
You have not removed upgrade.php!
删除两个脚本后告警消失:
rm /opt/smf/html/install.php /opt/smf/html/upgrade.php
实测删除后再次抓取后台页面,MAJOR SECURITY 关键字出现次数为 0。
⚠️ 注意:
upgrade.php平时也要求删除,需要升级时再放回(升级流程见本专栏《SMF 2.1.8 常用 CLI 命令与工具详解》「升级与维护流程」节)。
五、数据持久化说明
| 路径(容器内) | 宿主机位置 | 内容 | 备份优先级 |
|---|---|---|---|
/var/www/html/Settings.php | /opt/smf/html/Settings.php | 核心配置(DB 口令、URL、cookie 名、$auth_secret 密钥) | ★★★ 丢失即脱管 |
/var/www/html/attachments | /opt/smf/html/attachments | 帖子附件 | ★★★ |
/var/www/html/avatars | /opt/smf/html/avatars | 头像 | ★★ |
/var/www/html/Themes、Sources 等 | /opt/smf/html/ | 程序本体 + 后台「软件包」安装的 MOD | ★★(升级前备份) |
/var/www/html/cache | /opt/smf/html/cache | SQLite 文件缓存(实测 SQLite3Cache.db3) | ☆ 可再生 |
/var/lib/mysql | 命名卷 smf-218-stack_smf-db-data | 论坛全部数据(帖子/用户/设置,实测 73 张 smf_* 表) | ★★★ |
备份 = 打包 /opt/smf/html/(排除 cache/)+ mariadb-dump 导出数据库,完整命令见本专栏《SMF 2.1.8 常用 CLI 命令与工具详解》「数据库 CLI:配置、备份与恢复」节。
六、环境变量表
SMF 程序本身不读取环境变量,全部配置落 Settings.php 与数据库 smf_settings 表;环境变量只来自两个基础镜像:
| 变量 | 所属服务 | 默认值 | 说明 |
|---|---|---|---|
MARIADB_ROOT_PASSWORD | db | (必填) | MariaDB root 口令 |
MARIADB_DATABASE | db | 空 | 初始化建库名(本文 smf) |
MARIADB_USER / MARIADB_PASSWORD | db | 空 | 初始化建普通账号(本文 smf/q1w2e3r4) |
MARIADB_AUTO_UPGRADE | db | 1 | 大版本升级时自动跑升级流程 |
PHP_*(镜像 ENTRYPOINT 支持) | web | — | php:8.2-apache 无应用级环境变量入口 |
修改 MARIADB_* 只在数据卷为空时生效(首次初始化);已有数据卷上改环境变量不会重建账号,需进数据库改。
七、配置参数说明
与部署直接相关的 Settings.php 关键项(安装向导生成,实测值):
$db_type = 'mysql';
$db_server = 'db'; // compose 服务名,容器网络内解析
$db_name = 'smf';
$db_user = 'smf';
$db_passwd = 'q1w2e3r4';
$db_prefix = 'smf_';
$boardurl = 'http://192.168.1.172:8138';
$boarddir = '/var/www/html';
$sourcedir = '/var/www/html/Sources';
$packagesdir = '/var/www/html/Packages';
$cachedir = '/var/www/html/cache';
$maintenance = 0;
$db_server填服务名db而非localhost——两服务在自定义网络smf-net内由内置 DNS 解析;$boarddir等路径是容器内路径(bind mount 后与宿主机/opt/smf/html同一份文件);- 其余参数(cookie、缓存加速器、图片代理、
$auth_secret)逐项详解见本专栏《SMF 2.1.8 配置参数详解》。
八、配置文件挂载
- compose 将宿主机
/opt/smf/html整体挂载为/var/www/html,Settings.php即宿主机/opt/smf/html/Settings.php,宿主机上直接编辑即可,无需进容器; - 属主要求:Apache 进程是 UID 33(www-data),4.5 节的
chown -R 33:33 html必须执行,否则安装向导报目录不可写、后台「软件包」无法解包; - 修改
Settings.php后无需重启:PHP OPcache 对变更文件的重新校验周期约 2 秒(实测维护模式开关切换后首页状态码 503→200 延迟约 2s 生效); - 附件/头像目录同样经该挂载落宿主机,容器可随时销毁重建,数据不丢。
九、等价 docker run
不使用 compose 时,等价的两条原生命令(网络、卷、端口一致):
docker network create --subnet 10.89.64.0/24 smf-net
docker run -d --name smf-2.1.8-db \
--network smf-net \
-e MARIADB_ROOT_PASSWORD=q1w2e3r4 \
-e MARIADB_DATABASE=smf -e MARIADB_USER=smf -e MARIADB_PASSWORD=q1w2e3r4 \
-v smf-db-data:/var/lib/mysql \
--restart unless-stopped \
mariadb:11.4
docker run -d --name smf-2.1.8-web \
--network smf-net \
-p 8138:80 \
-v /opt/smf/html:/var/www/html \
--restart unless-stopped \
smf-web:2.1.8
十、常用运维命令
cd /opt/smf
docker compose ps # 查看两服务状态
docker compose logs -f --tail 50 web # 跟踪 Apache 访问/错误日志
docker compose logs --tail 30 db # 查看 MariaDB 初始化日志
docker compose restart web # 改 php ini/Settings.php 后重启 Web
docker compose down # 停止并移除容器与网络(数据保留)
docker compose down -v # 连命名卷一起删(清空数据库,慎用)
docker compose up -d # 再次启动
docker logs --tail 抓取 Web 访问日志实测节选(Apache combined 格式,10.89.64.1 为网关即宿主机):
10.89.64.1 - - [02/Nov/2026:09:31:38 +0000] "GET /index.php HTTP/1.1" 200 15030 "-" "curl/8.5.0"
10.89.64.1 - - [02/Nov/2026:09:31:38 +0000] "GET /index.php HTTP/1.1" 503 8477 "-" "curl/8.5.0"
10.89.64.1 - - [02/Nov/2026:09:32:51 +0000] "GET /index.php?action=post;board=1 HTTP/1.1" 200 31263 "-" "curl/8.5.0"
10.89.64.1 - - [02/Nov/2026:09:33:13 +0000] "POST /index.php?action=post2;board=1 HTTP/1.1" 302 417 "-" "curl/8.5.0"
升级版本流程(详见 CLI 篇「升级」节):备份 html/ 与数据库 → 下载新 tag 归档 → 覆盖源码(保留 Settings.php、attachments/、avatars/、cache/)→ 放回 upgrade.php 跑升级向导 → 删除脚本。
十一、常见问题
Q1:docker compose down 删不掉、网络名前缀和 compose 文件里写的 name: smf-2.1.8-stack 不一样?
Compose 规范化项目名时会剥掉点号:smf-2.1.8-stack 落地为 smf-218-stack(实测网络名 smf-218-stack_smf-net、卷名 smf-218-stack_smf-db-data)。只要始终在 /opt/smf/ 目录内用同一份 compose 文件操作(up/down 按文件内容定位项目),不受影响;但用 docker network rm 等原生命令清理时要按剥点后的实际名字操作。
Q2:官网 download.simplemachines.org 下载返回 403?
该端点有 Cloudflare 人机校验,非浏览器请求一律 403(实测 curl -I 三种 URL 形态均 403)。改用官方 GitHub 仓库 tag 归档 https://github.com/SimpleMachines/SMF/archive/refs/tags/v2.1.8.tar.gz(同一份代码),并按 4.2 节把 other/ 的安装文件复制到根目录即可。
Q3:GitHub 直连也超时?
本环境实测直连 120s 超时,需走代理(curl -x http://192.168.1.72:7897,见 4.1 ⚠️)。Docker Hub 镜像拉取在守护进程已配代理时无需额外处理。
Q4:安装向导第 2 步报「Unable to connect to the database」?
检查 db_server 是否填了 db(compose 服务名)。填 localhost/127.0.0.1 连的是 Web 服务自身,必然失败;填宿主机 IP 则需确认 MariaDB 监听与防火墙。本文环境填 db 后实测一次通过(建表 73 张)。
Q5:后台顶部一直显示「MAJOR SECURITY RISK」?
install.php/upgrade.php 未删除(4.8 节)。这是 SMF 的强制安全提示,删除两脚本即消失(实测复验)。
Q6:首页返回 503,只有维护模式提示?
Settings.php 中 $maintenance 为 1/2(管理员登录态下仍可浏览)。改回 0 后约 2 秒生效(OPcache 重校验周期),实测 503→200。维护模式详解见《SMF 2.1.8 配置参数详解》。
Q7:改了 Settings.php 里的 $boardurl,页面样式仍然指向旧地址?
清一次缓存:删除 html/cache/ 下的 *.db3 文件(可再生),或后台「维护 → 清除全部缓存」,再强制刷新浏览器。
十二、参考链接
- SMF 官方仓库与发布:https://github.com/SimpleMachines/SMF
- SMF 官网下载页:https://www.simplemachines.org/about/smf/download.php
- 官方安装要求(包内
other/requirements.md):https://github.com/SimpleMachines/SMF/blob/v2.1.8/other/requirements.md - 官方文档站:https://docs.simplemachines.org
- php:8.2-apache 镜像说明:https://hub.docker.com/_/php
- mariadb 镜像说明:https://hub.docker.com/_/mariadb