SMF 2.1.8 Docker Compose 部署指南

用 Docker Compose(php-apache + MariaDB)部署 SMF 2.1.8 全程实测:下载与包布局修正、安装向导五步、登录发帖验证、安全收尾与维护模式,含 FAQ。

SMFSMF论坛PHPMySQLDocker自托管2026/11/02

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.4SMF 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)。

三、前置条件

  1. 服务器已安装 Docker 与 Compose 插件:
docker --version
docker compose version

实测回显:

Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1
  1. 宿主机 8138 端口未被占用(ss -ltn | grep 8138 无输出);
  2. 服务器可拉取 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
2Database Server Settingsdb_type=mysql,db_server=db(compose 服务名),db_port 留默认,db_user=smf,db_passwd=q1w2e3r4,db_name=smf,db_prefix=smf_
3Forum Settingsmbname=My Community,boardurl=http://192.168.1.172:8138,reg_mode(注册模式)按需,勾选 compress(数据库存储帖子压缩)、dbsession(会话存库)、stats(匿名统计)
4Populated Database自动建表,确认后 Continue
5Create your accountusername=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/cacheSQLite 文件缓存(实测 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_PASSWORDdb(必填)MariaDB root 口令
MARIADB_DATABASEdb空初始化建库名(本文 smf)
MARIADB_USER / MARIADB_PASSWORDdb空初始化建普通账号(本文 smf/q1w2e3r4)
MARIADB_AUTO_UPGRADEdb1大版本升级时自动跑升级流程
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 配置参数详解》。

八、配置文件挂载

  1. compose 将宿主机 /opt/smf/html 整体挂载为 /var/www/html,Settings.php 即宿主机 /opt/smf/html/Settings.php,宿主机上直接编辑即可,无需进容器;
  2. 属主要求:Apache 进程是 UID 33(www-data),4.5 节的 chown -R 33:33 html 必须执行,否则安装向导报目录不可写、后台「软件包」无法解包;
  3. 修改 Settings.php 后无需重启:PHP OPcache 对变更文件的重新校验周期约 2 秒(实测维护模式开关切换后首页状态码 503→200 延迟约 2s 生效);
  4. 附件/头像目录同样经该挂载落宿主机,容器可随时销毁重建,数据不丢。

九、等价 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 2.1.8 Docker Compose 部署指南 - Quzuo