OSSN 10.1 Docker Compose 部署指南

OSSN 10.1 Docker Compose 部署:官方部署仓库改造为 PHP 8.2 + MySQL 8.0 双服务栈,curl 非交互跑通三步安装向导并完成管理员登录验证,沉淀 build.zip 不可达、AllowOverride 缺失、安装器自环检查失败三则排障实录,全部命令与回显实测。

OSSNOSSNDockerPHP自托管社交网络2026/11/02

OSSN 10.1 Docker Compose 部署指南

目标:以官方部署仓库 opensource-socialnetwork/docker 为基线,构建 OSSN 10.1 的 Docker Compose 生产栈(Apache PHP 8.2 应用 + MySQL 8.0 双服务),用 curl 非交互跑通官方三步安装向导(install → account → finish)并完成管理员登录验证;同时完整记录官方镜像路径的三个坑(build.zip 不可达、AllowOverride 缺失、安装器自环检查失败)与本地化改造方案。已在 Ubuntu 24.04.5 LTS + Docker 29.9.2 + Compose v5.6.1 环境全量实测通过,文中所有命令与回显均为实测原文。

一、环境信息

本文所有命令与输出均在以下环境实测采集:

  • 操作系统:Ubuntu 24.04.5 LTS(x86_64,kernel 7.0.0-38-generic)
  • Docker:29.9.2(含 Docker Compose v5.6.1 插件)
  • OSSN:10.1(GitHub tag 10.1;源码包 ossn-10.1.tar.gz,sha256 c4e68e7b44d0e2bfc9a983d4d81f0e39398ffd5da669124f59849ba53f876506)
  • 应用运行时:PHP 8.2.35(php:8.2-apache 基底)+ gd mysqli zip mbstring pdo_mysql opcache exif,Apache 开 mod_rewrite
  • 数据库:MySQL 8.0.46(mysql:8.0)
  • 部署目录:/opt/ossn(本文示例路径;实测宿主目录为 /opt/data/quzuo/tmp/ossn/compose,compose 内挂载全部为 ./ 相对路径,不影响回显内容)
  • 站点地址:http://127.0.0.1:8139/(端口槽位 8128–8152 中已占 8128/8133/8138/8143/8144/8147/8148,本栈取空闲的 8139)
  • 管理员账号:admin / q1w2e3r4(演示口令)
  • 数据库账号:库/用户/口令 ossn / ossn / q1w2e3r4,root 口令 q1w2e3r4;3306 不对外发布,仅自定义网络内访问
  • 自定义网络:ossn-101-stack_ossn-net(子网 10.89.60.0/24,网关 10.89.60.1;静态 IP:db 10.89.60.10、web 10.89.60.11;注意项目名中的点号被 Compose 规范化剔除,见 11.2)
  • 两服务常驻内存实测(安装完成并浏览若干页面后采样,docker stats --no-stream):
服务内存占用说明
ossn-10.1-web49.15MiBApache + PHP 8.2(OSSN 本体)
ossn-10.1-db423.1MiBMySQL 8.0(11 张表)
合计约 472MiB1GB 内存宿主即可运行(MySQL 为主要开销,可继续调低缓冲池)

二、镜像选型说明

OSSN 官方提供部署仓库但不发布预构建镜像——官方仓库 opensource-socialnetwork/docker(main 分支)只有三个文件:Dockerfile、docker-compose.yml、settings.php,官方 compose 的 web 服务写作 build: context: https://github.com/opensource-socialnetwork/docker.git,即每次部署都要从 Git 仓库现场构建,Docker Hub 上没有 opensourcesocialnetwork/* 之类的官方组织镜像(Docker Hub 检索实查,2026-11-02)。

官方 Dockerfile 的逐行逻辑(2026-11-02 实查):

  • 基础 php:8.1-apache,apt 装 libpng-dev libjpeg-dev libfreetype6-dev libzip-dev libonig-dev libxml2-dev 等编译依赖,docker-php-ext-install gd mysqli zip mbstring pdo_mysql opcache exif,a2enmod rewrite;
  • ADD https://www.opensource-socialnetwork.org/download_ossn/latest/build.zip 下载官方发布包解压到 /var/www/html;
  • 用 curl 从 GitHub raw 拉仓库内 settings.php 替换 installation/pages/settings.php:安装页的数据库四字段改为按环境变量 MYSQL_USER/MYSQL_PASSWORD/MYSQL_DATABASE 预填且 readonly,dbhost 固定为 db(compose 服务名),datadir 固定 /var/www/ossn_data/——这是实现"环境变量驱动安装"的关键机制;
  • mkdir /var/www/ossn_data 属 www-data、EXPOSE 80、CMD ["apache2-foreground"];
  • 官方 compose:web(80:80、命名卷 ossn_data:/var/www/ossn_data、env OSSN_DATA/MYSQL_*)+ db(mysql:8.0、命名卷 db_data)。

