But What Is Docker?

Xavi Soler



More than 10 years old

technology (in Linux)


Previously: BSD Jails, Solaris Zones

Provides isolation

to applications


Multiple processes

with conflicting dependencies can run in the same host


application deployment


Shipping apps

through the network

in seconds

How does it work?





Developer friendly


Not like other

container technologies

Programmed in Go


Open sourced by dotCloud (now Docker Inc.)


2 years ago

What makes Docker special?

It solves problems beyond process isolation and enables interesting workflows

Container creator

doesn't care about what's outside

the container or how to ship it


Container operator

doesn't have to care about what's inside


Any app can run anywhere.

Solves the "matrix from hell"

Solves the

dev/test/prod parity


Developers can run

production-like environments

in their laptops


builder and shipper


for continuous delivery

Runs anything

that belongs to userland


For example, Debian or Busybox based containers in any Linux host

Application dependencies

inside app container

instead of host system


Requires less configuration management tools


infrastructure immutability


All changes are done

replacing containers

OK but

what is Docker?

  1. Container Runtime
  2. Build System
  3. Storage and Transport Mechanisms
  4. Container Image Manager
  5. Layered Image Format
  6. API for containers

1. Container Runtime

$ docker run
$ docker exec
$ docker stop
$ docker restart
$ docker pause
$ docker logs
$ docker kill
$ docker ps

Run immutable environments

for processes


Changes in disk are ephemeral


Even by

simultanious executions

Container with attached terminal

$ docker run -t


With interactive terminal

$ docker run -it


Detach the process and run in background

$ docker run -d


Inject processes in a running container

(no need for SSH)

$ docker exec -it angry_stallman /bin/bash

Docker can be used as an
Init System for anything


$ docker run -d restart=always myscript


This will ensure your container

is running in detached mode

after system boot

Networking, in one slide!


Port mapping

$ docker run -d -P xavisb/myapp

$ docker run -d -p 8080:80 xavisb/myapp


Docker Linking

$ docker run -d --name=db xavisb/pgsql

$ docker run -d --link db:db xavisb/backend

Inject Environment Variables


$ docker run -e PASSWD=12345 xavisb/myapp


Want Persistence?

Mount Volumes!


$ docker run -d -v /path:/path xavisb/myapp

2. Build System

$ ls
Dockerfile myapp.go README.md

$ docker build -t myapp .

Dockerfile ⇢ Image


The same Dockerfile

will always generate

the same image

in repeated builds


enabling reproducibility

of container image creation

Image Inheritance

On-Build Triggers

FROM xavisb/my-base-image
RUN apt-get -y install runtimedependencies
COPY mywebserver /mywebserver
CMD ./mywebserver
FROM python:3-onbuild
CMD ["python", "./myapp.py"]

Notice that having:


  • a Container Runtime

  • a Build System

  • the ability easily distribute Dockerfiles

  • Docker Compose


Means that Docker can be used as an Environment Generator for Development!

3. Storage & Transport

$ docker pull
$ docker push

The Docker Registry

(could be private or public)


Stores images than can be pushed or pulled

and then run as containers


Hint: docker run = docker pull + docker run

(pull is implicit if image not found locally)



  • Registry: collection of repositories

  • Repository: collection of images

  • Image: physical binary file

  • Container: running isolated process




4. Image Manager

$ docker images
$ docker search
$ docker tag
$ docker rmi
$ docker export

List images in your system

$ docker images


Search for images in a Docker Registry

$ docker search debian


Remove images

$ docker rmi xavisb/myapp:latest

Tag images for versioning
$ docker tag xavisb/app:latest xavisb/app:2.0


Publish a specific version
$ docker push xavisb/myapp:2.0


Raw storage resides in

Notice that having


  • a Build System

  • a Storage and Transport Mechanisms

  • the ability to version images


means that

Docker is...

a fucking

Package Manager



Remember there is no magic

it's simply a filesystem


Export a container's filesystem

$ docker export -o container.tar <containerid>


See what's inside

$ tar tvf container.tar | less

5. Layered Images

$ docker commit
$ docker diff
$ docker history

Docker Containers

are made of layered filesystems

thanks to UnionFS

(AUFS, DeviceMapper, overlayfs, btrfs, ZFS)


A stack of read-only filesystems

with a read-write layer on top of it.

All of this is transparently provided

as a read-write filesystem


Every instruction in a Dockerfile

creates a new layer on top of the previous one


A change in one instruction makes

Docker build start from that point


Same for push and pull


This makes build, publish and deploy

processes really fast

History can show you

how and when an image was created

$ docker history ubuntu


Diff can compare changes

since previous layer

$ docker diff <container_id>


Don't do this at home

$ docker commit <container_id>

