Docker Remote API - bounswe/bounswe2017group3 GitHub Wiki

Introduction

docker logo

Docker is an open-source project that automates the deployment of applications inside software containers. It takes all the hassle from deployment and makes it as easy as a single click.

Docker has a REST API for controlling the resources such as containers and images remotely. It has an endpoint for literally everything so that you can do anything possible using this API.

Errors

Whenever something wrong happens, the Remote API returns a JSON object with the error message, and the HTTP status code indicates the type of the error.

For example: If you send a request to an endpoint that doesn’t exist; HTTP status code of the response will be 404 and the body of the response will be JSON in the following format:

{
    "message": "page not found"
}

Endpoints

This is what we actually care about. Endpoints are where we’ll make the requests and get the information we want in return.

Since this is a common REST API, we’ll make basic HTTP requests such as GET, POST, UPDATE, DELETE (and maybe some others), and the API will response back with a JSON in its body.

Let me list you down some of the endpoints with example requests. You can make the requests in any language you choose, but I’ll give the examples as raw HTTP requests. For reference, whenever I write something like GET /a/b, it means:

  • There is an endpoint /a/b.
  • It accepts a GET request.

Containers Endpoint

docker container

Docker containers wrap up a piece of software in a complete filesystem that contains everything it needs to run: code, runtime, system tools, system libraries – anything you can install on a server. This guarantees that it will always run the same, regardless of the environment it is running in.

List containers

GET /containers/json

Example request:

GET /containers/json?all=1&before=8dfafdbc3a40&size=1 HTTP/1.1

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

[{
  "Id": "8dfafdbc3a40",
  "Names": ["/boring_feynman"],
  "Image": "ubuntu:latest",
  "ImageID": "d74508fb6632491cea586a1fd7d748dfc5274cd6fdfedee309ecdcbc2bf5cb82",
  "Command": "echo 1",
  "Created": 1367854155,
  "State": "Exited",
  "Status": "Exit 0",
  "Ports": [{
    "PrivatePort": 2222,
    "PublicPort": 3333,
    "Type": "tcp"
  }],
  "Labels": {
    "com.example.vendor": "Acme",
    "com.example.license": "GPL",
    "com.example.version": "1.0"
  },
  "SizeRw": 12288,
  "SizeRootFs": 0,
  "HostConfig": {
    "NetworkMode": "default"
  },
  "NetworkSettings": {
    "Networks": {
      "bridge": {
        "IPAMConfig": null,
        "Links": null,
        "Aliases": null,
        "NetworkID": "7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812",
        "EndpointID": "2cdc4edb1ded3631c81f57966563e5c8525b81121bb3706a9a9a3ae102711f3f",
        "Gateway": "172.17.0.1",
        "IPAddress": "172.17.0.2",
        "IPPrefixLen": 16,
        "IPv6Gateway": "",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "MacAddress": "02:42:ac:11:00:02"
      }
    }
  },
  "Mounts": [{
    "Name": "fac362...80535",
    "Source": "/data",
    "Destination": "/data",
    "Driver": "local",
    "Mode": "ro,Z",
    "RW": false,
    "Propagation": ""
  }]
}]

As you can see, there is a ?all=1&before=8dfafdbc3a40&size=1 part in the endpoint. These are called query parameters. This endpoint accepts these query parameters:

  • all – Show all containers. It must be 1/True/true or 0/False/false. Only running containers are shown by default (i.e., this defaults to false)
  • limit – Show limit last created containers, include non-running ones.
  • since – Show only containers created since Id, include non-running ones.
  • before – Show only containers created before Id, include non-running ones.
  • size – Show the containers sizes. It must be 1/True/true or 0/False/false.
  • filters - a JSON encoded value of the filters to process on the containers list.

Status codes:

  • 200 - success
  • 400 - bad parameter
  • 500 - server error

Create a container

POST /containers/create

Example request:

POST /containers/create HTTP/1.1
Content-Type: application/json

