github EasyEngine/easyengine v4.13.1
EasyEngine v4.13.1

3 hours ago

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. redirect stops working right away (site-command#505).

Sites and data safety

  • A failed ee site create removes only the database and user it created itself (site-command#503, site-type-wp#240, site-type-php#115).
  • An interrupted create (for example Ctrl+C) removes the database, user and webroot it had just created, and an early failure keeps a site directory that already existed (site-type-wp#240, site-type-php#115).
  • ee site delete keeps a database or user that another site still uses (site-command#503).
  • A new site's database user is granted only its own database. Existing sites keep their current grants (site-command#503).
  • Database names and passwords with quotes, $ or backticks work (site-command#503).
  • When ee runs on PHP 8.5, a site create that stops with a PHP fatal error is rolled back again; before, it left its containers, database and files behind (site-command#507).

WordPress core download

  • ee site create --type=wp downloads WordPress core without truncated file names and checks it with wp core verify-checksums. A failed download now stops the create and cleans up, instead of carrying on without core (site-type-wp#241).
  • ee site restore restores WordPress core the same way, and keeps the old core if the new one can't be extracted (site-command#504).

Auth whitelist

  • The whole whitelist entry is validated, including its CIDR prefix, and the error names the bad entry. Before, an invalid prefix was written to the whitelist file and stopped every later nginx-proxy reload (auth-command#59).
  • A repeated IP in one --ip list no longer fails with a database error (auth-command#59).

Cron

  • With no cron jobs, the scheduler stays running instead of restarting in a loop, and ee cron delete no longer removes the cron container when the last job is deleted (cron-command#60).
  • Schedules are validated the same way on create and update, and ee cron update rejects unknown ids and checks --site like create (cron-command#60).
  • Host cron jobs no longer get a user, which stopped the scheduler. --user is refused for host jobs, and ee cron list host and ee cron list --all list host jobs without a user instead of failing (cron-command#60).
  • A stored job the scheduler can't read is left out of its config with a warning, instead of stopping every job (cron-command#60).

Core

  • ee no longer hangs when a command it runs writes a lot of output to stderr (easyengine#1939).

Docker image updates

All new images are tagged v4.13.1 (dockerfiles v4.13.1, matching the core version).

Image 4.13.0 tag 4.13.1 tag Upstream change PR
easyengine/php8.3 v4.13.0 v4.13.1 PHP 8.3.33 → 8.3.35 #361
easyengine/redis v4.13.0 v4.13.1 Redis 8.10.1 → 8.10.2 #358
easyengine/postfix v4.13.0 v4.13.1 Debian 13.6 → 13.7 (slim) #357
easyengine/newrelic-daemon v4.11.1 v4.13.1 Alpine 3.24.1 → 3.24.2 #359

Unchanged in this release: nginx-proxy v4.13.0, nginx v4.11.0, cron v4.11.0, mariadb v4.9.1, mailhog v4.6.5, php8.1/8.2/8.4/8.5 v4.13.0, php7.4/8.0 v4.13.0, php5.6–7.3 v4.7.4, php (stable) v4.6.6.

Package versions

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

Component 4.13.0 4.13.1 Why
easyengine (core) 4.13.0 4.13.1 fixes in bundled packages and images, and the process fix (easyengine#1939)
dockerfiles v4.13.0 v4.13.1 (tagged) base image bumps (PHP 8.3, redis, postfix, newrelic-daemon)
site-command v3.8.0 v3.8.1 (tagged) fixes: 14 SSL and Let's Encrypt PRs (site-command#485–#500) and site-command#503–#507
site-type-wp v1.11.0 v1.12.0 (tagged) fix(create) (site-type-wp#240) + fix(core) (site-type-wp#241); minor bump because it now requires site-command v3.8.1
site-type-php v1.11.0 v1.12.0 (tagged) fix(create) (site-type-php#115); minor bump because it now requires site-command v3.8.1
auth-command v1.3.1 v1.3.2 (tagged) fix(auth) (auth-command#59)
cron-command v2.1.0 v2.1.1 (tagged) fix(cron) (cron-command#60)
admin-tools, config, dash, log, mailhog, service, shell unchanged unchanged no changes since their pinned tags

Contributors

What's Changed

easyengine

  • build(composer): ignore the flysystem 1.x path-normalizer advisory #1941 @mrrobot47
  • chore(release): prepare v4.13.1 #1940 @mrrobot47
  • fix(process): read stdout and stderr together so large output can't deadlock #1939 @mrrobot47

site-command

site-type-wp

site-type-php

auth-command

cron-command

dockerfiles

Don't miss a new easyengine release

NewReleases is sending notifications on new releases.