官方路径在本实测环境存在三个不可用/不完整点,本文 Dockerfile 针对性改造(改动全部标注于 4.1):

#官方做法问题本文改造
1ADD .../build.zip 构建期下载官网官网被 Cloudflare 拦截,容器内直连亦不可达(实测超时)宿主先取 GitHub codeload 包并 sha256 校验,构建时 COPY 本地包
2仅 a2enmod rewriteDebian 默认 AllowOverride None,根 .htaccess 不生效,伪静态与内部路径屏蔽全部失效追加 conf:<Directory /var/www/html> AllowOverride All,并预置 .htaccess
3基础镜像 php:8.1-apachePHP 8.1 已于 2024-12 停止安全维护升级 php:8.2-apache(满足 OSSN ≥8.0 要求)

💡 技术拓展:PHP 社交/社区类软件的容器交付形态主要有三类——

形态代表取舍
官方组织预构建镜像 + 版本 tagMyBB(mybb/mybb)、Grafana拉取即用、升级改 tag
官方部署仓库本地构建OSSN(opensource-socialnetwork/docker)、Misago应用与编排同仓库演进;首次构建耗时、依赖构建期网络
无官方容器化、社区 composephpBB灵活但质量参差,供应链风险自担

OSSN 属第二类:官方给 Dockerfile 但不给镜像,构建期还要从官网拉包——这正是本文把"下载"前置到宿主、把"构建"留在本地的原因。

三、前置条件

3.1 Docker 与 Compose 插件

宿主机需 Docker 24+ 与 docker compose v2+ 插件。验证:

docker --version && docker compose version

实测回显:

Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1

3.2 端口规划

官方 compose 示例发布 80;本实测宿主在 8128–8152 规划段内取 8139。确认空闲:

ss -tlnp | grep ':8139'

实测回显:无输出(= 空闲)。部署完成后监听:

ss -ltn | grep 8139

实测回显:

LISTEN 0      4096         0.0.0.0:8139       0.0.0.0:*          
LISTEN 0      4096            [::]:8139          [::]:*          

MySQL 3306 留在自定义网络内,不发布宿主端口。

3.3 网段规划

多栈共存建议显式声明子网。检查空闲:

ip route | grep '10.89.60'

实测回显:无输出(= 10.89.60.0/24 空闲,本栈独占)。

3.4 源码包准备

官方 build.zip 不可达(见第二章),改从 GitHub codeload 取 tag 10.1 源码包并校验:

curl -sL -o ossn-10.1.tar.gz https://codeload.github.com/opensource-socialnetwork/opensource-socialnetwork/tar.gz/refs/tags/10.1
sha256sum ossn-10.1.tar.gz

实测回显:

c4e68e7b44d0e2bfc9a983d4d81f0e39398ffd5da669124f59849ba53f876506  /opt/data/quzuo/tmp/ossn/compose/ossn-10.1.tar.gz

⚠️ 注意 GitHub 源码包与官网 build.zip 的一个实际差异:仓库 .gitignore 排除了根目录 .htaccess,源码包内没有该文件(官方 build.zip 有)。OSSN 安装器会在安装页首次加载时从 installation/configs/htaccess.dist 自动生成它,本文 Dockerfile additionally 预置一份(见 4.1),保证容器重建后伪静态不丢。

3.5 目录结构

mkdir -p /opt/ossn/data/{db,ossn}
  • data/db/:MySQL 数据目录(bind mount);
  • data/ossn/:OSSN 用户数据目录(bind mount,对应容器内 /var/www/ossn_data);
  • configurations/:OSSN 配置目录(bind mount,必须预先播种,见 3.6);
  • Dockerfile、docker-compose.yml、settings.php、ossn-10.1.tar.gz:编排四件套。

