diego-ninja / docker
在PHP代码中运行和管理docker容器
Requires
- php: ^8.2
- spatie/macroable: ^2.0
- symfony/process: ^6.0 || ^7.0
Requires (Dev)
- captainhook/captainhook: ^5.10
- captainhook/plugin-composer: ^5.3
- ergebnis/composer-normalize: ^2.30
- friendsofphp/php-cs-fixer: ^3.40
- icanhazstring/composer-unused: ^0.8.7
- maglnet/composer-require-checker: ^4.5
- pestphp/pest: ^1.22
- php-parallel-lint/php-console-highlighter: ^1.0
- php-parallel-lint/php-parallel-lint: ^1.3
- phpstan/extension-installer: ^1.3
- phpstan/phpstan: ^1.10
- spatie/ssh: ^1.7.0
- symfony/var-dumper: ^5.3
README
此包提供了一种优雅的方式来启动docker容器并在其上执行命令。
$containerInstance = DockerContainer::create($imageName)->start(); $process = $containerInstance->execute('whoami'); $process->getOutput(); // returns the name of the user inside the docker container
差异
此包是基于spatie/docker的分支,并进行了一些适配以满足我的特定需求。
主要差异包括:此包取消了php 7.x的支持,并允许使用库与已创建的容器。此外,所有返回Symfony进程对象的函数现在都接受一个$async标志,以便异步运行进程,使用start方法而不是run方法。最后,start方法现在接受一个可选的可调用对象,如果存在,则可调用对象将在容器运行时连续调用,此可调用对象将接受Symfony Process对象作为其唯一参数。
$containerInstance = DockerContainerInstance::fromExisting("test-runner"); // uses a running container $spinner = new Spinner("Running unit tests...") // starts a console spinner $process = $containerInstance->execute('php vendor/bin/phpunit', true); // starts process asynchronous while($process->isRunning()) { $spinner->advance(); // updates spinner usleep(2000); } $process->isSuccessful() ? $spinner->success() : $spinner->error(); // finishes spinner based on result
安装
您可以通过composer安装此包
composer require diego-ninja/docker
使用方法
您可以使用以下方式获取docker容器的实例
$containerInstance = DockerContainer::create($imageName)->start();
默认情况下,容器将以守护进程形式运行,并在其存在后进行清理。
自定义docker容器
防止守护进程化
如果您不希望您的docker被守护进程化,请调用doNotDaemonize
。
$containerInstance = DockerContainer::create($imageName) ->doNotDaemonize() ->start();
防止自动清理
如果您不希望您的docker在存在后进行清理,请调用doNotCleanUpAfterExit
。
$containerInstance = DockerContainer::create($imageName) ->doNotCleanUpAfterExit() ->start();
特权
如果您希望您的docker具有特权,请调用privileged
。
$containerInstance = DockerContainer::create($imageName) ->privileged() ->start();
自定义shell
如果您的docker镜像中没有可用的bash shell,您可以使用其他shell进行指定。
$containerInstance = DockerContainer::create($imageName) ->shell('sh') ->start();
命名容器
您可以通过将名称作为构造函数的第二个参数传递来命名容器。
new DockerContainer($imageName, $nameOfContainer);
或者,使用name
方法。
$containerInstance = DockerContainer::create($imageName) ->name($yourName) ->start();
映射端口
您可以使用mapPort
方法在主机机器和docker容器之间映射端口。要映射多个端口,只需多次调用mapPort
。
$containerInstance = DockerContainer::create($imageName) ->mapPort($portOnHost, $portOnContainer) ->mapPort($anotherPortOnHost, $anotherPortOnContainer) ->start();
环境变量
您可以使用setEnvironmentVariable
方法设置环境变量。要添加多个参数,只需多次调用setEnvironmentVariable
。
$containerInstance = DockerContainer::create($imageName) ->setEnvironmentVariable($variableKey, $variableValue) ->setEnvironmentVariable($anotherVariableKey, $anotherVariableValue) ->start();
设置卷
您可以使用setVolume
方法设置卷。要添加多个参数,只需多次调用setVolume
。
$containerInstance = DockerContainer::create($imageName) ->setVolume($pathOnHost, $pathOnDocker) ->setVolume($anotherPathOnHost, $anotherPathOnDocker) ->start();
设置标签
您可以使用setLabel
方法设置标签。要添加多个参数,只需多次调用setLabel
。
$containerInstance = DockerContainer::create($imageName) ->setLabel($labelName, $labelValue) ->setLabel($anotherLabelName, $anotherLabelValue) ->start();
添加命令
您可以使用setCommands
方法添加命令。
$containerInstance = DockerContainer::create($imageName) ->setCommands('--api.insecure=true', '--providers.docker=true') ->start();
这些命令将放在docker run
命令的末尾。
添加可选参数
如果您想向docker run
命令添加可选参数,请使用setOptionalArgs
方法
$containerInstance = DockerContainer::create($imageName) ->setOptionalArgs('-it', '-a') ->start();
这些参数将放置在docker run
之后。
在PHP结束时自动停止容器
当在测试环境中使用此包时,在调用它上的__destruct
后停止docker容器可能很有用(这通常发生在PHP脚本结束时)。您可以通过使用stopOnDestruct
方法启用此行为。
$containerInstance = DockerContainer::create($imageName) ->stopOnDestruct() ->start();
将网络附加到容器
如果您想将容器连接到Docker网络,请使用network
方法
$containerInstance = DockerContainer::create($imageName) ->network('my-network') ->start();
指定用于执行的远程Docker主机
您可以设置用于执行容器的宿主。Docker命令行接受守护进程套接字字符串。要通过SSH连接到远程Docker主机,请使用语法ssh://username@hostname
。注意,您需要预先配置正确的SSH密钥以进行此操作。
$containerInstance = DockerContainer::create($imageName) ->remoteHost('ssh://username@hostname') ->start();
指定要执行的替代命令
在容器启动时,Docker将执行容器内定义的命令。使用command
方法可以覆盖容器内默认要运行的命令。
$containerInstance = DockerContainer::create($imageName) ->command('ls -l /etc') ->start();
获取启动命令字符串
您可以使用getStartCommand
函数获取容器启动时将要执行的字符串
// returns "docker run -d --rm spatie/docker" DockerContainer::create($imageName)->getStartCommand();
更改启动命令超时时间
您可以使用setStartCommandTimeout
函数更改启动命令的超时时间(默认为60秒)。
$containerInstance = DockerContainer::create($imageName) ->setStartCommandTimeout(120) ->start();
Docker容器实例上的可用方法
执行命令
要在容器上执行命令,请使用execute
方法。
$process = $instance->execute($command);
您可以通过传递一个数组一次性执行多个命令。
$process = $instance->execute([$command, $anotherCommand]); $asyncProcess = $instance->execute([$command, $anotherCommand], true);
要更改进程超时,您可以在execute
方法中传递第三个参数(默认为60秒)。
$process = $instance->execute([$command, $anotherCommand], false, 3600);
execute
方法返回一个Symfony/Process
实例。
您可以使用isSuccessful
方法检查命令是否成功运行
$process->isSuccessful(); // returns a boolean
您可以使用getOutput()
获取输出。如果命令没有成功运行,您可以使用getErrorOutput()
。有关如何使用Process
的更多信息,请参阅Symfony文档。
安装公钥
如果您想通过SSH连接到容器实例,您可能需要向其中添加公钥。
这可以通过使用addPublicKey
方法来完成。
$instance->addPublicKey($pathToPublicKey);
假设authorized_keys
文件位于/root/.ssh/authorized_keys
。如果不是这种情况,您可以将该文件的路径指定为第二个参数。
$instance->addPublicKey($pathToPublicKey, $pathToAuthorizedKeys);
请注意,为了能够通过SSH连接,您应该在dockerfile
中设置SSH服务器。请参阅此包的测试中的dockerfile
示例。
向实例添加文件
您可以使用addFiles
向实例添加文件。
$instance->addFiles($fileOrDirectoryOnHost, $pathInContainer);
获取Docker inspect信息
使用inspect
可以检索从Docker inspect命令解码的JSON数组。
$inspectArray = $instance->inspect(); $inspectArray[0]['State']['Status']; // Running, Starting etc. $inspectArray[0]['RestartCount']; // Integer $inspectArray[0]['NetworkSettings']['IPAddress']; // 172.17.0.2
向Docker实例添加其他函数
Ninja\Docker\ContainerInstance
类是可宏定义的。这意味着您可以向其中添加额外的函数。
Ninja\Docker\DockerContainerInstance::macro('whoAmI', function () { $process = $containerInstance->run('whoami'); return $process->getOutput(); }); $containerInstance = DockerContainer::create($imageName)->start(); $containerInstance->whoAmI(); // returns of name of user in the docker container
测试
在首次运行测试之前,您必须使用以下命令构建spatie/docker
容器:
composer build-docker
接下来,您可以使用以下命令运行测试:
composer test
变更日志
有关最近更改的更多信息,请参阅变更日志。
贡献
有关详细信息,请参阅贡献指南。
安全性
如果您发现有关安全的错误,请通过security@spatie.be发送邮件,而不是使用问题跟踪器。
鸣谢
许可
MIT许可(MIT)。有关更多信息,请参阅许可文件。