github EasyEngine/easyengine v4.13.0
EasyEngine v4.13.0

2 hours ago

Highlights

  • HTTP auth and IP whitelists now cover every domain a site serves. Until now, ee auth only protected a site's own domain: the subsites of a WordPress subdomain multisite (*.example.com) and a site's alias domains were served with the global auth or with no auth at all. In v4.13.0, auth and whitelists apply to subdomain multisite subsites, plain alias domains and *.alias wildcard aliases, and stay in sync when aliases are added or removed (auth-command#57, site-command#502).
  • No more auth leaking between sites. The nginx-proxy wildcard lookup no longer guesses from the host name: an unrelated site such as shop.example.com no longer asks for the credentials of the multisite example.com, and subsites of multisites with 4+ labels (*.ms.dev.example.com) are now matched correctly (dockerfiles#354).
  • Existing sites are fixed on upgrade. A migration regenerates every site's auth and whitelist files, so subsites and aliases that were unprotected become protected with the site's existing credentials, without any manual step. The upgrade never applies a site's wildcard auth to another site, not even while the old nginx-proxy is still running (auth-command#58).
  • Safer upgrades. When an upgrade fails before all containers are upgraded (for example because an image can't be pulled), EasyEngine now also undoes the auth file changes made earlier in the same run, so the host is left as it was and the next attempt starts cleanly (easyengine#1936).
  • No slow requests after upgrading. Sites whose containers are recreated during the upgrade no longer serve intermittent ~3 s (sometimes 10 s+) requests until their nginx is reloaded by hand (easyengine#1937).
  • Safer proxy reloads. EasyEngine now only reloads nginx-proxy when the regenerated config passes nginx -t. A broken config is no longer loaded into the running proxy; ee warns with the nginx error instead (site-command#494).
  • Updated images: nginx-proxy 1.11.6, PHP 8.2.34 / 8.3.33 / 8.4.26 / 8.5.11, PHP 8.1.34 with refreshed Debian 13 packages, Redis 8.10.1, postfix on Debian 13.6, and a final rebuild of the PHP 7.4 and 8.0 images with the last Debian 11 security updates.

Upgrade notes

nginx-proxy: wildcard auth files are now looked up only for *.X hosts

dockerfiles#354 changes how the proxy picks the htpasswd and ACL file for a host:

  1. htpasswd/<host> (and vhost.d/<host>_acl) if it exists;
  2. for a host that is literally *.X (a subdomain multisite or a *.X alias): htpasswd/_wildcard.X (and vhost.d/_wildcard.X_acl);
  3. otherwise the global htpasswd/default (and vhost.d/default_acl).

The label-counting fallback added in v4.11.0 (dockerfiles#298), which tried _wildcard.<last 3 labels> and then _wildcard.<last 2 labels> for any host, is removed. The same mapping is now used for the IP whitelist include, including the /ee-admin/ and mailhog locations. Setups managed with ee auth are not affected: before this release, EasyEngine never wrote _wildcard.X files, so only hand-made files relied on the old fallback.

PHP sites get new images

Every site on PHP 8.1, 8.2, 8.3, 8.4 or 8.5 is recreated on its new easyengine/php<version>:v4.13.0 image during the upgrade: PHP 8.2.34, 8.3.33, 8.4.26 and 8.5.11, and PHP 8.1.34 (unchanged) with up-to-date Debian 13 packages. All five images are based on Debian 13.7. PHP 8.1 is end of life upstream and its official base image is no longer rebuilt, so the EasyEngine image now applies the Debian security updates itself at build time; plan to move 8.1 sites to a newer PHP version.

Sites on PHP 7.4 and 8.0 are recreated on the new easyengine/php7.4:v4.13.0 and easyengine/php8.0:v4.13.0 images during the upgrade, like every other WordPress and PHP site. PHP itself doesn't change (7.4.33 and 8.0.30, both end of life upstream); the images are rebuilt on the last Debian 11 security snapshot, which brings up to two years of Debian security updates that the old images (built 2024-09-13 and 2025-02-13) didn't have. Debian 11 is now end of life too, so this is the last build of these two images: future releases keep them at v4.13.0. Move these sites to a supported PHP version with ee site update <site> --php=8.4 (or 8.2, 8.3, 8.5) when you can.

New features

auth-command

  • HTTP auth and IP whitelists now apply to all domains of a site: subdomain multisite subsites, alias domains and *.alias wildcard aliases. Plain aliases get their own files; only subdomain multisites and *.X aliases get _wildcard files (auth-command#57).
  • Auth files follow alias changes: files for a new alias are written before the proxy starts serving it, removed again if the alias update fails, and removed for deleted aliases (auth-command#57).
  • New upgrade migration that regenerates every site's auth and whitelist files (auth-command#57, auth-command#58).

site-command

  • New hooks around alias domain updates (site_alias_domains_before_update, site_alias_domains_updated, site_alias_domains_update_failed) for packages that keep per-domain proxy files (site-command#502).
  • Alias domain names are now validated on ee site update --add-alias-domains and ee site create --type=html --alias-domains: only a hostname or *.hostname is accepted, labels can't start with - or _ or end with -, and the reserved names default / default_admin_tools are refused. Invalid names are listed in the error before anything changes. Existing invalid aliases can still be deleted (site-command#502).

core

  • New hook after_docker_image_migration, fired during an upgrade right after the image migration, once the updated global containers run. Packages can use it for changes that need the new containers (easyengine#1936).

Fixes

core

  • A failed upgrade now also reverts the container migrations that ran earlier in the same run (for example when an image can't be pulled), and removes their records so the next attempt runs them again. Before, they stayed applied on the old containers and were never re-run. Once the image migration has completed, a later failure keeps them (easyengine#1936).
  • After the upgrade recreates a WordPress or PHP site's containers, its nginx is reloaded, so it no longer keeps sending some requests to the removed temporary php container (each took ~3 s, sometimes 10 s+, until ee site reload <site> --nginx). The same reload runs for each site when a failed upgrade rolls the sites back. If a reload fails, ee warns with the site name and the command to run (easyengine#1937).

auth-command

  • Site delete now removes all of the site's auth and whitelist rows and every htpasswd and ACL file it used (the cleanup hook existed but was never loaded, so these were left behind) (auth-command#57).
  • Usernames and passwords are shell-escaped when the htpasswd files are written: passwords with spaces, $ or ; were silently cut or broke the command (auth-command#57).
  • Passwords and usernames are no longer written to ee.log (auth-command#57).
  • htpasswd files are written atomically (temp file and rename), so a failed write keeps the previous file, including the global default file (auth-command#57).
  • Sites without auth or whitelist entries of their own no longer keep stale files, and correctly fall back to the global auth (auth-command#57).
  • The upgrade migration backs up the auth files and restores them exactly if the upgrade fails. It holds the _wildcard.* files back while the old nginx-proxy template runs and puts them in place once the new proxy is up, so sibling sites never pick up another site's wildcard auth during an upgrade, even when the upgrade fails or is interrupted. If a site's auth changed in between (for example after an interrupted upgrade), its files are regenerated from the current settings instead (auth-command#58).

site-command

  • nginx-proxy is only reloaded when nginx -t passes, and the test now checks the regenerated config rather than the previous one. On failure, ee warns with the nginx error and skips the reload (site-command#494).
  • Adding or removing alias domains on a site with custom, self-signed or inherited SSL no longer aborts halfway with "Only Letsencrypt certificate renewal is supported." (which left the containers and the database out of sync). Let's Encrypt sites still get a renewed certificate, custom-cert sites get a warning to supply a certificate covering the new aliases, and self-signed sites keep HTTPS (site-command#488).
  • Blank entries in alias lists (a.com,,b.com,) are dropped instead of ending up in the proxy and nginx config; an update with nothing left to add or delete is refused (site-command#502).

site-type-wp

  • ee site create --type=wp --alias-domains drops blank entries and rejects invalid alias names (such as ../evil, a..b, a.com. or default) before anything is created; --alias-domains without a value no longer creates the alias 1 (site-type-wp#239).
  • --mu=subdom is refused when another site already has the alias *.<site>, which the multisite would also serve (site-type-wp#239).

site-type-php

  • ee site create --type=php --alias-domains drops blank entries and rejects invalid alias names before anything is created; --alias-domains without a value no longer creates the alias 1 (site-type-php#114).

nginx-proxy image

  • Per-site IP whitelists now apply to subdomain multisite subsites and *.X aliases, including the /ee-admin/ and mailhog locations (dockerfiles#354).

PHP 7.4 and 8.0 images

  • The PHP 7.4 and 8.0 images build again: Debian 11's security repository was removed from deb.debian.org after Debian 11 LTS ended, so their builds failed. They now use the final bullseye-security snapshot from snapshot.debian.org (dockerfiles#355).

Improvements and maintenance

  • The PHP 8.1 image now installs Debian security updates at build time, because the official PHP 8.1 base image is no longer rebuilt upstream (dockerfiles#360).
  • The PHP 7.4 and 8.0 images are no longer built: Debian 11, their base, is end of life (dockerfiles#356).
  • composer/composer updated to 2.2.30, which also fixes the core nightly and PR builds that had failed since 2026-07-21 (easyengine#1933).
  • Development: php_codesniffer 3.13.6 (easyengine#1932); core CI moved to Node 24 GitHub Actions (easyengine#1934).

Docker image updates

All new images are tagged v4.13.0 (dockerfiles v4.13.0, matching the core version, as with v4.11.0).

Image 4.12.0 tag 4.13.0 tag Upstream change PR
easyengine/nginx-proxy v4.11.1 v4.13.0 jwilder/nginx-proxy 1.11.2 → 1.11.6, new wildcard auth/ACL lookup in nginx.tmpl #345, #354
easyengine/php8.1 v4.10.2 v4.13.0 PHP unchanged (8.1.34); Debian 13 packages upgraded at build time, now Debian 13.7 #360
easyengine/php8.2 v4.11.0 v4.13.0 PHP 8.2.31 → 8.2.34 #350, #360
easyengine/php8.3 v4.11.0 v4.13.0 PHP 8.3.31 → 8.3.33 #348
easyengine/php8.4 v4.11.0 v4.13.0 PHP 8.4.22 → 8.4.26 #352, #360
easyengine/php8.5 v4.11.1 v4.13.0 PHP 8.5.7 → 8.5.11 #360
easyengine/redis v4.11.0 v4.13.0 Redis 8.8.0 → 8.10.1 #351
easyengine/postfix v4.11.0 v4.13.0 Debian 13.5 → 13.6 (slim) #344
easyengine/php7.4 v4.7.4 v4.13.0 Final rebuild on the last Debian 11 security snapshot; PHP unchanged (7.4.33) #355
easyengine/php8.0 v4.8.1 v4.13.0 Final rebuild on the last Debian 11 security snapshot; PHP unchanged (8.0.30) #355

Unchanged in this release: nginx v4.11.0, cron v4.11.0, mariadb v4.9.1 (still held back; the MariaDB upgrade isn't part of this release), mailhog v4.6.5, php5.6–7.3 v4.7.4, php (stable) v4.6.6, newrelic-daemon v4.11.1. Only the nginx-proxy bump is required for the new auth behaviour.

PHP 7.4 and 8.0 run on Debian 11, which is end of life, so v4.13.0 is their last image; like 5.6–7.3, they stay available but are no longer rebuilt (#356 removes them from the image builds).

Package versions

All tagged. Semver follows the Conventional Commit types of the merged PRs.

Component 4.12.0 4.13.0 Why
easyengine (core) 4.12.0 4.13.0 (tagged) new features in bundled packages and the upgrade fixes (#1936, #1937) (EasyEngine uses minor versions for these)
dockerfiles v4.11.1 v4.13.0 (tagged) fix(nginx-proxy)!, the PHP 7.4/8.0 build fix, base image bumps (PHP 8.1–8.5, nginx-proxy, redis, postfix) and the end of 7.4/8.0 builds
auth-command v1.2.1 v1.3.1 (tagged) feat(auth) (auth-command#57) + fix(migration) (auth-command#58)
site-command v3.7.6 v3.8.0 (tagged) feat(site) (site-command#502) + fixes (site-command#488, site-command#494)
site-type-wp v1.10.1 v1.11.0 (tagged) fix(site) (site-type-wp#239); minor bump because it now requires site-command v3.8.0
site-type-php v1.10.1 v1.11.0 (tagged) fix(site) (site-type-php#114); minor bump because it now requires site-command v3.8.0
admin-tools, config, cron, dash, log, mailhog, service, shell unchanged unchanged no changes since their pinned tags

Contributors

What's Changed

Don't miss a new easyengine release

NewReleases is sending notifications on new releases.