A platform for developing and running applications that separates the code you’re running from your main system using a “container”, which is a loosely-isolated system.
The docker client docker talks to the docker daemon which does the heavy lifting of building, running and distributing your docker containers. These can run on the same system, or you can have dockerd on a remote. Another docker client is Docker Compose which is used to work with apps consisting of a set of containers.

Docker daemon: listens for Docker API requests and manages docker objects, such as images, containers, networks and volumes (explained below).

Docker client: docker - you use this to interact with docker and it sends commands to dockerd which carries them out.

There’s also a GUI with docker desktop.

Docker hub: a public registry for docker images (explained below) which is used by default by docker. You can have your own private registry. docker pull or run are used to pull the required images from the registry, while push pushes them to the configured registry.

Objects in Docker

Images: read only template with instructions for creating a docker container, a blueprint of sorts. Often an image is based on another image, with additional customisations. Ex. an image based on the Ubuntu image that includes the Apache web server and your application, as well as the config details to make your app run. To build your own images, you create a Dockerfile with simple syntax that defines the steps needed to create the image and run it. Each instruction creates a layer in the image, but when you change the file and rebuild the image, only the changed layers are rebuilt, which is why it feels fast and lightweight.

Containers: a runnable instance of an image. If an image is a class, a container is an object of that class. You can create, start, stop and delete a container using the CLI or API. You can connect these to networks or attach storage (volumes) to it, or create new images based on its current state. You can even control how isolated a container is. A container is defined by the image, as well as the options you provide it when you create or start it. When a container is removed, any changes to its state that aren’t stored in a persistent storage are gone. See volumes.

ex. docker run -i -t ubuntu /bin/bash
when this is run,
- if you don’t have the ubuntu image locally, docker pulls it off the registry as though you had run docker pull ubuntu
- docker creates a new container, as though you had run docker container create manually
- docker allocates a read-write filesystem to the container as its final layer, which allows for you to create or modify files and directories in the container’s local filesystem.
- docker creates a network interface to connect the container to a default network, since a network option wasn’t specified. This includes assigning an IP address and connecting to host machine’s networks by default.
- docker starts the container and execs /bin/bash. The -i flag means that it’s running interactively, and the -t means that it’s attached to your terminal. So you can provide input using your keyboard, while docker logs the output to your terminal.
- when you run exit to exit from bash, the container stops but isn’t removed. You can start it again or remove it.

Docker internally uses namespaces to provide the containers, or isolated workspaces. When you run a container, docker creates a set of namespaces for the container. This is part of the reason I wasn’t able to run docker on android, because of namespace restrictions. These namespaces provide a layer of isolation. Each aspect of the container is run in a separate namespace and is limited to that namespace.


Useful commands:
- docker image ls to check which images are present, and docker image rm to prevent them from being storage space hogs.