{
  "Hostname": "",
  "Domainname": "",
  "User": "",
  "AttachStdin": false,
  "AttachStdout": true,
  "AttachStderr": true,
  "Tty": false,
  "OpenStdin": false,
  "StdinOnce": false,
  "Env": [
    "FOO=bar",
    "BAZ=quux"
  ],
  "Cmd": [
    "date"
  ],
  "Entrypoint": "",
  "Image": "ubuntu",
  "Labels": {
    "com.example.vendor": "Acme",
    "com.example.license": "GPL",
    "com.example.version": "1.0"
  },
  "Volumes": {
    "/volumes/data": {}
  },
  "WorkingDir": "",
  "NetworkDisabled": false,
  "MacAddress": "12:34:56:78:9a:bc",
  "ExposedPorts": {
    "22/tcp": {}
  },
  "StopSignal": "SIGTERM",
  "HostConfig": {
    "Binds": ["/tmp:/tmp"],
    "Tmpfs": {
      "/run": "rw,noexec,nosuid,size=65536k"
    },
    "Links": ["redis3:redis"],
    "Memory": 0,
    "MemorySwap": 0,
    "MemoryReservation": 0,
    "KernelMemory": 0,
    "CpuPercent": 80,
    "CpuShares": 512,
    "CpuPeriod": 100000,
    "CpuQuota": 50000,
    "CpusetCpus": "0,1",
    "CpusetMems": "0,1",
    "IOMaximumBandwidth": 0,
    "IOMaximumIOps": 0,
    "BlkioWeight": 300,
    "BlkioWeightDevice": [{}],
    "BlkioDeviceReadBps": [{}],
    "BlkioDeviceReadIOps": [{}],
    "BlkioDeviceWriteBps": [{}],
    "BlkioDeviceWriteIOps": [{}],
    "MemorySwappiness": 60,
    "OomKillDisable": false,
    "OomScoreAdj": 500,
    "PidMode": "",
    "PidsLimit": -1,
    "PortBindings": {
      "22/tcp": [{
        "HostPort": "11022"
      }]
    },
    "PublishAllPorts": false,
    "Privileged": false,
    "ReadonlyRootfs": false,
    "Dns": ["8.8.8.8"],
    "DnsOptions": [""],
    "DnsSearch": [""],
    "ExtraHosts": null,
    "VolumesFrom": ["parent", "other:ro"],
    "CapAdd": ["NET_ADMIN"],
    "CapDrop": ["MKNOD"],
    "GroupAdd": ["newgroup"],
    "RestartPolicy": {
      "Name": "",
      "MaximumRetryCount": 0
    },
    "NetworkMode": "bridge",
    "Devices": [],
    "Sysctls": {
      "net.ipv4.ip_forward": "1"
    },
    "Ulimits": [{}],
    "LogConfig": {
      "Type": "json-file",
      "Config": {}
    },
    "SecurityOpt": [],
    "StorageOpt": {},
    "CgroupParent": "",
    "VolumeDriver": "",
    "ShmSize": 67108864
  },
  "NetworkingConfig": {
    "EndpointsConfig": {
      "isolated_nw": {
        "IPAMConfig": {
          "IPv4Address": "172.20.30.33",
          "IPv6Address": "2001:db8:abcd::3033",
          "LinkLocalIPs": ["169.254.34.68", "fe80::3468"]
        },
        "Links": ["container_1", "container_2"],
        "Aliases": ["server_x", "server_y"]
      }
    }
  }
}

Example response:

HTTP/1.1 201 Created
Content-Type: application/json

{
	"Id":"e90e34656806",
	"Warnings":[]
}

Different than the previous example, we’ve sent a JSON object in the HTTP request body instead of using query parameters. This is how data is (usually) sent in POST requests.

The keys in the JSON object we send are called JSON parameters. This endpoint accepts these JSON parameters:

  • Hostname - A string value containing the hostname to use for the container.
  • Domainname - A string value containing the domain name to use for the container.
  • User - A string value specifying the user inside the container.
  • AttachStdin - Boolean value, attaches to stdin.
  • AttachStdout - Boolean value, attaches to stdout.
  • AttachStderr - Boolean value, attaches to stderr.
  • Devices - A list of devices to add to the container specified as a JSON object in the form { "PathOnHost": "/dev/deviceName", "PathInContainer": "/dev/deviceName", "CgroupPermissions": "mrw"}
  • … many others.

And this endpoint accepts 1 query parameter:

  • name - Assign the specified name to the container.

Status codes:

  • 201 – success
  • 400 – bad parameter
  • 404 – no such container
  • 406 – impossible to attach (container not running)
  • 409 – conflict
  • 500 – server error

Update a container

POST /containers/(id or name)/update

Example request:

POST /containers/e90e34656806/update HTTP/1.1
Content-Type: application/json

{
  "BlkioWeight": 300,
  "CpuShares": 512,
  "CpuPeriod": 100000,
  "CpuQuota": 50000,
  "CpusetCpus": "0,1",
  "CpusetMems": "0",
  "Memory": 314572800,
  "MemorySwap": 514288000,
  "MemoryReservation": 209715200,
  "KernelMemory": 52428800,
  "RestartPolicy": {
    "MaximumRetryCount": 4,
    "Name": "on-failure"
  },
}

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
	"Warnings": []
}

This endpoint accepts the same JSON parameters as the create endpoint. So I’ll just skip to the status codes.

Status codes:

  • 200 – success
  • 400 – bad parameter
  • 404 – no such container
  • 500 – server error

Remove a container

DELETE /containers/(id or name)

Example request:

DELETE /containers/16253994b7c4?v=1 HTTP/1.1

Example response:

HTTP/1.1 204 No Content

Query parameters:

  • v – Remove the volumes associated with the container. It must be 1/True/true or 0/False/false. Default false.
  • force - Kill then remove the container. It must be 1/True/true or 0/False/false. Default false.

Status codes:

  • 204 – success
  • 400 – bad parameter
  • 404 – no such container
  • 409 – conflict
  • 500 – server error

Those were the endpoints for 4 basic operations, called CRUD (Create, Read, Update, Delete), for containers.

As you might have noticed, success codes differ for these 4 operations.

  • 200 - success code for listing (GET request)
  • 201 - success code for creating (POST request)
  • 204 - success code for removing (DELETE request)

These are the common success code for these kinds of HTTP requests.

References