3.6 configurations 目录播种(关键前置)

OSSN 安装器生成配置的方式是读取 configurations/ossn.config.db.example.php 与 ossn.config.site.example.php 模板做占位符替换(OssnInstall.php 的 configurations_db()/configurations_site())。本文把 configurations/ 做成 bind mount 以持久化配置(见第八章),因此宿主机目录必须先从源码包复制初始内容,否则安装器读不到模板直接报 "all:files:required":

tar -xzf ossn-10.1.tar.gz
cp -a opensource-socialnetwork-10.1/configurations /opt/ossn/configurations
chown -R 33:33 /opt/ossn/configurations /opt/ossn/data/ossn

chown 33:33 即容器内 www-data 的 uid/gid——bind mount 保留宿主属主,Apache 子进程以 www-data 运行,安装器要往这个目录写两个配置文件。

四、部署步骤

4.1 应用镜像 Dockerfile

/opt/ossn/Dockerfile(基于官方 Dockerfile 改造,逐行注释标出改动):

# OSSN 10.1 应用镜像(基于官方 opensource-socialnetwork/docker 仓库 Dockerfile 改造)
# 改造点:php:8.1-apache -> php:8.2-apache;build.zip -> 本地源码包 COPY;
#         settings.php 本地化 COPY;新增 AllowOverride All 与预置 .htaccess
FROM php:8.2-apache

# 系统依赖与 PHP 扩展(与官方一致)
RUN apt-get update && apt-get install -y \
        unzip zip \
        libpng-dev libjpeg-dev libfreetype6-dev libzip-dev libonig-dev libxml2-dev \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install gd mysqli zip mbstring pdo_mysql opcache exif \
    && a2enmod rewrite \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# 允许 .htaccess 生效(OSSN 伪静态依赖根目录 .htaccess)
RUN printf '<Directory /var/www/html>\n    AllowOverride All\n    Require all granted\n</Directory>\n' \
        > /etc/apache2/conf-available/ossn.conf \
    && a2enconf ossn

# 源码包本地构建(官方路径为下载 build.zip,其官网被 CDN 拦截时不可用)
COPY ossn-10.1.tar.gz /tmp/ossn.tar.gz
RUN mkdir -p /tmp/ossnsrc \
    && tar -xzf /tmp/ossn.tar.gz -C /tmp/ossnsrc \
    && cp -a /tmp/ossnsrc/opensource-socialnetwork-10.1/. /var/www/html/ \
    && rm -rf /tmp/ossnsrc /tmp/ossn.tar.gz

# 预置根 .htaccess(安装器本应在安装页首次加载时生成,预置后容器重建不丢伪静态)
RUN cp /var/www/html/installation/configs/htaccess.dist /var/www/html/.htaccess

# 用官方 docker 仓库 settings.php 替换安装页(DB 字段按环境变量预填、dbhost=db)
COPY settings.php /var/www/html/installation/pages/settings.php

# 数据目录(必须位于安装目录之外)
RUN mkdir -p /var/www/ossn_data \
    && chgrp www-data /var/www/ossn_data && chmod g+w /var/www/ossn_data \
    && chown -R www-data:www-data /var/www/html /var/www/ossn_data \
    && chmod -R 755 /var/www/html

EXPOSE 80
CMD ["apache2-foreground"]

其中 settings.php 直接取官方仓库同名文件(安装页替换件,见第二章),保存为 /opt/ossn/settings.php:

curl -sL -o settings.php https://raw.githubusercontent.com/opensource-socialnetwork/docker/main/settings.php

4.2 编排文件 docker-compose.yml

name: ossn-10.1-stack

networks:
  ossn-net:
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.60.0/24
          gateway: 10.89.60.1

services:
  db:
    image: mysql:8.0
    container_name: ossn-10.1-db
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: q1w2e3r4
      MYSQL_DATABASE: ossn
      MYSQL_USER: ossn
      MYSQL_PASSWORD: q1w2e3r4
    volumes:
      - ./data/db:/var/lib/mysql
    networks:
      ossn-net:
        ipv4_address: 10.89.60.10
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-uroot", "-pq1w2e3r4"]
      interval: 10s
      timeout: 5s
      retries: 12

  web:
    build: .
    container_name: ossn-10.1-web
    restart: unless-stopped
    ports:
      - "8139:80"
    environment:
      MYSQL_DATABASE: ossn
      MYSQL_USER: ossn
      MYSQL_PASSWORD: q1w2e3r4
      OSSN_DATA: /var/www/ossn_data
    volumes:
      - ./data/ossn:/var/www/ossn_data
      - ./configurations:/var/www/html/configurations
    networks:
      ossn-net:
        ipv4_address: 10.89.60.11
    depends_on:
      db:
        condition: service_healthy

