Docker
These are notes from the Docker Mastery course at Udemy.
- docker run looks for image in local cache or in docker hub. By default it looks for latest image version.
- it creates a new container based on where the image left off.
- Gives the container a virtual IP within the docker engine private virtual network
- by default it does not open any port, unless specified in the –publish flag.
- It starts the container with the default command specified in the CMD directive of the Dockerfile
- These defaults can be changed when running the
docker run
command.
containers are just restricted processes running in the host.
What happens inside a container
docker top
shows the running processes within a container.
docker container inspect
shows how a container is configured
docker container stats
shows a stream of container system usage
ubuntu
image has less installed software than what you would have on a VM.
docker container run -it
runs a the container interactively. You can specify which command to run. Some images have bash
as a default CMD
for example.
docker container exec -it
runs an additinal process on a running container (does not affect the root process). Like connecting to a db container to run bash
. Works exactly like run
but only on an existing container.
creating a container and running it
you can create and then start a container. You have to pass the attach
and interactive
args to the start
command so that it does not start the container and then exits.
docker create --it --name <container_name> <image> <command>
docker start --attach --interactive <container_name>
or
docker run -dit --name <container_name> <image>
docker start <container_name>
this will not attach to the container.
alternatively:
docker run -it <image> <command>
will create and then run the docker container running the <command>
.
Docker networking
docker container run -p
exposes a port to the host.
docker container port <container>
shows what ports are exposed in that container
the default VPN (Virtual Private Network) is called bridge
or docker0
. When you create a container, you connect to the VPN (unless you specify otherwise).
You can create as many VPNs you want and you should put containers that are related togther in the same network.
VPN routes through the NAT on host IP (using the docker daemon)
It’s a good practice to create different VPNs for each app.
Whats a NAT?
NAT = Network Address Translation In a given LAN, connected devices have different IPs. These devices connect to the internet using a single external IP address (assed by Internet Service Provider). A NAT does the translation of these device IPs to external IP address.
You can connect containers to networks and disconnect them using the docker network connect/disconnect <network_name> <container>
You can create a new network using docker network create <network_name> --driver
where the default driver is bridge
.
Docker uses container names as hostnames.
Containers should not rely on IPs for inter-communication Custom networks have DNS built in It’s a good practice to create a custom network to make inter-containers communication easier.
-p
is only used when exposing a port to the outside interface of the host.
docker run -dit -p <host_port>:<docker_vpn_port>
Docker images
There is no kernel, kernel modules (like drivers) inside an image. These are provided by the host. It can be as small as static binary (golang application) or as large as an OS (ubuntu).
images start with a blank layer called “scratch”.
each image starts with a layer that has its own sha that differentiates between layers. If two images use the same layer to create additional ones (add changes and commit them), we don’t need to download/upload the same base layer multiple times. This saves us download/upload time and space.
we identify images by this format user?/repo:tag
tag is a pointer to a specific image commit.
:latest
is just a tag and does not mean that it is actually the latest.
For private docker repos, create it first in the hub.docker.com dashboard and then push to it.
Make sure you run docker login
before pushing.
Docker files
A recipe/instructions for creating docker images.
docker build -f <docker_file>
specifies the non-default Dockerfile to build the image.
chaining commands in the RUN
directive avoids creating layers, usually uncessarily created and saves us time and space.
do not put logs in logfiles because docker handles it for us, otherwise it makes it hard to export those files and use them.
EXPOSE
does not automatically expose the ports to the host. Use -p
for that. It only exports it to the docker VPN.
Put the things that change the least at the top of the dockerfile, and the things that change the most at the bottom. This saves time because it does not have to excute those commands over and over and builds layers.
WORKDIR
is just cd-ing to that directory.
Dockerfile inherits commands from the image it is FROM-ing from.
Docker container lifetime and data persistence
- Containers are ephemeral = disposable.
- Containers ephemeral by design (immutable infra)
- Container should not contain the “unique” data and the app binaries.
- The UFS (files) layer goes away only when the container is removed (not stopped).
- Volumes: make special location outside of the container file system. Allows us to attach it to any container.
- Bind mounts: Link filepath to a path inside a container.
Vollumes
VOLUME
directive in Dockerfile tells docker to create a volume and assign it to the specified location in the container.
volumes need manual deletion.
The database/volumes outlives the executable
-v
creates a new volume, or a named volume.
Creating a volume ahead of time (before docker run
) with docker volume create
is useful only if you want to specify a driver (plugin)
Bind mounting
It’s mapping of file/dir from host to container.
won’t delete the host location when the container is deleted.
docker container run -v /my/host/path:/path/container
(notice the forward the slash in the beginning, this tells docker that this is a mount and not a volume).