Coder Social home page Coder Social logo

docker's Introduction

Manage docker containers with PHP

Latest Version on Packagist GitHub Tests Action Status Total Downloads

This package provides a nice way to start docker containers and execute commands on them.

$containerInstance = DockerContainer::create($imageName)->start();

$process = $containerInstance->execute('whoami');

$process->getOutput(); // returns the name of the user inside the docker container

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Installation

You can install the package via composer:

composer require spatie/docker

Usage

You can get an instance of a docker container using

$containerInstance = DockerContainer::create($imageName)->start();

By default the container will be daemonized and it will be cleaned up after it exists.

Customizing the docker container

Prevent daemonization

If you don't want your docker being daemonized, call doNotDaemonize.

$containerInstance = DockerContainer::create($imageName)
    ->doNotDaemonize()
    ->start();

Prevent automatic clean up

If you don't want your docker being cleaned up after it exists, call doNotCleanUpAfterExit.

$containerInstance = DockerContainer::create($imageName)
    ->doNotCleanUpAfterExit()
    ->start();

Priviliged

If you want your docker being privileged, call privileged.

$containerInstance = DockerContainer::create($imageName)
    ->privileged()
    ->start();

Custom shell

If the bash shell is not available in your docker image, you can specify an alternative shell.

$containerInstance = DockerContainer::create($imageName)
    ->shell('sh')
    ->start();

Custom docker binary

If the docker binary is not globally available, you can specify the exact path.

$containerInstance = DockerContainer::create($imageName)
    ->dockerBin('/usr/local/bin/docker')
    ->start();

Naming the container

You can name the container by passing the name as the second argument to the constructor.

new DockerContainer($imageName, $nameOfContainer);

Alternatively, use the name method.

$containerInstance = DockerContainer::create($imageName)
    ->name($yourName)
    ->start();

Mapping ports

You can map ports between the host machine and the docker container using the mapPort method. To map multiple ports, just call mapPort multiple times.

$containerInstance = DockerContainer::create($imageName)
    ->mapPort($portOnHost, $portOnContainer)
    ->mapPort($anotherPortOnHost, $anotherPortOnContainer)
    ->start();

Environment variables

You can set environment variables using the setEnvironmentVariable method. To add multiple arguments, just call setEnvironmentVariable multiple times.

$containerInstance = DockerContainer::create($imageName)
    ->setEnvironmentVariable($variableKey, $variableValue)
    ->setEnvironmentVariable($anotherVariableKey, $anotherVariableValue)
    ->start();

Setting Volumes

You can set volumes using the setVolume method. To add multiple arguments, just call setVolume multiple times.

$containerInstance = DockerContainer::create($imageName)
    ->setVolume($pathOnHost, $pathOnDocker)
    ->setVolume($anotherPathOnHost, $anotherPathOnDocker)
    ->start();

Setting Labels

You can set labels using the setLabel method. To add multiple arguments, just call setLabel multiple times.

$containerInstance = DockerContainer::create($imageName)
    ->setLabel($labelName, $labelValue)
    ->setLabel($anotherLabelName, $anotherLabelValue)
    ->start();

Adding Commands

You can add commands using the setCommands method.

$containerInstance = DockerContainer::create($imageName)
    ->setCommands('--api.insecure=true', '--providers.docker=true')
    ->start();

These commands will be placed at the end of to the docker run command.

Add optional arguments

If you want to add optional arguments to the docker run command, use setOptionalArgs method:

$containerInstance = DockerContainer::create($imageName)
    ->setOptionalArgs('-it', '-a')
    ->start();

These arguments will be placed after docker run immediately.

Automatically stopping the container after PHP exists

When using this package in a testing environment, it can be handy that the docker container is stopped after __destruct is called on it (mostly this will happen when the PHP script ends). You can enable this behaviour with the stopOnDestruct method.

$containerInstance = DockerContainer::create($imageName)
    ->stopOnDestruct()
    ->start();

Attaching a network to the container

If you want to attach the container to a docker network, use network method:

$containerInstance = DockerContainer::create($imageName)
    ->network('my-network')
    ->start();

Specify a remote docker host for execution

You can set the host used for executing the container. The docker command line accepts a daemon socket string. To connect to a remote docker host via ssh, use the syntax ssh://username@hostname. Note that the proper SSH keys will already need to be configured for this work.

$containerInstance = DockerContainer::create($imageName)
    ->remoteHost('ssh://username@hostname')
    ->start();

Specify an alternative command to execute

Upon startup of a container, docker will execute the command defined within the container. The command method gives the ability to override to default command to run within the container.

$containerInstance = DockerContainer::create($imageName)
    ->command('ls -l /etc')
    ->start();

Getting the start command string

You can get the string that will be executed when a container is started with the getStartCommand function

// returns "docker run -d --rm spatie/docker"
DockerContainer::create($imageName)->getStartCommand();

Changing the start command timeout

You can change the timeout for the start command with the setStartCommandTimeout function (the default is 60s).

$containerInstance = DockerContainer::create($imageName)
    ->setStartCommandTimeout(120)
    ->start();

Available methods on the docker container instance

Executing a command

To execute a command on the container, use the execute method.

$process = $instance->execute($command);

You can execute multiple command in one go by passing an array.

$process = $instance->execute([$command, $anotherCommand]);

To change the process timeout you can pass a second parameter to the execute method (the default is 60s).

$process = $instance->execute($command, 3600);

The execute method returns an instance of Symfony/Process.

You can check if your command ran successfully using the isSuccessful $method

$process->isSuccessful(); // returns a boolean

You can get to the output using getOutput(). If the command did not run successfully, you can use getErrorOutput(). For more information on how to work with a Process head over to the Symfony docs.

Installing a public key

If you cant to connect to your container instance via SSH, you probably want to add a public key to it.

This can be done using the addPublicKey method.

$instance->addPublicKey($pathToPublicKey);

It is assumed that the authorized_keys file is located in at /root/.ssh/authorized_keys. If this is not the case, you can specify the path of that file as a second parameter.

$instance->addPublicKey($pathToPublicKey, $pathToAuthorizedKeys);

Note that in order to be able to connect via SSH, you should set up a SSH server in your dockerfile. Take a look at the dockerfile in the tests of this package for an example.

Adding files to your instance

Files can be added to an instance with addFiles.

$instance->addFiles($fileOrDirectoryOnHost, $pathInContainer);

Get the docker inspect information

The json decoded array from the docker inspect command can be retrieved with inspect.

$inspectArray = $instance->inspect();
$inspectArray[0]['State']['Status']; // Running, Starting etc.
$inspectArray[0]['RestartCount']; // Integer
$inspectArray[0]['NetworkSettings']['IPAddress']; // 172.17.0.2

Adding other functions on the docker instance

The Spatie\Docker\ContainerInstance class is macroable. This means you can add extra functions to it.

Spatie\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

Testing

Before running the tests for the first time, you must build the spatie/docker container with:

composer build-docker

Next, you can run the tests with:

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you've found a bug regarding security please mail [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

docker's People

Contributors

adrianmrn avatar atefbb avatar ayoobmh avatar dimitri-koenig avatar erjanmx avatar exileed avatar fernandokbs avatar freekmurze avatar galironfydar avatar inmanturbo avatar jbraband avatar jkniest avatar m1guelpf avatar maartenpaauw avatar patinthehat avatar rubenvanassche avatar saschahemleb avatar sfolador avatar spekulatius avatar szepeviktor avatar thecaliskan avatar tiagof avatar tomwelch avatar vedelaar avatar wajdijurry avatar walderlansena avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

docker's Issues

Request: A convenient way to get the docker instance at any time

So all of the DockerContainerInstance methods are available after you create a DockerContainer by accessing the instance. Should there be a way to find the docker container at any time?

My use case would be saving the docker container name within a DB then after a period of time "find" that container again then perform ->execute() or ->stop().

Have i missed something? Could I use the DockerContainerInstance to get that container again already?

Add optional arguments after `docker run` command

Needs:
When I need to pass -it for example to the docker run command, I can't since there is no option to pass these optional arguments.

Example:

docker run -it --name example -d redis:latest

Is there any intention to add the ability to pass optional arguments to docker run command ?

Add image enviroment variables as an argument

It would be great to add an option to add variables to the docker image on create.

This is often used in docker using the -e argument to set variables.

$container = DockerContainer::create("mysql/mysql-server:5.7")
            ->name("db")
            ->setVariable("MYSQL_ROOT_PASSWORD", "root")
            ->mapPort("3306", "3306")
            ->getStartCommand();

Would return something like:

docker run -p 3306:3306--name db -e MYSQL_ROOT_PASSWORD=root -d --rm mysql/mysql-server:5.7

Windows support

Does this package support Windows?

(Sorry for the stupid question😢)

Add networking support

It would be nice if there was an API for the --network CLI argument to configure networks of the Docker container instances.

Using spatie/macroable 2.0.0 in PHP 8.1

Using spatie/macroable 2.0.0 in PHP 8.1
In PHP 8.1 you have to lower spatie/macroable to 1.0.1.
Can't upgrade to 2.0.0?
Other spatie packages are using 2.0.0

Issue with unescaped ENV variables when calling `execute`

Because of the way this library echos and pipes commands into docker, using environment variables with execute gives unexpected behaviour.

For example this does not echo 'some-value' but an empty string, because $MY_VARIABLE is evaluated on my host, and not in the container.

$container = DockerContainer::create('image-name')
    ->setEnvironmentVariable('MY_VARIABLE', 'some-value')
    ->start();

$process = $container->execute('echo $MY_VARIABLE');
echo $process->getOutput(); // returns ''

Escaping the $ before MY_VARIABLE makes it work as you'd expect (being evaluated in the container).

I think the answer is a simple:

$command = escapeshellcmd($command);

in DockerContainer::getExecCommand(); before:

"echo \"{$command}\"",

Happy to send a PR if that sounds correct - there's a risk of it being a breaking change if somebody is already working around the problem by escaping their execute() arguments though.

The container name "/docker-instance" is already in use by container "..."

When seting up the Docker container within the setUp method of my TestCase in Laravel (a fresh and newly installed one). I can't get the destruct option to work for me:

public function setUp(): void
{
    parent::setUp();

    $this->container = DockerContainer::create('markvaneijk/docker')
        ->name('docker-instance')
        ->mapPort(4848, 22)
        ->stopOnDestruct()
        ->start();
}

When running PHPUnit I get:

Spatie\Docker\Exceptions\CouldNotStartDockerContainer: Could not start docker container for image markvaneijk/docker. Process output: docker: Error response from daemon: Conflict. The container name "/docker-instance" is already in use by container "0c9ff467ca3be1ddcabf085c025f957c6ee268cc8a2e0b20362f798e3205eadb". You have to remove (or rename) that container to be able to reuse that name.

I also tried putting this inside the test itself, but than I get the same error.

But it does work when I start and stop the container inside every test, so it seems like the destruct does not work as expected. Or did I forgot something to take care off?

No found class

I am installed on my computer this package, restarted php, apache2, but package isn't working.
Screenshot_18

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.