Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions readme-vars.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ init_diagram: |
"phpmyadmin:latest" <- Base Images
# changelog
changelogs:
- {date: "23.08.25:", desc: "Add support for mTLS. Existing users will need to delete their config.inc.php and restart the container."}
- {date: "05.07.25:", desc: "Rebase to Alpine 3.22."}
- {date: "19.12.24:", desc: "Rebase to Alpine 3.21."}
- {date: "27.05.24:", desc: "Existing users should update their nginx confs to avoid http2 deprecation warnings."}
Expand Down
137 changes: 115 additions & 22 deletions root/defaults/config.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

// Sourced from https://github.com/phpmyadmin/docker/blob/master/config.inc.php

require('/config/phpmyadmin/config.secret.inc.php');
require_once '/config/phpmyadmin/config.secret.inc.php';
require_once '/config/phpmyadmin/helpers.php';

/* Ensure we got the environment */
$vars = array(
$vars = [
'PMA_ARBITRARY',
'PMA_HOST',
'PMA_HOSTS',
Expand All @@ -26,20 +27,45 @@
'PMA_QUERYHISTORYDB',
'PMA_QUERYHISTORYMAX',
'MAX_EXECUTION_TIME',
'MEMORY_LIMIT'
);
'MEMORY_LIMIT',
'PMA_UPLOADDIR',
'PMA_SAVEDIR',
'PMA_SSL',
'PMA_SSLS',
'PMA_SSL_DIR',
'PMA_SSL_VERIFY',
'PMA_SSL_VERIFIES',
'PMA_SSL_CA',
'PMA_SSL_CAS',
'PMA_SSL_CA_BASE64',
'PMA_SSL_CAS_BASE64',
'PMA_SSL_KEY',
'PMA_SSL_KEYS',
'PMA_SSL_KEY_BASE64',
'PMA_SSL_KEYS_BASE64',
'PMA_SSL_CERT',
'PMA_SSL_CERTS',
'PMA_SSL_CERT_BASE64',
'PMA_SSL_CERTS_BASE64',
];

foreach ($vars as $var) {
$env = getenv($var);
if (!isset($_ENV[$var]) && $env !== false) {
$_ENV[$var] = $env;
}
}

if (! defined('PMA_SSL_DIR')) {
define('PMA_SSL_DIR', $_ENV['PMA_SSL_DIR'] ?? '/config/phpmyadmin/ssl');
}

if (isset($_ENV['PMA_QUERYHISTORYDB'])) {
$cfg['QueryHistoryDB'] = boolval($_ENV['PMA_QUERYHISTORYDB']);
$cfg['QueryHistoryDB'] = (bool) $_ENV['PMA_QUERYHISTORYDB'];
}

if (isset($_ENV['PMA_QUERYHISTORYMAX'])) {
$cfg['QueryHistoryMax'] = intval($_ENV['PMA_QUERYHISTORYMAX']);
$cfg['QueryHistoryMax'] = (int) $_ENV['PMA_QUERYHISTORYMAX'];
}

/* Arbitrary server connection */
Expand All @@ -52,29 +78,84 @@
$cfg['PmaAbsoluteUri'] = trim($_ENV['PMA_ABSOLUTE_URI']);
}

if (isset($_ENV['PMA_SSL_CA_BASE64'])) {
$_ENV['PMA_SSL_CA'] = decodeBase64AndSaveFiles($_ENV['PMA_SSL_CA_BASE64'], 'phpmyadmin-ssl-CA', 'pem', PMA_SSL_DIR);
}

/* Decode and save the SSL key from base64 */
if (isset($_ENV['PMA_SSL_KEY_BASE64'])) {
$_ENV['PMA_SSL_KEY'] = decodeBase64AndSaveFiles($_ENV['PMA_SSL_KEY_BASE64'], 'phpmyadmin-ssl-CERT', 'cert', PMA_SSL_DIR);
}

/* Decode and save the SSL certificate from base64 */
if (isset($_ENV['PMA_SSL_CERT_BASE64'])) {
$_ENV['PMA_SSL_CERT'] = decodeBase64AndSaveFiles($_ENV['PMA_SSL_CERT_BASE64'], 'phpmyadmin-ssl-CERT', 'cert', PMA_SSL_DIR);
}

