Elgg 7.1.2 Docker Compose 部署指南

无官方镜像的 Elgg 7.1.2 用 php:8.3-apache+mariadb:11 自建 Compose 栈部署:扩展编译、CLI 安装向导 13 问逐字实测、登录与上传下载验证、数据持久化与等价 docker run,含 pdo_mysql/intl/权限/密码策略/上传 404 等七条实测排障实录。

ElggElggDockerDocker ComposeMariaDBPHP 应用2026/11/02

Elgg 7.1.2 Docker Compose 部署指南

目标:在一台 Ubuntu 24.04 服务器上,用 Docker Compose 从零部署一套可登录、可上传、可下载的 Elgg 7.1.2 社交站点——因 Elgg 无官方 Docker 镜像,采用 php:8.3-apache + mariadb:11 自建镜像组合,加载官方 starter-project 发行包后经 CLI 安装向导完成初始化。全部命令与回显均在 Ubuntu 24.04.5 LTS(x86_64)+ Docker Engine 29.9.2 + Compose v5.6.1 环境实测通过,含六条首次部署排障实录。

一、环境信息

  • 操作系统:Ubuntu 24.04.5 LTS(x86_64)
  • Docker Engine:29.9.2(docker --version 实测)
  • Docker Compose:v5.6.1(插件形态,docker compose version 实测)
  • Elgg:7.1.2(GitHub Releases 实查最新稳定版,2026-10-21 发布)
  • 镜像组合:php:8.3-apache(自建扩展层)+ mariadb:11(实测运行 11.8.9-MariaDB)
  • Web 端口:8148(宿主映射 app 的 80 端口,ss -ltn 实测空闲)
  • 部署目录:/opt/data/quzuo/tmp/elgg/stack(compose 工作目录,数据均 bind mount 于其下)
  • compose 项目名:elgg-7.1.2-stack;专用网络子网 10.89.72.0/24
  • 演示账号:admin / q1w2e3r4q1w2e3r4(Elgg 7 默认密码策略要求至少 16 字符,见十一、常见问题)

二、镜像选型说明

Elgg 官方不提供 Docker 镜像(官网与文档站均无官方镜像发布渠道,GitHub 无 Elgg org 下的镜像仓库),因此本方案为自建镜像组合,如实记录:

  • 应用层:官方 php:8.3-apache 镜像(满足 Elgg 7 的 PHP 8.3+ 与 Apache 重写需求),在其上编译 Elgg 必需的三个 PHP 扩展:gd、intl、pdo_mysql(基础镜像默认只有 minimal 扩展集,intl/gd/pdo_mysql 全部缺失,见排障实录)
  • 数据层:官方 mariadb:11 镜像(Elgg 官方要求 MariaDB 10.6+/MySQL 8.4+)
  • 应用代码:Elgg 官方 starter-project 发行包 zip(vendor 依赖完整内置,解压即用,无需在容器内跑 composer install)

发行包获取与完整性校验(实测):

# 官方 Releases 的 starter-project 发行包
sha256sum elgg-7.1.2.zip
# 2544600e7abdcafb311bcb085a98d023ec93fd9c8ff5298ed6fe970ca59f4746  elgg-7.1.2.zip
ls -l elgg-7.1.2.zip
# -rw-r--r-- 1 root root 96625150 ... elgg-7.1.2.zip
unzip -q elgg-7.1.2.zip -d stack/elgg   # 解压后共 56,891 个文件,站点根即该目录

三、前置条件

  1. 端口空闲实测(选 8148):
ss -ltn | grep -E ':81(4[89]|5[0-2])\b' || echo "8148-8152 空闲"
# 8148-8152 空闲
  1. 网络子网槽位查重后使用 10.89.72.0/24:
docker network ls -q | xargs -r docker network inspect \
  --format '{{range .IPAM.Config}}{{.Subnet}} {{end}}' | tr ' ' '\n' | grep '^10.89.7'
# 无输出即 72 槽空闲
  1. 目录规划(bind mount,全部落在 compose 工作目录内):
mkdir -p stack/app stack/elgg stack/data stack/db

四、部署步骤

4.1 编写 docker-compose.yml