6. API for containers

$ docker inspect <container_name>
    "AppArmorProfile": "",
    "Args": [],
    "Config": {
        "AttachStderr": true,
        "AttachStdin": true,
        "AttachStdout": true,
        "Cmd": [
        "CpuShares": 0,
        "Cpuset": "",
        "Domainname": "",
        "Entrypoint": null,
        "Env": [
        "ExposedPorts": null,
        "Hostname": "a27fa5f20edd",
        "Image": "ubuntu",
        "Labels": {},
        "MacAddress": "",
        "Memory": 0,
        "MemorySwap": 0,
        "NetworkDisabled": false,
        "OnBuild": null,
        "OpenStdin": true,
        "PortSpecs": null,
        "StdinOnce": true,
        "Tty": true,
        "User": "",
        "Volumes": null,
        "WorkingDir": ""
    "Created": "2015-05-18T12:36:49.800975939Z",
    "Driver": "devicemapper",
    "ExecDriver": "native-0.2",
    "ExecIDs": null,
    "HostConfig": {
        "Binds": null,
        "CapAdd": null,
        "CapDrop": null,
        "CgroupParent": "",
        "ContainerIDFile": "",
        "CpuShares": 0,
        "CpusetCpus": "",
        "Devices": [],
        "Dns": null,
        "DnsSearch": null,
        "ExtraHosts": null,
        "IpcMode": "",
        "Links": null,
        "LogConfig": {
            "Config": null,
            "Type": "json-file"
        "LxcConf": [],
        "Memory": 0,
        "MemorySwap": 0,
        "NetworkMode": "bridge",
        "PidMode": "",
        "PortBindings": {},
        "Privileged": false,
        "PublishAllPorts": false,
        "ReadonlyRootfs": false,
        "RestartPolicy": {
            "MaximumRetryCount": 0,
            "Name": "no"
        "SecurityOpt": null,
        "Ulimits": null,
        "VolumesFrom": null
    "HostnamePath": "/var/lib/docker/containers/a27fa5f20edddaa96aeb1a0c82b048aa71489435996a67bea9c0b9754600f7b5/hostname",
    "HostsPath": "/var/lib/docker/containers/a27fa5f20edddaa96aeb1a0c82b048aa71489435996a67bea9c0b9754600f7b5/hosts",
    "Id": "a27fa5f20edddaa96aeb1a0c82b048aa71489435996a67bea9c0b9754600f7b5",
    "Image": "d0955f21bf24f5bfffd32d2d0bb669d0564701c271bc3dfc64cfc5adfdec2d07",
    "LogPath": "/var/lib/docker/containers/a27fa5f20edddaa96aeb1a0c82b048aa71489435996a67bea9c0b9754600f7b5/a27fa5f20edddaa96aeb1a0c82b048aa71489435996a67bea9c0b9754600f7b5-json.log",
    "MountLabel": "",
    "Name": "/angry_rosalind",
    "NetworkSettings": {
        "Bridge": "docker0",
        "Gateway": "",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "IPAddress": "",
        "IPPrefixLen": 16,
        "IPv6Gateway": "",
        "LinkLocalIPv6Address": "fe80::42:acff:fe11:2",
        "LinkLocalIPv6PrefixLen": 64,
        "MacAddress": "02:42:ac:11:00:02",
        "PortMapping": null,
        "Ports": {}
    "Path": "bash",
    "ProcessLabel": "",
    "ResolvConfPath": "/var/lib/docker/containers/a27fa5f20edddaa96aeb1a0c82b048aa71489435996a67bea9c0b9754600f7b5/resolv.conf",
    "RestartCount": 0,
    "State": {
        "Dead": false,
        "Error": "",
        "ExitCode": 0,
        "FinishedAt": "0001-01-01T00:00:00Z",
        "OOMKilled": false,
        "Paused": false,
        "Pid": 14763,
        "Restarting": false,
        "Running": true,
        "StartedAt": "2015-05-18T12:36:50.445521305Z"
    "Volumes": {},
    "VolumesRW": {}

Everything in Docker is made

through an HTTP API



The Docker client (CLI)

is a consumer of that API

$ docker version
Client version: 1.6.2
Client API version: 1.18
Go version (client): go1.4.2
Git commit (client): 7c8fca2
OS/Arch (client): linux/amd64
Server version: 1.6.2
Server API version: 1.18
Go version (server): go1.4.2
Git commit (server): 7c8fca2
OS/Arch (server): linux/amd64

Client and Server

don't need to run

in the same host


If you use boot2docker

server runs in Linux VM

and client runs in OSX Host


But What is Docker?​

By Xavi Soler

But What is Docker?​

  • 1,192

More from Xavi Soler