/* Decode and save multiple SSL CA certificates from base64 */
if (isset($_ENV['PMA_SSL_CAS_BASE64'])) {
$_ENV['PMA_SSL_CAS'] = decodeBase64AndSaveFiles($_ENV['PMA_SSL_CAS_BASE64'], 'phpmyadmin-ssl-CA', 'pem', PMA_SSL_DIR);
}

/* Decode and save multiple SSL keys from base64 */
if (isset($_ENV['PMA_SSL_KEYS_BASE64'])) {
$_ENV['PMA_SSL_KEYS'] = decodeBase64AndSaveFiles($_ENV['PMA_SSL_KEYS_BASE64'], 'phpmyadmin-ssl-CERT', 'cert', PMA_SSL_DIR);
}

/* Decode and save multiple SSL certificates from base64 */
if (isset($_ENV['PMA_SSL_CERTS_BASE64'])) {
$_ENV['PMA_SSL_CERTS'] = decodeBase64AndSaveFiles($_ENV['PMA_SSL_CERTS_BASE64'], 'phpmyadmin-ssl-KEY', 'key', PMA_SSL_DIR);
}

/* Figure out hosts */

/* Fallback to default linked */
$hosts = array('db');
$hosts = ['db'];

/* Set by environment */
if (!empty($_ENV['PMA_HOST'])) {
$hosts = array($_ENV['PMA_HOST']);
$verbose = array($_ENV['PMA_VERBOSE']);
$ports = array($_ENV['PMA_PORT']);
} elseif (!empty($_ENV['PMA_HOSTS'])) {
if (! empty($_ENV['PMA_HOST'])) {
$hosts = [$_ENV['PMA_HOST']];
$verbose = [$_ENV['PMA_VERBOSE']];
$ports = [$_ENV['PMA_PORT']];
$ssls = [$_ENV['PMA_SSL']];
$ssl_verifies = [$_ENV['PMA_SSL_VERIFY']];
$ssl_cas = [$_ENV['PMA_SSL_CA']];
$ssl_keys = [$_ENV['PMA_SSL_KEY']];
$ssl_certs = [$_ENV['PMA_SSL_CERT']];
} elseif (! empty($_ENV['PMA_HOSTS'])) {
$hosts = array_map('trim', explode(',', $_ENV['PMA_HOSTS']));
$verbose = array_map('trim', explode(',', $_ENV['PMA_VERBOSES']));
$ports = array_map('trim', explode(',', $_ENV['PMA_PORTS']));
$ssls = array_map('trim', explode(',', $_ENV['PMA_SSLS']));
$ssl_verifies = array_map('trim', explode(',', $_ENV['PMA_SSL_VERIFIES']));
$ssl_cas = array_map('trim', explode(',', $_ENV['PMA_SSL_CAS']));
$ssl_keys = array_map('trim', explode(',', $_ENV['PMA_SSL_KEYS']));
$ssl_certs = array_map('trim', explode(',', $_ENV['PMA_SSL_CERTS']));
}
if (!empty($_ENV['PMA_SOCKET'])) {
$sockets = array($_ENV['PMA_SOCKET']);
} elseif (!empty($_ENV['PMA_SOCKETS'])) {

if (! empty($_ENV['PMA_SOCKET'])) {
$sockets = [$_ENV['PMA_SOCKET']];
} elseif (! empty($_ENV['PMA_SOCKETS'])) {
$sockets = explode(',', $_ENV['PMA_SOCKETS']);
}

/* Server settings */
for ($i = 1; isset($hosts[$i - 1]); $i++) {
if (isset($ssls[$i - 1]) && $ssls[$i - 1] === '1') {
$cfg['Servers'][$i]['ssl'] = $ssls[$i - 1];
}
if (isset($ssl_verifies[$i - 1]) && $ssl_verifies[$i - 1] === '1') {
$cfg['Servers'][$i]['ssl_verify'] = $ssl_verifies[$i - 1];
}
if (isset($ssl_cas[$i - 1])) {
$cfg['Servers'][$i]['ssl_ca'] = $ssl_cas[$i - 1];
}
if (isset($ssl_keys[$i - 1])) {
$cfg['Servers'][$i]['ssl_key'] = $ssl_keys[$i - 1];
}
if (isset($ssl_certs[$i - 1])) {
$cfg['Servers'][$i]['ssl_cert'] = $ssl_certs[$i - 1];
}
$cfg['Servers'][$i]['host'] = $hosts[$i - 1];
if (isset($verbose[$i - 1])) {
$cfg['Servers'][$i]['verbose'] = $verbose[$i - 1];
Expand Down Expand Up @@ -126,9 +207,10 @@
$cfg['Servers'][$i]['compress'] = false;
$cfg['Servers'][$i]['AllowNoPassword'] = true;
}
for ($i = 1; isset($sockets[$i - 1]); $i++) {
$cfg['Servers'][$i]['socket'] = $sockets[$i - 1];
$cfg['Servers'][$i]['host'] = 'localhost';
// Avoid overwriting the last server id $i, use another variable name
for ($socketHostId = 1; isset($sockets[$socketHostId - 1]); $socketHostId++) {
$cfg['Servers'][$socketHostId]['socket'] = $sockets[$socketHostId - 1];
$cfg['Servers'][$socketHostId]['host'] = 'localhost';
}
/*
* Revert back to last configured server to make
Expand All @@ -137,9 +219,13 @@
$i--;

/* Uploads setup */
$cfg['UploadDir'] = '';
$cfg['SaveDir'] = '';
$cfg['TempDir'] = '/tmp';
if (isset($_ENV['PMA_UPLOADDIR'])) {
$cfg['UploadDir'] = $_ENV['PMA_UPLOADDIR'];
}

if (isset($_ENV['PMA_SAVEDIR'])) {
$cfg['SaveDir'] = $_ENV['PMA_SAVEDIR'];
}

if (isset($_ENV['MAX_EXECUTION_TIME'])) {
$cfg['ExecTimeLimit'] = $_ENV['MAX_EXECUTION_TIME'];
Expand All @@ -151,5 +237,12 @@

/* Include User Defined Settings Hook */
if (file_exists('/config/phpmyadmin/config.user.inc.php')) {
include('/config/phpmyadmin/config.user.inc.php');
include '/config/phpmyadmin/config.user.inc.php';
}

/* Support additional configurations */
if (is_dir('/config/phpmyadmin/conf.d/')) {
foreach (glob('/config/phpmyadmin/conf.d/*.php') as $filename) {
include $filename;
}
}
53 changes: 53 additions & 0 deletions root/defaults/helpers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

// Sourced from https://github.com/phpmyadmin/docker/blob/master/helpers.php

declare(strict_types=1);

/**
* Helper function to decode and save multiple SSL files from base64.
*
* @param string $base64FilesContents The base64 encoded string containing multiple files separated by commas.
* If no commas are present, the entire string is treated as a single file.
* @param string $prefix The prefix to use for the generated file names.
* @param string $extension The file extension to use for the generated files.
* @param string $storageFolder The folder where to store the generated files.
*
* @return string A comma-separated list of paths to the generated files.
*/
function decodeBase64AndSaveFiles(string $base64FilesContents, string $prefix, string $extension, string $storageFolder): string
{
// Ensure the output directory exists
if (! is_dir($storageFolder)) {
mkdir($storageFolder, 0755, true);
}

// Split the base64 string into an array of files
$base64FilesContents = explode(',', trim($base64FilesContents));
$counter = 1;
$outputFiles = [];

// Process each file
foreach ($base64FilesContents as $base64FileContent) {
$outputFile = $storageFolder . '/' . $prefix . '-' . $counter . '.' . $extension;

$fileContent = base64_decode($base64FileContent, true);
if ($fileContent === false) {
echo 'Failed to decode: ' . $base64FileContent;
exit(1);
}

// Write the decoded file to the output directory
if (file_put_contents($outputFile, $fileContent) === false) {
echo 'Failed to write to ' . $outputFile;
exit(1);
}

// Add the output file path to the list
$outputFiles[] = $outputFile;
$counter++;
}

// Return a comma-separated list of the generated file paths
return implode(',', $outputFiles);
}
4 changes: 4 additions & 0 deletions root/etc/s6-overlay/s6-rc.d/init-phpmyadmin-config/run
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ if [[ ! -f /config/phpmyadmin/config.inc.php ]]; then
cp /defaults/config.inc.php /config/phpmyadmin/config.inc.php
fi

if [[ ! -f /config/phpmyadmin/helpers.php ]]; then
cp /defaults/helpers.php /config/phpmyadmin/helpers.php
fi

if [[ -z ${LSIO_READ_ONLY_FS} ]] && [[ -z ${LSIO_NON_ROOT_USER} ]]; then
# Set up themes
if [[ -d "/config/themes" && ! -L "/app/www/public/themes" ]]; then
Expand Down