name: elgg-7.1.2-stack

services:
  elgg-db:
    image: mariadb:11
    container_name: elgg-7.1.2-mariadb
    restart: unless-stopped
    environment:
      MARIADB_ROOT_PASSWORD: q1w2e3r4
      MARIADB_DATABASE: elgg
      MARIADB_USER: elgg
      MARIADB_PASSWORD: q1w2e3r4
    volumes:
      - ./db:/var/lib/mysql
    networks:
      elgg-net:
        ipv4_address: 10.89.72.20
    healthcheck:
      test: ["CMD", "mariadb-admin", "ping", "-h", "127.0.0.1", "-u", "root", "-pq1w2e3r4"]
      interval: 5s
      timeout: 5s
      retries: 12

  elgg-app:
    build: ./app
    container_name: elgg-7.1.2-apache
    restart: unless-stopped
    depends_on:
      elgg-db:
        condition: service_healthy
    ports:
      - "8148:80"
    volumes:
      - ./elgg:/var/www/html
      - ./data:/var/www/elgg-data
    networks:
      elgg-net:
        ipv4_address: 10.89.72.21

networks:
  elgg-net:
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.72.0/24
          gateway: 10.89.72.1

要点:显式 name 固定项目名;数据库用健康检查门控应用启动;应用代码与数据目录均为 bind mount,升级/重建镜像不丢数据。

4.2 编写应用镜像 Dockerfile(stack/app/Dockerfile)

FROM php:8.3-apache

