Skip to content

Releases: EasyEngine/easyengine

EasyEngine v4.13.1

Choose a tag to compare

@github-actions github-actions released this 30 Sep 07:26
v4.13.1
d510297

Highlights

  • Complete WordPress 7.x core. New and restored WordPress sites get a complete core, checked with wp core verify-checksums, and existing WordPress 7.x sites with truncated core files are repaired on upgrade (site-type-wp#241, site-command#504).
  • Failed Let's Encrypt alias changes roll back. When a certificate can't be issued for new alias domains, the aliases, certificate and redirect files stay as they were and the command exits with an error, instead of reporting success and revoking the certificate still in use (site-command#505).
  • ee site ssl-verify no longer breaks the proxy. A request on an already-finalized order could deploy a certificate next to a new key that didn't match it, which stopped nginx-proxy reloads for all sites. The previous key is now kept when a request fails, and a certificate that doesn't match its key is never deployed (site-command#506).
  • More reliable SSL handling. Custom certificates are validated and installed on ee site update --ssl=custom, stale ACME orders are rebuilt on retry, concurrent SSL commands no longer race, and warnings now show the actual Let's Encrypt error (site-command#489, site-command#492, site-command#493, site-command#498, site-command#486).
  • Safer site creation. In the rare case where two site names map to the same database name or volume prefix, a failed create no longer removes the other site's database, user or volumes (site-command#503, site-type-wp#240, site-type-php#115).
  • IP whitelist and cron fixes. An invalid CIDR prefix in ee auth --ip is rejected instead of stopping proxy reloads (auth-command#59), and the cron scheduler no longer restarts in a loop when there are no cron jobs (cron-command#60).
  • Updated images: PHP 8.3.35, Redis 8.10.2, postfix on Debian 13.7 and newrelic-daemon on Alpine 3.24.2.

Upgrade notes

Cron jobs saved with ee cron update run on their intended schedule

ee cron update stored a five-field schedule without the seconds field, so it was read as a six-field one: * * * * * ran every second instead of once a minute. The scheduler config is regenerated on upgrade, so these jobs now fire on their intended schedule (cron-command#60).

IP whitelist entries are checked and cleaned up

ee auth create --ip lists are now split on any whitespace or comma, and a repeated IP is stored once. Entries with an invalid CIDR prefix (such as 192.0.2.1/abc, /99 or an IPv6 prefix over 128) are refused. On upgrade, a migration removes invalid entries from existing whitelist files and normalizes the ones nginx accepts (such as 10.0.0.0/08). The database rows are kept; an invalid one is skipped with a warning that names the command to remove it (auth-command#59).

WordPress 7.x sites with truncated core files are repaired

On upgrade, a migration runs wp core verify-checksums on each WordPress site that has wp-includes/php-ai-client/, and repairs the truncated core files in place. Content and database are not touched. Disabled or stopped sites, and sites that can't be checked, get a warning with the command to check them later (site-type-wp#241).

Colliding site names

Existing sites, including pairs that already share a database name or volume prefix, are left as they are. New creates that would collide are refused: a site whose volume prefix or compose project another site uses, or a --dbname/--dbuser that is already taken. A default database name that is already taken gets a _2 (then _3, …) suffix (site-command#503).

Let's Encrypt needs a valid le-mail

Issuing or renewing a Let's Encrypt certificate now stops with a clear error when le-mail is empty or not a valid address, including the nightly ssl-renew --all. Check it with ee config get le-mail and set it with ee config set le-mail <email> if needed (site-command#496).

WordPress and PHP sites get new images

Every WordPress and PHP site is recreated on the new postfix image during the upgrade, and sites on PHP 8.3 also move to PHP 8.3.35. Expect a short interruption per site.

Fixes

SSL and Let's Encrypt

  • A failed Let's Encrypt alias change restores the certificate, ACME and redirect files, keeps the aliases unchanged and exits non-zero. Only certificates that an alias change actually replaced are revoked (site-command#505).
  • ee site update --ssl=le fails when no certificate was issued, and ee site ssl-renew <site> exits non-zero when the renewal fails. A failure in ee site update --ssl=… puts the site back to HTTP-only before anything is saved (site-command#505).
  • A site's certificate and ACME files, including those of its aliases, are removed on ee site delete and --ssl=off, also for wildcard sites. --ssl=off is refused while other sites inherit the certificate, works on sites stored as wildcard, and a self-signed site can turn SSL back on afterwards (site-command#505).
  • Certificates without a subject CN are parsed, and ACME challenge types EasyEngine can't solve no longer break certificate orders (site-command#505).
  • When a first certificate request fails, the previous key is restored, and a 403 from Let's Encrypt gives a warning with its reason instead of a PHP fatal error. Certificate keys are no longer written to ee.log when a request fails (site-command#506).
  • ee site update --ssl=custom now copies the certificate and key; before, it turned on HTTPS without them (site-command#489).
  • Custom certificates are checked before install: an invalid PEM file, a broken chain or a key that doesn't match the certificate is refused, and an expired certificate or one expiring within 30 days gives a warning (site-command#492).
  • ee site ssl-verify is refused on sites without Let's Encrypt SSL, so it can no longer replace a custom certificate. On a site without SSL it points to ee site update <site> --ssl=le (site-command#487).
  • ee site ssl-verify rebuilds a stored ACME order that has expired or failed, instead of failing on every retry (site-command#493).
  • Certificates are copied to nginx-proxy through temporary files, so a failed copy no longer leaves a mismatched key and certificate. The file permissions are kept on renewal (site-command#491).
  • SSL commands wait for each other: a second one waits up to 120 seconds (600 for ssl-renew) and then stops with a clear message (site-command#498).
  • le-mail is validated before registering with Let's Encrypt, and renewals use the current le-mail (site-command#496, site-command#497).
  • SSL warnings include the Let's Encrypt error, and the misleading "Challenge Authorization failed" line is gone from renewal failures (site-command#486). The renewal message now says "less than 35 days", matching the actual threshold (site-command#485).
  • ssl-renew --all pauses 1–5 seconds between due renewals, reports Let's Encrypt rate limits as such, and carries on with the next site when one is rate-limited (site-command#499).
  • A warning is shown when the Let's Encrypt account key is missing while certificates issued under it still exist, instead of silently creating a new account (site-command#500).
  • Self-signed certificate generation quotes the site name and file paths it passes to openssl (site-command#495).
  • The SSL flag migration no longer marks sites with custom, self-signed or inherited SSL as Let's Encrypt, on installs that still have to run it (site-command#490).

Proxy

  • A proxy cache update that fails keeps a valid nginx-proxy config: the files it wrote are restored, and the config test is retried once (site-command#505).
  • Alias changes reload nginx-proxy instead of restarting it, and sites without SSL stay HTTP-only when their aliases change (site-command#505).
  • After a site is deleted, nginx-proxy is reloaded, so its www. redire...
Read more

EasyEngine v4.13.0

Choose a tag to compare

@github-actions github-actions released this 28 Sep 08:13
v4.13.0
705cbfc

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...
Read more

EasyEngine v4.12.0

Choose a tag to compare

@github-actions github-actions released this 08 Jul 10:06
v4.12.0
927e779

What's Changed

EasyEngine v4.11.0

Choose a tag to compare

@github-actions github-actions released this 12 Jun 13:05
v4.11.0
9f1af48

What's Changed

EasyEngine v4.10.2

Choose a tag to compare

@github-actions github-actions released this 07 Jan 12:39
v4.10.2

What's Changed

EasyEngine v4.10.1

Choose a tag to compare

@github-actions github-actions released this 26 Dec 10:29
v4.10.1

What's Changed

EasyEngine v4.10.0

Choose a tag to compare

@github-actions github-actions released this 22 Dec 07:01
v4.10.0

What's Changed

EasyEngine v4.9.3

Choose a tag to compare

@github-actions github-actions released this 27 Sep 08:34
v4.9.3

What's Changed

EasyEngine v4.9.2

Choose a tag to compare

@github-actions github-actions released this 05 Sep 08:11
v4.9.2

What's Changed

EasyEngine v4.9.1

Choose a tag to compare

@github-actions github-actions released this 04 Sep 09:57
v4.9.1

What's Changed