[3.0][Testing] Add a Docker development environment for MySQL and PostgreSQL - #9317
Open
albertlast wants to merge 4 commits into
Open
[3.0][Testing] Add a Docker development environment for MySQL and PostgreSQL#9317albertlast wants to merge 4 commits into
albertlast wants to merge 4 commits into
Conversation
Provides a reproducible local stack so contributors can work on SMF without installing PHP, Composer or PostgreSQL on the host: - PHP 8.4 on Apache, with every extension other/requirements.md lists as required (mbstring, fileinfo, pgsql, mysqli) or recommended (gd, intl, curl, exif, ftp, xsl, zip). - PostgreSQL 17, with standard_conforming_strings forced on at database level as SMF requires. - Mailpit, so mail() is captured locally and nothing can be sent out. - Adminer, for browsing the database. The entrypoint runs composer install, waits for the database, generates a Settings.php pointed at the db service and drops install.php into place, so a fresh checkout is ready to install on first boot. Everything lives under .docker/ because check-smf-index.php and check-smf-license.php skip dot directories, so the environment cannot break the file integrity checks. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
This was referenced Jul 29, 2026
SMF supports MySQL and PostgreSQL, and until now this environment only offered one of them. Both database services now start, and SMF_DB_TYPE decides which one the generated Settings.php points at. It defaults to mysql, since that is what the great majority of installs run on. The two engines keep separate volumes, so a forum can be installed on each and switched between by deleting Settings.php and restarting. Settings.php wins over SMF_DB_TYPE once it exists, and the entrypoint says so rather than silently ignoring the variable. The postgres service is renamed from `db` to say what it is, and keeps `db` as a network alias so Settings.php files written by the previous version still resolve. Engine settings are pinned the same way the postgres side already pinned standard_conforming_strings: utf8mb4 and InnoDB, matching SMF's own table DDL. The collation is deliberately left at the charset default, because SMF sets CHARSET without COLLATE, and forcing one here would diverge from the tables it creates. Also corrects the everyday-use notes: php.ini, the vhost and the entrypoint are copied into the image, so editing them needs a rebuild rather than a restart. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
PostgreSQL logs every statement that errors together with the SQL that caused it, with no configuration needed, and the log is only on the container stderr. That makes `docker compose logs postgres` the most useful debugging tool in the stack, and nothing said so. MySQL logs server errors only, never the client statement that failed, so the note points out the asymmetry: now that mysql is the default engine, a suspected SQL problem is worth reproducing on postgres. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
This change was produced by an LLM. The code, the commit messages and this
description were all written by Claude (Anthropic), driven by @albertlast. It has
not yet had human code review.
Everything stated below was verified by actually running it — a full install from
an empty database on each engine — rather than only reasoned about. Even so, please
review it as untrusted work: it may be right about what it does while not being
what SMF would prefer stylistically or architecturally.
Description
This one is a proposal rather than a fix — please close it if a bundled dev
environment is not wanted in the repository. It adds tooling only and changes no
forum code. It is the environment the other PRs in this batch were found and verified
in, so it is offered mainly so that work is reproducible.
docker compose up -d --buildgives a working 3.0 checkout with no local PHP,Composer, MySQL or PostgreSQL install:
mail(), nothing can be sentlocalhost:3307localhost:5433Both engines SMF supports are in the stack, and MySQL is the default. Both
services always start, on separate volumes, so a forum can be installed on each and
switched between.
SMF_DB_TYPEdecides which one the generatedSettings.phppointsat:
Once the forum is installed
Settings.phpis what counts, and the variable no longerhas any effect. The entrypoint detects that case and says so in the log rather than
appearing to ignore the setting.
Built to match
other/requirements.md: the required extensions (mbstring,fileinfo, and bothmysqliandpgsql, since SMF checks forpg_connect) and therecommended ones (
gd,intl,curl,exif,ftp,xsl,zip). The enginesettings SMF asks for are pinned at server level rather than left to whatever the
images happen to ship:
standard_conforming_strings = on, asrequirements.mdrequires.utf8mb4and InnoDB, matching SMF's own table DDL. The collation isdeliberately left at the charset default — SMF writes
CHARSET=utf8mb4with noCOLLATE, so its tables come oututf8mb4_0900_ai_cion MySQL 8.4, and forcing adifferent server collation would only apply to objects SMF did not create and make
the two diverge.
The entrypoint runs
composer install, waits for whichever database was selected,generates a
Settings.phppointed at it and putsinstall.phpin place, so a freshcheckout is ready to install on first boot.
The PostgreSQL service is named
postgresrather thandb, and keepsdbas anetwork alias so a
Settings.phpwritten by an earlier revision of this branch stillresolves.
It does not disturb the existing CI checks
Everything lives under
.docker/on purpose.check-smf-index.phprequires anindex.phpin every directory but skips dot directories (that is how.githubpasses today), and
check-smf-license.phponly inspects.phpfiles —.docker/contains none. Re-confirmed after adding the MySQL side: all four integrity scripts
in the
buildjob exit 0 with this branch checked out.The only tracked file outside
.docker/andcompose.yamlis.gitignore, to add/install.php(next to the existing/upgrade.php),/.envand the compose overridefilenames.
Notes for review
smf/smf/smfon both engines and are deliberatelycommitted — this is a throwaway local environment, not something with secrets worth
protecting.
compose.yamlworks with no.envfile;.docker/env.exampleis there foroverriding ports, versions, credentials and the engine.
.docker/README.md: the installer does not take its formdefaults from
Settings.php, it uses the hardcoded ones in the database API class,so the database step still has to be filled in by hand. The README lists the exact
values for both engines.
php.ini, the vhost and the entrypoint are copied into the image rather thanbind-mounted, so editing them needs
docker compose up -d --build web, not arestart. An earlier revision of the README said restart, which was wrong.
UpdateUnicodescheduled taskregenerates
Sources/Unicode/*.phpin place viafile_put_contents(), and itsoutput differs from what is committed by a handful of blank lines, so the working
tree goes dirty on its own. Not caused by this PR, but it will be noticed by anyone
using it.
How this was verified
PostgreSQL side: full teardown and rebuild (
docker compose down -v, deleteSettings.php, up again) followed by a complete install from an empty database,repeated several times while finding the other issues in this batch.
MySQL side: same, driven through every installer step against an empty database.
database population) all return HTTP 200.
utf8mb4.install.phpremoved, andindex.phpthenserves the new forum at HTTP 200.
engines do not interfere.
docker compose configvalidates, and all fourbuildjob integrity scripts pass.One thing found while verifying, which this PR depends on
The installer cannot finish on this branch without #9316. Step 6, the admin
account step, dies with:
which is exactly what #9316 fixes. Merging that branch in locally was what allowed the
MySQL install above to complete, and it was then dropped again so this PR stays
tooling-only. The code involved is in
Sources/Maintenance/Tools/Install.phpand isnot engine-specific, so it should affect a PostgreSQL install equally; it was only
observed here on MySQL.
This branch has also been brought up to date with
release-3.0, which it was tencommits behind.
Issues References (Fixes|Related|Closes)