RUN apt-get update \
    && apt-get install -y --no-install-recommends libpng-dev libjpeg62-turbo-dev libfreetype6-dev libicu-dev \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j"$(nproc)" gd intl pdo_mysql \
    && rm -rf /var/lib/apt/lists/*

RUN a2enmod rewrite

COPY elgg.ini /usr/local/etc/php/conf.d/zz-elgg.ini
COPY elgg-apache.conf /etc/apache2/conf-enabled/elgg.conf

三个易错点(均为实测踩坑,详见十一、常见问题):intl 需要 libicu-dev 头文件;gd 需要 libpng/libjpeg/libfreetype 开发包并显式 --configure;Elgg 依赖 .htaccess 重写规则,必须 a2enmod rewrite 且站点目录允许 AllowOverride All。

4.3 PHP 与 Apache 配置文件挂载

stack/app/elgg.ini:

memory_limit = 512M
upload_max_filesize = 20M
post_max_size = 25M
max_execution_time = 120
date.timezone = UTC

stack/app/elgg-apache.conf:

<Directory /var/www/html>
    AllowOverride All
    Require all granted
</Directory>

4.4 构建并启动

cd stack
docker compose up -d --build
docker compose ps

实测回显:

NAME                 IMAGE                     COMMAND                  SERVICE    CREATED          STATUS                    PORTS
elgg-7.1.2-apache    elgg-712-stack-elgg-app   "docker-php-entrypoi…"   elgg-app   37 minutes ago   Up 37 minutes             0.0.0.0:8148->80/tcp, [:::8148->80/tcp]
elgg-7.1.2-mariadb   mariadb:11                "docker-entrypoint.s…"   elgg-db    43 minutes ago   Up 43 minutes (healthy)   3306/tcp

(自建镜像名随项目名生成,elgg-7.1.2-stack 中的点被镜像命名规则剔除,显示为 elgg-712-stack-elgg-app。)

4.5 数据目录授权(必做)

Elgg 运行用户为容器内 www-data,bind mount 的数据目录与配置目录必须可写,否则安装后首屏即崩(实录见常见问题):

docker compose exec elgg-app chown -R www-data:www-data /var/www/elgg-data /var/www/html/elgg-config

4.6 CLI 安装向导

docker compose exec -u www-data elgg-app php vendor/bin/elgg-cli install

向导共 13 个问题,逐字回显(方括号为默认值):

Enter admin username [admin]: Enter admin password: 
Enter admin email: Enter database host [localhost]: Enter database port [3306]: Enter database username: Enter database password: 
Enter database name: Enter database prefix (for example: elgg_) []: Enter site name: Enter site email [admin@example.com]: Enter site URL (including protocol http|https and a trailing /): Enter data directory path:

本次实测应答:admin / q1w2e3r4q1w2e3r4 / 管理员邮箱 / elgg-db 主机名 3306 / elgg / q1w2e3r4 / elgg / 空前缀 / Elgg Community / 站点 URL http://192.168.1.172:8148/ / 数据目录 /var/www/elgg-data/。

数据库连接成功后进入 Phinx 迁移,尾部回显(实测节选,共 50+ 条迁移):

All Done. Took 0.2362s
 Elgg 7.1.2 install successful 
 wwwroot: http://192.168.1.172:8148/ 
 dataroot: /var/www/elgg-data/ 
 cacheroot: /var/www/elgg-data/caches/ 
 assetroot: /var/www/elgg-data/caches/views_simplecache/

4.7 登录验证

curl -s http://192.168.1.172:8148/login   # 取 __elgg_ts/__elgg_token
curl -s -b cookies.txt -c cookies.txt \
  --data-urlencode "username=admin" --data-urlencode "password=q1w2e3r4q1w2e3r4" \
  --data-urlencode "__elgg_ts=$TS" --data-urlencode "__elgg_token=$TK" \
  http://192.168.1.172:8148/action/login
# login POST http=302 redirect=http://192.168.1.172:8148/
curl -s -b cookies.txt http://192.168.1.172:8148/activity | grep -oE '<title>[^<]+</title>|Log out'
# <title>All Site Activity : Elgg Community</title>
# Log out

4.8 上传/下载功能验证

以文件插件实测(表单字段 title/upload,action 为 /action/file/edit,需带 Referer 头,见常见问题):

curl -s -b cookies.txt -c cookies.txt -H "Referer: http://192.168.1.172:8148/file/add" \
  -F "title=test-upload" -F "upload=@testfile.txt" -F "__elgg_ts=$TS" -F "__elgg_token=$TK" \
  http://192.168.1.172:8148/action/file/edit
# 成功生成 GUID 51;文件落盘:
ls stack/data/1/51/
# file
curl -s -b cookies.txt -o /dev/null -w '%{http_code}\n' http://192.168.1.172:8148/file/download/51
# 200

五、数据持久化说明

宿主路径容器路径内容
stack/db//var/lib/mysqlMariaDB 数据目录(17 张 elgg 表)
stack/elgg//var/www/htmlElgg 代码 + mod/ 插件 + elgg-config/settings.php(安装向导生成)
stack/data//var/www/elgg-data上传文件(<owner_guid>/<guid>/file)、caches 缓存、cron 状态(1/1/cron/*.complete)

三者都是 bind mount,docker compose down 后数据全部保留;down -v 对本方案无额外影响(未用命名卷),删除目录即彻底清场。

六、环境变量表

本方案中 Elgg 应用不读环境变量(配置全部在 settings.php),环境变量仅数据库容器使用:

变量容器值(实测)说明
MARIADB_ROOT_PASSWORDelgg-dbq1w2e3r4root 口令,健康检查同用
MARIADB_DATABASEelgg-dbelgg预建库名
MARIADB_USERelgg-dbelgg应用账号
MARIADB_PASSWORDelgg-dbq1w2e3r4应用口令

七、配置参数说明

安装向导生成的 elgg-config/settings.php 关键项(实测站点):

  • $CONFIG->dbuser/dbname/dbpass/dbhost/dbport:数据库连接,dbhost 填 compose 服务名 elgg-db
  • $CONFIG->wwwroot:http://192.168.1.172:8148/,必须与访问地址一致(含末尾斜杠),否则表单 token 校验异常
  • $CONFIG->dataroot:/var/www/elgg-data/
  • $CONFIG->cacheroot:默认 dataroot/caches/
  • 邮件 SMTP 亦在此文件配置($CONFIG->mail_* 键族),未配置时站内信仅入队不外发

PHP 层参数见 elgg.ini(八、配置文件挂载):memory_limit=512M 为 Elgg 官方建议量级,upload_max_filesize 决定站内文件上限。

八、配置文件挂载

文件挂载点作用
app/elgg.ini/usr/local/etc/php/conf.d/zz-elgg.iniPHP 运行时参数
app/elgg-apache.conf/etc/apache2/conf-enabled/elgg.conf放开 AllowOverride All 使 Elgg .htaccess 重写生效
elgg-config/settings.php随代码目录 bind mount站点核心配置(安装生成,可手工编辑)

九、等价 docker run

docker run -d --name elgg-7.1.2-mariadb --network elgg-net \
  -e MARIADB_ROOT_PASSWORD=q1w2e3r4 -e MARIADB_DATABASE=elgg \
  -e MARIADB_USER=elgg -e MARIADB_PASSWORD=q1w2e3r4 \
  -v $PWD/db:/var/lib/mysql mariadb:11

docker run -d --name elgg-7.1.2-apache --network elgg-net \
  -p 8148:80 -v $PWD/elgg:/var/www/html -v $PWD/data:/var/www/elgg-data \
  elgg-712-stack-elgg-app

十、常用运维命令

docker compose ps                          # 状态与健康
docker compose logs --tail 30 elgg-app     # 应用日志(Apache 日志走 stdout/stderr,勿在容器内 tail error.log)
docker compose exec -T -u www-data elgg-app php vendor/bin/elgg-cli cache:clear
docker compose exec -T -u www-data elgg-app php vendor/bin/elgg-cli cron
docker compose exec -T elgg-db mariadb -u elgg -pq1w2e3r4 elgg -e 'SELECT COUNT(*) FROM elgg_entities;'

十一、常见问题

以下六条全部为本次部署实测踩坑与修复实录。

Q1: 安装向导输入完 13 个问题后报 An exception occurred in the driver: could not find driver,异常栈指向 vendor/doctrine/dbal/src/Driver/PDO/PDOConnect.php:25,最终提示 Elgg couldn't connect to the database using the given credentials。

A: php 基础镜像未编译 pdo_mysql 扩展。Dockerfile 中 docker-php-ext-install 必须包含 pdo_mysql。验证:php -m | grep pdo_mysql。

Q2: 第一次安装失败后修复扩展重装,报 Table 'elgg.elgg_config' doesn't exist。

A: 失败的安装已写出 elgg-config/settings.php 残留配置,重装时向导跳过建库直连旧配置。删除 elgg-config/settings.php 并清空数据库后重新 elgg-cli install。

Q3: 向导最后一步报 The provided password doesn't meet the minimal length requirement of 16 characters。

A: Elgg 7 默认密码策略最少 16 字符。示例口令 q1w2e3r4(8 位)被拒,本文改用 q1w2e3r4q1w2e3r4(16 位)。注意此错发生在迁移执行后,需 DROP DATABASE elgg 重建再装。

Q4: 构建镜像时 docker-php-ext-install intl 报 Package requirements (icu-uc >= 50.1 icu-io icu-i18n) were not met。

A: 缺 libicu-dev 开发头文件。apt 列表中补装 libicu-dev 后重建通过。intl 是 Elgg 硬需求扩展,不能省。

Q5: 安装成功但打开站点 500,日志报 PhpfastcacheIOException: The directory /var/www/elgg-data/caches/fastcache/boot_cache/Files could not be created。

A: bind mount 的数据目录属主是宿主 root,容器内 www-data 无写权限。执行 4.5 的 chown -R www-data:www-data /var/www/elgg-data /var/www/html/elgg-config 后恢复。

Q6: 上传文件 POST /action/file/add 返回 404。

A: 三重原因:① 该表单实际提交目标是 /action/file/edit(从 file_add.html 表单 action 属性实查);② 字段名是 title 与 upload,不是 name/file;③ Elgg 动作要求同源 Referer 头。三处修正后上传成功(GUID 51,data/1/51/file 落盘,/file/download/51 返回 200)。

Q7: 容器内 tail -f /var/log/apache2/error.log 卡住无输出。

A: 官方 php:apache 镜像把 error.log 软链到 /dev/stderr,容器内 tail 会阻塞。用 docker compose logs/docker logs 取日志。

十二、参考链接

Elgg 7.1.2 Docker Compose 部署指南 - Quzuo