From c68d723b29f14cd8c397c29755011c56da6584d7 Mon Sep 17 00:00:00 2001 From: Aaron Feledy Date: Thu, 19 Feb 2026 16:16:22 -0600 Subject: [PATCH 1/8] test: add MySQL 5.7 SSL connectivity test Reproduces #167 - MySQL 8.0 client connecting to MySQL 5.7 server fails with TLS/SSL self-signed certificate error because the MySQL client install script does not configure ssl-mode. --- examples/db-client-mysql57/.lando.yml | 17 +++++++++++ examples/db-client-mysql57/README.md | 44 +++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 examples/db-client-mysql57/.lando.yml create mode 100644 examples/db-client-mysql57/README.md diff --git a/examples/db-client-mysql57/.lando.yml b/examples/db-client-mysql57/.lando.yml new file mode 100644 index 00000000..758f2ac3 --- /dev/null +++ b/examples/db-client-mysql57/.lando.yml @@ -0,0 +1,17 @@ +name: lando-php-db-client-mysql57 + +services: + # Test MySQL 5.7 auto-detection and connectivity + php: + type: php:8.4 + via: cli + + database: + type: mysql:5.7 + creds: + user: testuser + password: testpass + database: testdb + +plugins: + "@lando/php": ../.. diff --git a/examples/db-client-mysql57/README.md b/examples/db-client-mysql57/README.md new file mode 100644 index 00000000..a42972fe --- /dev/null +++ b/examples/db-client-mysql57/README.md @@ -0,0 +1,44 @@ +# Database Client MySQL 5.7 SSL Test + +This example tests that `db_client: auto` correctly handles MySQL 5.7, which uses self-signed certificates that cause TLS/SSL errors with the MySQL 8.0 client. + +## Start up tests + +Run the following commands to get up and running with this example. + +```bash +# Should start up successfully +lando poweroff +lando start +``` + +## Verification commands + +Run the following commands to validate things are rolling as they should. + +```bash +# Auto-detection installs MySQL client (not MariaDB) +lando exec php -- mysql --version | grep -q "mysql" +lando exec php -- mysql --version | grep -qi "Ver 8.0" +lando exec php -- mysql --version | grep -qiv "MariaDB" +``` + +```bash +# MySQL client can connect to MySQL 5.7 database without SSL errors +lando exec php -- mysql -h database -u testuser -ptestpass testdb -e "SELECT 1" +``` + +```bash +# mysqldump works against MySQL 5.7 without SSL errors +lando exec php -- mysqldump -h database -u testuser -ptestpass testdb --no-data > /dev/null +``` + +## Destroy tests + +Run the following commands to trash this app like nothing ever happened. + +```bash +# Should be destroyed with success +lando destroy -y +lando poweroff +``` From 63ac18699a22d25104aaad7db94e59983f8c8644 Mon Sep 17 00:00:00 2001 From: Aaron Feledy Date: Thu, 19 Feb 2026 16:16:40 -0600 Subject: [PATCH 2/8] ci: add db-client-mysql57 to test matrix --- .github/workflows/pr-php-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr-php-tests.yml b/.github/workflows/pr-php-tests.yml index 3129d845..2c177a46 100644 --- a/.github/workflows/pr-php-tests.yml +++ b/.github/workflows/pr-php-tests.yml @@ -36,6 +36,7 @@ jobs: - examples/composer - examples/db-client - examples/db-client-mysql + - examples/db-client-mysql57 - examples/php-extensions - examples/xdebug lando-version: From 09f1d149cddff284002d8c8773dc0787c77b6b9e Mon Sep 17 00:00:00 2001 From: Aaron Feledy Date: Thu, 19 Feb 2026 16:19:13 -0600 Subject: [PATCH 3/8] chore: add syncthing to gitignore --- .gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitignore b/.gitignore index 8b56b4be..ff687046 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,11 @@ config.*.timestamp-*-*.* # YARN yarn.lock + + +# Syncthing +.stfolder/ +.stversions/ +.stignore +*.sync-conflict-* + From 6c2d991b4e0702a91ef2d60d5bfe3d77866deef4 Mon Sep 17 00:00:00 2001 From: Aaron Feledy Date: Thu, 19 Feb 2026 16:26:39 -0600 Subject: [PATCH 4/8] chore: remove accidental syncthing gitignore entries --- .gitignore | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.gitignore b/.gitignore index ff687046..8b56b4be 100644 --- a/.gitignore +++ b/.gitignore @@ -44,11 +44,3 @@ config.*.timestamp-*-*.* # YARN yarn.lock - - -# Syncthing -.stfolder/ -.stversions/ -.stignore -*.sync-conflict-* - From 9f63de96529daac67024a24db08bad8a1eb73ed5 Mon Sep 17 00:00:00 2001 From: Aaron Feledy Date: Thu, 19 Feb 2026 17:07:49 -0600 Subject: [PATCH 5/8] test: use apache appserver with run commands to reproduce MySQL 5.7 SSL error The original cli-based test passed because the SSL issue manifests specifically when mysql commands run via services.run or events on an appserver (apache/nginx), matching the real-world Backdrop recipe scenario reported by the user. --- examples/db-client-mysql57/.lando.yml | 11 ++++++++--- examples/db-client-mysql57/README.md | 16 +++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/examples/db-client-mysql57/.lando.yml b/examples/db-client-mysql57/.lando.yml index 758f2ac3..799fd868 100644 --- a/examples/db-client-mysql57/.lando.yml +++ b/examples/db-client-mysql57/.lando.yml @@ -1,10 +1,15 @@ name: lando-php-db-client-mysql57 services: - # Test MySQL 5.7 auto-detection and connectivity - php: + # Test MySQL 5.7 auto-detection with an appserver (not cli) + # Reproduces SSL errors when mysql commands run via services.run or events + appserver: type: php:8.4 - via: cli + via: apache + run: + - mysql -h database -u testuser -ptestpass testdb -e "SELECT 1 AS connection_test" + run_as_root: + - mysql -h database -u root testdb -e "SELECT 1 AS root_connection_test" database: type: mysql:5.7 diff --git a/examples/db-client-mysql57/README.md b/examples/db-client-mysql57/README.md index a42972fe..5ed8d1af 100644 --- a/examples/db-client-mysql57/README.md +++ b/examples/db-client-mysql57/README.md @@ -1,13 +1,15 @@ # Database Client MySQL 5.7 SSL Test -This example tests that `db_client: auto` correctly handles MySQL 5.7, which uses self-signed certificates that cause TLS/SSL errors with the MySQL 8.0 client. +This example tests that `db_client: auto` correctly handles MySQL 5.7 when using +an Apache appserver with mysql commands in `services.run` (matching a real-world +recipe scenario where SSL errors occur). ## Start up tests Run the following commands to get up and running with this example. ```bash -# Should start up successfully +# Should start up successfully with mysql run commands completing without SSL errors lando poweroff lando start ``` @@ -18,19 +20,19 @@ Run the following commands to validate things are rolling as they should. ```bash # Auto-detection installs MySQL client (not MariaDB) -lando exec php -- mysql --version | grep -q "mysql" -lando exec php -- mysql --version | grep -qi "Ver 8.0" -lando exec php -- mysql --version | grep -qiv "MariaDB" +lando exec appserver -- mysql --version | grep -q "mysql" +lando exec appserver -- mysql --version | grep -qi "Ver 8.0" +lando exec appserver -- mysql --version | grep -qiv "MariaDB" ``` ```bash # MySQL client can connect to MySQL 5.7 database without SSL errors -lando exec php -- mysql -h database -u testuser -ptestpass testdb -e "SELECT 1" +lando exec appserver -- mysql -h database -u testuser -ptestpass testdb -e "SELECT 1" ``` ```bash # mysqldump works against MySQL 5.7 without SSL errors -lando exec php -- mysqldump -h database -u testuser -ptestpass testdb --no-data > /dev/null +lando exec appserver -- mysqldump -h database -u testuser -ptestpass testdb --no-data > /dev/null ``` ## Destroy tests From 72b99159270d7df9cdb1d542a49c13bb7756c310 Mon Sep 17 00:00:00 2001 From: Aaron Feledy Date: Thu, 19 Feb 2026 17:15:41 -0600 Subject: [PATCH 6/8] fix: add ssl-mode=DISABLED to MySQL client config for local dev Prevents TLS/SSL errors when MySQL 8.0 client connects to older MySQL servers (e.g. 5.7) with self-signed certificates. Containers on the same Docker network don't need encrypted connections. Fixes lando/lando#3833 --- scripts/mysql-client-install.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/mysql-client-install.sh b/scripts/mysql-client-install.sh index 4d63e45d..3358ca99 100755 --- a/scripts/mysql-client-install.sh +++ b/scripts/mysql-client-install.sh @@ -50,10 +50,15 @@ mkdir -p /etc/mysql/conf.d cat > /etc/mysql/conf.d/lando.cnf << 'MYCNF' [client] default-character-set=utf8mb4 +# Disable SSL verification for local dev — containers on the same Docker +# network don't need encrypted connections, and older MySQL versions +# (e.g. 5.7) use self-signed certs that cause verification failures +ssl-mode=DISABLED [mysqldump] # Prevent column-statistics errors with newer mysqldump skip-column-statistics +ssl-mode=DISABLED MYCNF if ! mysql --version 2>/dev/null; then From a833e954de7960acc79e5f39c34f07e00845a3e6 Mon Sep 17 00:00:00 2001 From: Aaron Feledy Date: Thu, 19 Feb 2026 18:56:51 -0600 Subject: [PATCH 7/8] fix: detect database type even when no version is specified MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When users set 'database: mysql' without a version (e.g. in Backdrop recipe config), the service type is 'backdrop-mysql' with no colon or version number. The detection regex required a version, so it returned null and no MySQL client was installed — falling back to the default MariaDB client which fails with TLS/SSL errors on MySQL servers. Now matches versionless types and defaults to mysql:8.0 / mariadb:11.4. Fixes lando/lando#3833 --- builders/php.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/builders/php.js b/builders/php.js index 5ac1ced2..8a63dfce 100644 --- a/builders/php.js +++ b/builders/php.js @@ -68,12 +68,12 @@ const detectDatabaseClient = (options, debug = () => {}) => { for (const service of Object.values(services)) { const type = service?.type || ''; - // Match mysql:X or recipe-mysql:X (e.g., backdrop-mysql:8.0, drupal-mysql:8.4) - const mysqlMatch = type.match(/(?:^|-)mysql:(\d+(?:\.\d+)?)/); - if (mysqlMatch && !mysqlVersion) mysqlVersion = mysqlMatch[1]; - // Match mariadb:X or recipe-mariadb:X (e.g., backdrop-mariadb:10.6, drupal-mariadb:11.4) - const mariaMatch = type.match(/(?:^|-)mariadb:(\d+(?:\.\d+)?)/); - if (mariaMatch && !mariaVersion) mariaVersion = mariaMatch[1]; + // Match mysql or mysql:X, including recipe prefixes (e.g., backdrop-mysql, backdrop-mysql:8.0) + const mysqlMatch = type.match(/(?:^|-)mysql(?::(\d+(?:\.\d+)?))?(?:$|[^a-z])/); + if (mysqlMatch && !mysqlVersion) mysqlVersion = mysqlMatch[1] || '8.0'; + // Match mariadb or mariadb:X, including recipe prefixes (e.g., backdrop-mariadb:10.6) + const mariaMatch = type.match(/(?:^|-)mariadb(?::(\d+(?:\.\d+)?))?(?:$|[^a-z])/); + if (mariaMatch && !mariaVersion) mariaVersion = mariaMatch[1] || '11.4'; } if (mariaVersion && mysqlVersion) { From b9d18d63b986de4efc0eff6974ed48f6e25fcad1 Mon Sep 17 00:00:00 2001 From: Aaron Feledy Date: Thu, 19 Feb 2026 21:20:38 -0600 Subject: [PATCH 8/8] fix: use ssl-mode=PREFERRED instead of DISABLED MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PREFERRED still uses SSL when available but won't fail on self-signed certs. DISABLED was too aggressive — it would break connections to servers requiring secure transport. --- scripts/mysql-client-install.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/mysql-client-install.sh b/scripts/mysql-client-install.sh index 3358ca99..6444d823 100755 --- a/scripts/mysql-client-install.sh +++ b/scripts/mysql-client-install.sh @@ -50,15 +50,15 @@ mkdir -p /etc/mysql/conf.d cat > /etc/mysql/conf.d/lando.cnf << 'MYCNF' [client] default-character-set=utf8mb4 -# Disable SSL verification for local dev — containers on the same Docker -# network don't need encrypted connections, and older MySQL versions -# (e.g. 5.7) use self-signed certs that cause verification failures -ssl-mode=DISABLED +# Use PREFERRED so SSL is used when available but self-signed certs +# (e.g. MySQL 5.7 defaults) don't cause verification failures. +# Preserves SSL for servers that support it +ssl-mode=PREFERRED [mysqldump] # Prevent column-statistics errors with newer mysqldump skip-column-statistics -ssl-mode=DISABLED +ssl-mode=PREFERRED MYCNF if ! mysql --version 2>/dev/null; then