Improvements to docker detection (#12062)
* Improvements to docker detection, fixes #11073 * Apply suggestions from code review Co-authored-by: Dan Wallis <dan@wallis.nz>pull/12090/head
parent
d3d378184b
commit
9da1948585
|
@ -39,3 +39,10 @@ Also note that the `exec` command will always run third party code as the user w
|
||||||
|
|
||||||
See the [COMPOSER_ALLOW_SUPERUSER](../03-cli.md#composer-allow-superuser) environment variable for
|
See the [COMPOSER_ALLOW_SUPERUSER](../03-cli.md#composer-allow-superuser) environment variable for
|
||||||
more info on how to disable the warnings.
|
more info on how to disable the warnings.
|
||||||
|
|
||||||
|
## Running Composer inside Docker/Podman containers
|
||||||
|
|
||||||
|
Composer makes a best effort attempt to detect that it runs inside a container and if so it will
|
||||||
|
allow running as root without any further issues. If that detection fails however you will
|
||||||
|
see warnings and plugins will be disabled unless you set the [COMPOSER_ALLOW_SUPERUSER](../03-cli.md#composer-allow-superuser)
|
||||||
|
environment variable.
|
||||||
|
|
|
@ -218,11 +218,7 @@ class Application extends BaseApplication
|
||||||
$needsSudoCheck = !Platform::isWindows()
|
$needsSudoCheck = !Platform::isWindows()
|
||||||
&& function_exists('exec')
|
&& function_exists('exec')
|
||||||
&& !Platform::getEnv('COMPOSER_ALLOW_SUPERUSER')
|
&& !Platform::getEnv('COMPOSER_ALLOW_SUPERUSER')
|
||||||
&& (ini_get('open_basedir') || (
|
&& !Platform::isDocker();
|
||||||
!file_exists('/.dockerenv')
|
|
||||||
&& !file_exists('/run/.containerenv')
|
|
||||||
&& !file_exists('/var/run/.containerenv')
|
|
||||||
));
|
|
||||||
$isNonAllowedRoot = false;
|
$isNonAllowedRoot = false;
|
||||||
|
|
||||||
// Clobber sudo credentials if COMPOSER_ALLOW_SUPERUSER is not set before loading plugins
|
// Clobber sudo credentials if COMPOSER_ALLOW_SUPERUSER is not set before loading plugins
|
||||||
|
|
|
@ -25,6 +25,8 @@ class Platform
|
||||||
private static $isVirtualBoxGuest = null;
|
private static $isVirtualBoxGuest = null;
|
||||||
/** @var ?bool */
|
/** @var ?bool */
|
||||||
private static $isWindowsSubsystemForLinux = null;
|
private static $isWindowsSubsystemForLinux = null;
|
||||||
|
/** @var ?bool */
|
||||||
|
private static $isDocker = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getcwd() equivalent which always returns a string
|
* getcwd() equivalent which always returns a string
|
||||||
|
@ -153,12 +155,10 @@ class Platform
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!ini_get('open_basedir')
|
!(bool) ini_get('open_basedir')
|
||||||
&& is_readable('/proc/version')
|
&& is_readable('/proc/version')
|
||||||
&& false !== stripos((string)Silencer::call('file_get_contents', '/proc/version'), 'microsoft')
|
&& false !== stripos((string)Silencer::call('file_get_contents', '/proc/version'), 'microsoft')
|
||||||
&& !file_exists('/.dockerenv') // Docker and Podman running inside WSL should not be seen as WSL
|
&& !self::isDocker() // Docker and Podman running inside WSL should not be seen as WSL
|
||||||
&& !file_exists('/run/.containerenv')
|
|
||||||
&& !file_exists('/var/run/.containerenv')
|
|
||||||
) {
|
) {
|
||||||
return self::$isWindowsSubsystemForLinux = true;
|
return self::$isWindowsSubsystemForLinux = true;
|
||||||
}
|
}
|
||||||
|
@ -175,6 +175,40 @@ class Platform
|
||||||
return \defined('PHP_WINDOWS_VERSION_BUILD');
|
return \defined('PHP_WINDOWS_VERSION_BUILD');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function isDocker(): bool
|
||||||
|
{
|
||||||
|
if (null !== self::$isDocker) {
|
||||||
|
return self::$isDocker;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cannot check so assume no
|
||||||
|
if ((bool) ini_get('open_basedir')) {
|
||||||
|
return self::$isDocker = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .dockerenv and .containerenv are present in some cases but not reliably
|
||||||
|
if (file_exists('/.dockerenv') || file_exists('/run/.containerenv') || file_exists('/var/run/.containerenv')) {
|
||||||
|
return self::$isDocker = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// see https://www.baeldung.com/linux/is-process-running-inside-container
|
||||||
|
$cgroups = [
|
||||||
|
'/proc/self/mountinfo', // cgroup v2
|
||||||
|
'/proc/1/cgroup', // cgroup v1
|
||||||
|
];
|
||||||
|
foreach($cgroups as $cgroup) {
|
||||||
|
if (!is_readable($cgroup)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$data = file_get_contents($cgroup);
|
||||||
|
if (is_string($data) && str_contains($data, '/var/lib/docker/')) {
|
||||||
|
return self::$isDocker = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$isDocker = false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int return a guaranteed binary length of the string, regardless of silly mbstring configs
|
* @return int return a guaranteed binary length of the string, regardless of silly mbstring configs
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue