4

I'm trying to manage docker via PHP curl requests. (Using Ubuntu 15.10)

I have followed API documentation but it bit confusing and also followed a few online tutorials but no luck.

This is what I have done so far, stopped docker daemon and added

script
    /usr/bin/docker -H tcp://127.0.0.1:4243 -d
end script

to

/etc/init/docker.conf

Docker daemon started

This is My PHP script

function post_to_url($url, $data, $headers) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10); //timeout in seconds

    curl_setopt($ch, CURLOPT_URL, $url);
    if ($headers != '') {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }
    curl_setopt($ch, CURLOPT_POST, 1);
    if ($data != '') {
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    }

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $return = curl_exec($ch);
    if ($return == '') {
        return curl_getinfo($ch, CURLINFO_HTTP_CODE);
    } else {
        return $return;
    }
    curl_close($ch);
}
//Sample API request
echo post_to_url('http://127.0.0.1:4243/containers/json', '', '');

But I did not able to get any output via CURL request?

What I'm missing here?

G H Prakash
  • 1,720
  • 10
  • 30
M_R_K
  • 5,929
  • 1
  • 39
  • 40
  • In the very last line, `loclhost` should perhaps be `localhost`? :) – morphatic Jan 19 '16 at 03:41
  • @morphatic Nope that wasn't the issue. I tried with 127.0.0.1 – M_R_K Jan 19 '16 at 03:44
  • in the docker docs I don't see any mention of the `-d` flag that you've added to the script in your `docker.conf` file. Perhaps you meant `-D`. Using the wrong flag could prevent docker from starting properly. – morphatic Jan 19 '16 at 04:11

4 Answers4

2

Ubuntu 15.10 is a system that uses systemd. The /etc/init/docker.conf file is only used on systems that use upstart.

Read this section in the documentation on how to configure daemon options on a system that uses systemd:

Custom Docker daemon options

Please note that:

  • Port 4243 is no longer the standard port for docker. Use port 2375 (plain) and 2376 (for tls)
  • Remember that anybody that's able to obtain access to the API has effectively root permissions on your host. So never expose an unprotected API

Also note, that there's an (unofficial) PHP client-library that for docker; http://stage1.github.io/docker-php/ that may save you a lot of time and headaches :)

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
thaJeztah
  • 27,738
  • 9
  • 73
  • 92
2

Finally I was able to figure that out.

In /etc/defaults/docker I put

DOCKER_OPTS='-H tcp://127.0.0.1:4243 -H unix:///var/run/docker.sock'

(Use 0.0.0.0 instead of 127.0.0.1 to access API via any host)

My PHP function in the question is not compatible with REST API,

So I have used following function (Source - This)

// Method: POST, PUT, GET etc
// Data: array("param" => "value") ==> index.php?param=value

function CallAPI($method, $url, $data = false)
{
    $curl = curl_init();

    switch ($method)
    {
        case "POST":
            curl_setopt($curl, CURLOPT_POST, 1);

            if ($data)
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            break;
        case "PUT":
            curl_setopt($curl, CURLOPT_PUT, 1);
            break;
        default:
            if ($data)
                $url = sprintf("%s?%s", $url, http_build_query($data));
    }

    // Optional Authentication:
    curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($curl, CURLOPT_USERPWD, "username:password");

    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

    $result = curl_exec($curl);

    curl_close($curl);

    return $result;
}

And called above function:

echo CallAPI('GET', 'http://127.0.0.1:4243/images/json', $data = false)

and it worked!

Opening up Docker API to the public is a major security risk, so I have used IP address 127.0.0.1 instead of 0.0.0.0, so my PHP script can still access it.

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
M_R_K
  • 5,929
  • 1
  • 39
  • 40
1

I recently had the same issue. The existing solutions have not convinced me, so I have written a new Docker API Client in PHP. I also published a docker container to make the API available via HTTP (jarkt/docker-remote-api). Visit the project page with documentation here: https://github.com/jarkt/docker-php-client

JT2809
  • 324
  • 1
  • 5
  • 16
0

Instead of changing the docker daemon config and having to restart it, you can use Sherpa to open up a path to the remote API via remote-proxy. Something like:

docker run -d \
--name sherpa \
-e CONFIG='[
    { 
        "Path" : "/",
        "Access": "allow",
        "Addresses": ["10.0.0.0/8"]
    }
]' \
-v /var/run/docker.sock:/tmp/docker.sock \
-p 4550:4550 \
djenriquez/sherpa --allow

would give you access on port 4550 and only accepts requests from source clients in the 10.0.0.0/8 space. You can customize all kinds of ACLs for the remote API also.

Checkout the introductory post here:

https://www.linkedin.com/pulse/easily-enable-docker-remote-api-sherpa-dj-enriquez

or directly to the repo here:

https://hub.docker.com/r/djenriquez/sherpa/

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94