关键项逐项说明:

  • name: ossn-10.1-stack:显式项目名,防止与其他组件的 compose 目录互相 down 误删;
  • db:MYSQL_DATABASE/USER/PASSWORD 首次初始化时预建库与业务账号,安装向导直接连用;healthcheck 用 mysqladmin ping 把关,web 以 condition: service_healthy 依赖,避免 Apache 起来时数据库未就绪;
  • web:build: . 本地构建(对应官方 build: context: https://github.com/... 的现场构建形态);MYSQL_* 三个变量不是给 OSSN 运行时读的——OSSN 核心不读任何环境变量,它们只被安装页 settings.php 的 getenv() 预填进表单(见 4.6 与第六章);OSSN_DATA 同理仅为标注,真实数据目录由安装表单的 datadir 字段决定;
  • 两个 bind mount:./data/ossn 持久化用户数据(图片/附件),./configurations 持久化安装生成的配置文件(播种要求见 3.6,机制见第八章);
  • 静态 IP 便于巡检对照(4.4 验证),非必需项。

语法校验:

cd /opt/ossn && docker compose config --quiet && echo "config OK"

实测回显:

config OK

4.3 构建应用镜像

cd /opt/ossn && docker compose build

实测回显(输出节选,构建尾部):

#10 [5/8] RUN mkdir -p /tmp/ossnsrc     && tar -xzf /tmp/ossn.tar.gz -C /tmp/ossnsrc     && cp -a /tmp/ossnsrc/opensource-socialnetwork-10.1/. /var/www/html/     && rm -rf /tmp/ossnsrc /tmp/ossn.tar.gz
#10 DONE 0.4s

#11 [6/8] RUN cp /var/www/html/installation/configs/htaccess.dist /var/www/html/.htaccess
#11 DONE 0.3s

#12 [7/8] COPY settings.php /var/www/html/installation/pages/settings.php
#12 DONE 0.1s

#13 [8/8] RUN mkdir -p /var/www/ossn_data     && chgrp www-data /var/www/ossn_data && chmod g+w /var/www/ossn_data     && chown -R www-data:www-data /var/www/html /var/www/ossn_data     && chmod -R 755 /var/www/html
#13 DONE 1.1s

#14 exporting to image
#14 naming to docker.io/library/ossn-101-stack-web:latest done
#14 DONE 1.2s

#15 resolving provenance for metadata file
#15 DONE 0.0s
 Image ossn-101-stack-web Built 

镜像名由 Compose 按"项目名-服务名"自动生成(ossn-10.1-stack 中的点被剔除,故为 ossn-101-stack-web)。体积实测:

docker images ossn-101-stack-web --format '{{.Repository}}:{{.Tag}} {{.Size}}'
ossn-101-stack-web:latest 782MB

4.4 启动与网络验证

docker compose up -d

实测回显:

 Container ossn-10.1-db Creating 
 Container ossn-10.1-db Created 
 Container ossn-10.1-web Creating 
 Container ossn-10.1-web Created 
 Container ossn-10.1-db Starting 
 Container ossn-10.1-db Started 
 Container ossn-10.1-db Waiting 
 Container ossn-10.1-db Healthy 
 Container ossn-10.1-web Starting 
 Container ossn-10.1-web Started 
docker compose ps

实测回显:

NAME            IMAGE                COMMAND                  SERVICE   CREATED          STATUS                    PORTS
ossn-10.1-db    mysql:8.0            "docker-entrypoint.s…"   db        20 seconds ago   Up 18 seconds (healthy)   3306/tcp, 33060/tcp
ossn-10.1-web   ossn-101-stack-web   "docker-php-entrypoi…"   web       19 seconds ago   Up 8 seconds              0.0.0.0:8139->80/tcp, [::]:8139->80/tcp

网络与 IP 验证:

docker network ls | grep ossn
docker inspect ossn-10.1-web --format '{{range $k,$v := .NetworkSettings.Networks}}{{$k}} => {{$v.IPAddress}}{{end}}'

实测回显:

ef09c60ec787   ossn-101-stack_ossn-net    bridge    local
ossn-101-stack_ossn-net => 10.89.60.11

4.5 安装器前置检查页

OSSN 安装向导是 Web 表单(installation/),官方文档没有 CLI 安装器;但三步提交的全部字段都在表单里,用 curl 即可非交互等价执行。先看 Prerequisites 检查页:

curl -s http://127.0.0.1:8139/installation/ | grep -oE 'ossn-installation-(success|fail)">[^<]*'

实测回显:

ossn-installation-success">PHP 8.2.35 
ossn-installation-success">PHP allow_url_fopen ENABLED
ossn-installation-success">PHP ZipArchive ENABLED
ossn-installation-success">PHP CURL
ossn-installation-success">PHP GD LIBRARY
ossn-installation-success">PHP openssl
ossn-installation-success">PHP SimpleXML
ossn-installation-success">PHP json
ossn-installation-success">PHP fileinfo
ossn-installation-success">PHP mbstring
ossn-installation-success">PHP exif
ossn-installation-success">MYSQLI ENABLED
ossn-installation-success">APACHE ENABLED
ossn-installation-fail">Failed to connect to 127.0.0.1 port 8139 after 0 ms: Could not connect to server
ossn-installation-success">CONFIGURATION DIRECTORY WRITEABLE

倒数第二行的 fail 是 mod_rewrite 自检项——安装器在容器内用 curl 回访站点 URL http://127.0.0.1:8139/rewrite.php,而 8139 只在宿主发布、容器内 Apache 监听 80,所以自环连接失败。这是端口映射部署的固有现象,不影响安装(检查项为提示性),排障与消除方法见 11.1。

4.6 第一步:写配置 + 导入 SQL(action=install)

先建会话并取安装表单(settings.php 替换件把 DB 字段按环境变量预填为 readonly):

curl -s -c cj.txt 'http://127.0.0.1:8139/installation/' -o /dev/null
curl -s -b cj.txt 'http://127.0.0.1:8139/installation/?page=settings' | grep -E 'form action|input type|name=|value='

实测回显:

                <div><div class="layout-installation"><h2>Site Settings</h2><form action="http://127.0.0.1:8139/installation/?action=install" method="post">
        <input type="text" name="dbuser" placeholder="Database User" value="ossn" readonly="readonly"/>
        <input type="password" name="dbpwd" placeholder="Database Password" value="q1w2e3r4" readonly="readonly"/>
        <input type="text" name="dbname" placeholder="Database Name" value="ossn" readonly="readonly"/>
        <input type="text" name="dbhost" placeholder="Database Host" value="db" readonly="readonly" />
        <input type="text" name="sitename" placeholder="Website name"/>
        <input type="text" name="owner_email" placeholder="Site Owner Email"/>
                <input type="text" name="notification_email" placeholder="Notification Email" value=""/>                
  	<input type="hidden" name="url" value="http://127.0.0.1:8139/"/>
        <input type="text" name="datadir" value="/var/www/ossn_data/" readonly="readonly" />
	    <input type="submit" value="Install" class="button-blue primary">

提交安装(字段与浏览器表单完全一致):

curl -s -b cj.txt -c cj.txt -X POST 'http://127.0.0.1:8139/installation/?action=install' \
  -d 'dbuser=ossn' -d 'dbpwd=q1w2e3r4' -d 'dbhost=db' -d 'dbname=ossn' \
  -d 'url=http://127.0.0.1:8139/' -d 'datadir=/var/www/ossn_data/' \
  -d 'owner_email=admin@quzuo.net' -d 'notification_email=noreply@quzuo.net' \
  -d 'sitename=OSSN Demo' -L | grep -oE '<title>[^<]*</title>|Admin Account|name="[a-z_]+"' | sort -u

实测回显(返回 Account 步骤页即安装成功):

Admin Account
name="birthday"
name="birthm"
name="birthy"
name="email"
name="email_re"
name="firstname"
name="lastname"
name="password"
name="username"
<title>Account settings</title>
Username

此步做了三件事:连接 db 服务导入 installation/sql/opensource-socialnetwork.sql(替换 <<owner_email>> <<notification_email>> <<sitename>> <<secret>> 占位符,建 11 张表)、把两个 .example.php 模板渲染成 configurations/ossn.config.db.php 与 ossn.config.site.php(见第八章回显)、执行 post_install/ 钩子。

4.7 第二步:创建管理员(action=account)

curl -s -b cj.txt -c cj.txt -X POST 'http://127.0.0.1:8139/installation/?action=account' \
  -d 'username=admin' -d 'firstname=Admin' -d 'lastname=User' \
  -d 'email=admin@quzuo.net' -d 'email_re=admin@quzuo.net' -d 'password=q1w2e3r4' \
  -d 'gender=male' -d 'birthday=2' -d 'birthm=11' -d 'birthy=1990' -L | grep -oE '<title>[^<]*</title>|Finish'

实测回显:

<title>Installed</title>
Finish
finish
Finish

十个字段全部必填。提交后直接渲染 Installed 完成页(会话此时已以 admin 身份登录)。

4.8 第三步:锁定安装器(action=finish)

curl -s -b cj.txt -c cj.txt -L 'http://127.0.0.1:8139/installation?action=finish' -o /dev/null -w 'finish -L => %{http_code} %{url_effective}\n'

实测回显:

finish -L => 200 http://127.0.0.1:8139/administrator

finish 写入 installation/INSTALLED 文件后 301 跳 /administrator;安装器被永久锁定:

curl -s http://127.0.0.1:8139/installation/

实测回显:

It seems the Open Source Social Network is already installed

4.9 管理员登录验证(干净会话)

curl -s -c lj.txt 'http://127.0.0.1:8139/login' -o login.html
grep -oE 'name="ossn_token" value="[^"]*"' login.html

登录表单带 CSRF 令牌(ossn_token + ossn_ts),POST 到伪静态端点 /action/user/login:

TOKEN=$(grep -oE 'name="ossn_token" value="[^"]*"' login.html | sed 's/.*value="//;s/"//')
TS=$(grep -oE 'name="ossn_ts" value="[^"]*"' login.html | sed 's/.*value="//;s/"//')
curl -s -b lj.txt -c lj.txt -X POST 'http://127.0.0.1:8139/action/user/login' \
  -d "username=admin" -d "password=q1w2e3r4" -d "ossn_token=$TOKEN" -d "ossn_ts=$TS"

实测回显(JSON):

{"redirect":"http:\/\/127.0.0.1:8139\/home"}
curl -s -b lj.txt -o /dev/null -w 'administrator => %{http_code}\n' 'http://127.0.0.1:8139/administrator'
curl -s -b lj.txt 'http://127.0.0.1:8139/administrator' | grep -oE '<title>[^<]*</title>'

实测回显:

administrator => 200
<title>Dashboard : OSSN Demo</title>

后台仪表盘 200,登录验证通过。伪静态与匿名行为一并确认:

curl -s -o /dev/null -w '/home(匿名) => %{http_code} -> %{redirect_url}\n' http://127.0.0.1:8139/home
curl -s http://127.0.0.1:8139/rewrite.php

实测回显:

/home(匿名) => 302 -> http://127.0.0.1:8139/login
1

/home 未登录 302 到 /login(路由重写生效);rewrite.php 输出 1(.htaccess → installation/tests/apache_rewrite.php 重写链路正常)。

五、数据持久化说明

本栈三个 bind mount 的分工与内容:

宿主路径容器路径内容实测体积(安装后)
./data/db/var/lib/mysqlMySQL 全部数据(11 张表)常规 ibdata/binlog
./data/ossn/var/www/ossn_dataOSSN 用户数据(图片、附件、组件缓存)du -sh 实测 1.1M
./configurations/var/www/html/configurations安装生成的两个配置文件 + 装配清单 + dcache6 个文件

数据目录结构(安装后 find 实测):

/var/www/ossn_data
/var/www/ossn_data/system
/var/www/ossn_data/system/plugins_paths
/var/www/ossn_data/system/locales

不在持久化范围内的:/var/www/html 应用代码本体(烧在镜像里,升级镜像即换代码)、cache/(css/js 压缩缓存,可再生)、installation/INSTALLED 锁定文件(镜像层,容器重建后消失——但站点以 configurations/ 两文件存在与否判断是否已安装,不受影响;重装风险见 11.4)。

备份口径:停栈后打包 data/db + data/ossn + configurations 三目录即可完整恢复;configurations 里含数据库明文口令,注意权限。

六、环境变量表

先说透一个容易误解的点:OSSN 应用本体不读取任何环境变量(核心配置全部来自 configurations/*.php 与数据库 ossn_site_settings 表)。本编排里的 env 分两类:

db 服务(mysql:8.0 镜像标准初始化变量,真实生效):

变量实测值作用
MYSQL_ROOT_PASSWORDq1w2e3r4root 口令,初始化必需
MYSQL_DATABASEossn首次启动预建库
MYSQL_USERossn预建业务账号
MYSQL_PASSWORDq1w2e3r4业务账号口令

web 服务(仅供安装页 settings.php 预填与标注,非运行时配置):

变量实测值消费方
MYSQL_DATABASE / MYSQL_USER / MYSQL_PASSWORD同 db 侧getenv() 渲染进安装表单 readonly 字段(4.6 回显可见)
OSSN_DATA/var/www/ossn_data官方 compose 遗留标注;真实 datadir 由表单 datadir 字段决定(settings.php 中 readonly,值来自 OssnInstallation::DefaultDataDir() 计算)

安装完成后,这些变量对站点行为不再有任何影响;改站点 URL、数据目录要动配置文件(见 7.2 与 11.5)。

七、配置参数说明

安装生成的两份配置全文(容器内 cat 实测回显):

docker exec ossn-10.1-web cat /var/www/html/configurations/ossn.config.db.php /var/www/html/configurations/ossn.config.site.php
$Ossn->host = 'db';
$Ossn->port = '3306';
$Ossn->user = 'ossn';
$Ossn->password = 'q1w2e3r4';
$Ossn->database = 'ossn';

$Ossn->url = 'http://127.0.0.1:8139/';
$Ossn->userdata = '/var/www/ossn_data/';

文件层配置就这七个参数(另有 ossn.config.dcache.php 动态缓存默认 disabled),其余站点参数全部在数据库 ossn_site_settings 表(实测安装后 14 行:theme=goblue、site_name、language=en、cache=1、owner_email、notification_email、upgrades(38 个升级脚本记账)、display_errors、site_key、site_version=10.1 等)。逐项详解、修改方式与生产模板见《OSSN 10.1 配置参数详解》。

八、配置文件挂载

为什么把 configurations/ 做成 bind mount:官方形态下它随代码烧进镜像,容器重建(升级镜像、down && up)后安装器生成的两个配置文件丢失,站点回到"未安装"状态,必须重跑安装向导。bind mount + 播种(3.6)后:

  • 安装器写入的 ossn.config.db.php/ossn.config.site.php 落在宿主,重建容器零影响;
  • ACP"动态缓存"页保存设置时回写的 ossn.config.dcache.php(actions/administrator/cache/dynamic.php 用 file_put_contents 写该文件)同样持久化;
  • 代价:挂载遮蔽镜像内同名目录,镜像升级时该目录的新模板文件不会自动同步,大版本升级需人工比对 configurations/ 内容(新增 .php 清单文件要手动合并)。

权限要点:宿主目录属主必须 chown -R 33:33(容器内 www-data),否则安装器写配置报 "CONFIGURATION DIRECTORY WRITEABLE" 检查失败(该项在 4.5 回显中为 success 即权限正确)。

九、等价 docker run

compose 的 web 服务可翻译为一条 docker run(复用同一网络与挂载)。实测:先 docker compose stop web,再:

docker run -d --name ossn-10.1-web-run \
  --network ossn-101-stack_ossn-net -p 8139:80 \
  -e MYSQL_DATABASE=ossn -e MYSQL_USER=ossn -e MYSQL_PASSWORD=q1w2e3r4 \
  -e OSSN_DATA=/var/www/ossn_data \
  -v $(pwd)/data/ossn:/var/www/ossn_data \
  -v $(pwd)/configurations:/var/www/html/configurations \
  ossn-101-stack-web:latest

实测回显:

7268015b4af8c9745ffa974c3ec6e78552e8396b78fcad7beeb31d733e684dee
等价形态首页 => 200
<title>Welcome : OSSN Demo</title>

站点在裸 run 形态下完整可用(复用 bind mount 的配置与数据)。验证后清理并复原 compose 托管:

docker rm -f ossn-10.1-web-run
docker compose up -d web

实测回显:

ossn-10.1-web-run
 Container ossn-10.1-db Running 
 Container ossn-10.1-db Waiting 
 Container ossn-10.1-db Healthy 
 Container ossn-10.1-web Starting 
 Container ossn-10.1-web Started 
compose 复原 => 200

十、常用运维命令

# 状态与端口
docker compose ps
# 应用日志(Apache access/error)
docker compose logs --tail=50 web
# 滚动重启应用(配置改动后)
docker compose restart web
# 进入 PHP 运行时执行 CLI 入口(见[《OSSN 10.1 常用 CLI 命令与工具详解》](https://www.quzuo.net/document/t6y1VFz3w78H))
docker compose exec web php /var/www/html/system/handlers/cli --handler=EnableCache
# 查库
docker compose exec db mysql -uossn -pq1w2e3r4 ossn -e "SHOW TABLES;"
# 资源占用
docker stats --no-stream ossn-10.1-web ossn-10.1-db
# 完整下线(数据在 bind mount 中保留)
docker compose down

docker compose restart web 实测回显:

 Container ossn-10.1-web Restarting 
 Container ossn-10.1-web Started 

restart 后站点即恢复(GET / 200)。MySQL 11 张表实测:

docker compose exec db mysql -uossn -pq1w2e3r4 ossn -N -e "SHOW TABLES;"
ossn_annotations ossn_components ossn_entities ossn_entities_metadata ossn_likes ossn_messages ossn_notifications ossn_object ossn_relationships ossn_site_settings ossn_users

十一、常见问题

11.1 Prerequisites 页 mod_rewrite 自检失败

现象:4.5 回显中 ossn-installation-fail">Failed to connect to 127.0.0.1 port 8139 after 0 ms: Could not connect to server。原因:安装器在容器内 curl 站点 URL 的 rewrite.php 做端到端验证,而站点 URL 是宿主映射地址(url 表单字段),容器内没有 8139 监听。影响:仅提示性检查,实测安装与伪静态均正常(4.9 的 /home 302 与 rewrite.php 输出 1 证明重写已生效)。消除方法:安装提交前在 web 服务加 extra_hosts 不可行(127.0.0.1 是容器自身回环);实用做法是安装期间临时把站点 URL 表单值提交为 http://localhost/(容器内 80),装完再改 ossn.config.site.php 的 $Ossn->url 回宿主地址——或者接受这一行 fail,不影响任何功能。

11.2 项目名中的点号被剔除

name: ossn-10.1-stack 声明后,实际网络/镜像名是 ossn-101-stack_ossn-net、ossn-101-stack-web——Compose 将项目名规范化为 [a-z0-9] 字符集(点号被删除)。按官方 compose 的 docker compose down 无感知,但手工 docker network rm/docker rmi 时要用规范化后的名字(4.4 回显为准),别拿声明名去猜。

11.3 configurations bind mount 未播种导致安装失败

空目录直接挂载会遮蔽镜像内的 .example.php 模板,action=install 抛 "all:files:required" 类错误。必须按 3.6 先 cp -a 播种再挂载。若坚持用官方"配置烧镜像"形态,删掉该 volume 行即可,代价见第八章。

11.4 容器重建后能否重装

docker compose down && up 后 installation/INSTALLED(镜像层)消失,/installation/ 重新可达 Prerequisites 页;但只要 configurations/ 两个配置文件还在(bind mount),站点本体照常运行,切勿误点重装——重装会重跑 SQL 导入(表已存在多数语句报错被安装器吞掉)并覆盖配置。若需彻底重装,先清 data/db 与 configurations/ossn.config.*.php。

11.5 官网 build.zip 不可达

官方 Dockerfile 的 ADD https://www.opensource-socialnetwork.org/download_ossn/latest/build.zip 在本实测环境(容器内直连与宿主直连均)超时——官网全站 Cloudflare 强校验。替代源即 3.4 的 GitHub codeload tag 包(注意 3.4 的 .htaccess 差异说明)。若你的服务器可直连官网,官方 Dockerfile 原样可用。

十二、参考链接

OSSN 10.1 Docker Compose 部署指南 - Quzuo