---
# System prepended metadata

title: Docker

---

# Docker
## Installation
### Get Docker
To quickly install the newest Edge (beta) release, we can use the command shell uploaded to docker GitHub repo:
> curl -sSL https://get.docker.com |  sh

Otherwise, go to https://store.docker.com for more detail instructions
We may want to add our user account to docker group to avoid typing sudo for every docker command:
> sudo usermod -aG docker ${USER}

**Warning:** Docker requires root access to interact with OS kernel (namespace, kernel, etc.), by adding an user to docker group, this user can create container that later have root permission, and this may cause security issue. This should be carefully consider to do to container in production.

### Get Docker Machine and Docker Compose
Go to https://docs.docker.com to get detail instruction.
### Basic commands
Checkout the engine's version and verify cli can talk to it.
> docker version

See various configurations of the engine
> docker info

## Basic concepts
### Containers
Containers are basically just processes:
- They are limited to what resources they can access
- Exit when the process stops
They are usually immutable and ephemeral (unchanging and temporary). We only re-deploy containers, never change a container ("immutable infrastructure")
#### docker run command
Thing happened when we use docker run command:
1. Looks for the image in the cache, if there is no image, then fetch the image from the registry (default registry is Docker Hub). If the image version is not specified, the latest version will be pulled.
2. Creates a new container based on that image and prepares to start.
3. Gives container a virtual IP on a private network inside the engine.
4. Starts the container using the command in the image Dockerfile.

#### Let a container control daemon
We can gives the control of the daemon to the container by bind mounting `/var/run/docker.sock`. This should only be used with trusted containers.


### Networks
Each container created is attached to the *bridge* virtual network by default. Containers in the same network and freely talk to each other using their default port. Each virtual network using NAT to manage its' containers virtual IP.
"-p p1:p2" option in run command ask the host machine to listen to port p1 and forward the traffic to the port p2 of the container.
Default networks:
- bridge: the default virtual network for containers
- host: skip the virtual network and attach container directly to the host
- none: 
For a container to find others in a network, a DNS is used so containers can find each other using their name.
**Note:** Default *bridge* network does not have DNS, we have to use *--link* options when create container to link containers.
### Images
Official definition:
> An image is an ordered collection of root filesystem changes and the corresponding execution parameters for use within a container runtime

Simply put:
- App binaries and dependencies
- Metadata about image data and how to run the image
An Image is not a full OS, it does not have kernel, kernel modules (drivers, etc.)
Images are *tagged*:
- *latest* is a default tag (not really latest) to get the latest version of an image
- One SHA id of image can have many tags
#### Image layers:
Image are designed using [[union file system]] concept of making layers about file system changes. Each set of changes create a layer. Each layer has an unique SHA.
Layers are cached locally, pulling a new image won't download the same layers that cached. We will never store the same layers more than once.
Everytime we run a container, Docker create a read-write layer on top of existed readonly image's layers.
**Copy on write**: If a change to a file in the image is made in the container, that file will be copy over to the container layer.
#### Image tags
Conventional format for tags:
> username/imagename:tag

This format is used in docker hub, tag is usually the version number. We can have many tags for the same image.

**Uploading image to Docker Hub**:
We have to use `docker login` to login to Docker Hub account first. The account key will be saved in json on the host, if the host can't be trusted, use `docker logout` after pushing it to the registry.
To create a *private* Docker Hub image, we have to create the private repo first, and then push the image with a suitable image tag.
#### Building Images
##### Dockerfile
Each Dockerfile start with FROM clause to set the base image. The new image will inherit the base image information (EXPOSE, CMD, etc.)
`docker image build` command takes in a Dockerfile and executes it line by line.
It is recommend to put the least changes part on top and the part that have much more changes at the bottom.
Use WORKDIR instead of RUN cd.

### Persistent Data
#### Volumes
Used to separate data from temporary file system of container. Won't be deleted with when remove container, and can be mapped to many containers at once.
Though we can create volume when starting a container, it is prefer to create volumes ahead with `docker volume create` , this allow us to specify a driver for the volume so we can use additional plugin.
To create volume with `docker run` use `-v {name}:{-path_in_container}`
#### Bind mounting
Map a host file or directory to a container file or directory. It basically two locations pointing to the same file.
**Can't** be used in the Dockerfile, to used bind mount we have to use `-v {full_host_path}:{full_container_path}`. Docker know it's a bind mount instead of a volume name by look at the "/" at the start of left side string.
#### File Permissions Across Multiple Containers
**File ownership between containers and the host are just numbers**. 
### Private registry
#### Run a local registry using official image
Pull *registry* image from Docker Hub and run it as a container.
##### Storage
- Use local docker volume by default, can specify bind mount to use instead
- Other storage back end such as Amazon S3 bucket, Google Cloud Platform can be used by using storage drivers
##### External access
Must first secure the registry container using [[TLS]]:
- Can mannually set up a certificate
- Concatenate intermediate certificate with own certificate to create a *bundle*
- Use [[Let's Encrypt]]
- May use self-signed certificate (insecure).
##### Authentication
