-
-
Notifications
You must be signed in to change notification settings - Fork 1
HOWTO dev docker_intro
- Docker on Rails
- "Docker for Rails Developers", by Rob Isenberg, ed. by The Pragmatic Programmer
- Basic Docker Networking
At a high level, Docker provides five capabilities:
- Packaging. The ability to package software into a reusable, shareable format known as images.
- Distribution. The ability to easily share packaged software (images) with other people and deploy it to different machines.
- Runtime. The ability to run, pause, restart, or stop packaged software in a reliable, repeatable way.
- Infrastructure creation. Creating virtual machines ready to run our Docker containers.
- Orchestration and scaling. Managing the release of software to a single Docker node or across an entire cluster.
Docker Images are factories for Containers.
Conceptually, a Container is an isolated or "sandboxed" execution environment - an empty vessel for executing software.
Dockerfiles (blueprint for images)
+----------------------+ +------------------------+ +-----------------------+
| | | | | |
| FROM mariadb:latest | | FROM ruby:2.6.3-alpine | | FROM redis:latest |
| # ... | | # ... | | # ... |
| | | | | |
| | | | | |
| | | | | |
+----------------------+ +------------------------+ +-----------------------+
+ + +
| | |
$> docker build my_db $> docker build my_app $> docker build my_queue
| | |
v v v
+---------------+ +----------------+ +----------------+
| | | | | |
| my_db image | | my_app image | | my_queue image |
| | | | | |
+---------------+ +----------------+ +----------------+
Images
+ (Container factories) + +
| | |
| | |
| | |
v v v
+-----------+ +-----------+ +------------+ +-------------+ +-------------+
| | | | | | | | | |
| my_db_1 | | my_db_2 | | my_app_dev | | my_app_test | | my_queue_1 |
| | | | | | | | | |
+-----------+ +-----------+ +------------+ +-------------+ +-------------+
Containers +-------------+
| |
(Lightweight sandboxes) | my_app_prod |
| |
+-------------+
$> docker run --name my_db_1 my_db
Containers can be started, paused, resumed, and stopped, leading many to draw comparisons with virtual machines (VMs).
Containers rely on virtualization features and share an isolation layer with the kernel, but are different from VMs specifically because of their size and speed.
Container images are made of "layers", cached during image building or downloading (pull), with each layer storing a single command found in its definition file (the Dockerfile
).
You can visualize the container resulting from the built image as a tied together set of multiple isolated boxes (the layers), each one encapsulating and storing each single step required for the container creation and taken from the Dockerfile
used to define its image. Each individual step in the Dockerfile will produce an additional, immutable & cache-able step in the resulting container image.
Due to this isolated and "stateless" nature, Containers that are supposed to interact with data (such as database services) usually rely (mount) external volumes dedicated to storage and backups.
That is true also for communicating ports. Containers are totally isolated from the hosting environment: you'll have to map explicitly everything you need on its "outside".
O Port 36060
localhost |
+-------------------------------|-------+
| Port mapping | |
| | |
| +---------------------------|---+ |
| | Docker Daemon | | |
| | ________________/ | |
| | / | |
| | | | |
| | +--O-------------+ | |
| | | Container | | |
| | | | | |
| | | port 3606 | | |
| | +----------------+ | |
| | | |
| +-------------------------------+ |
| |
+---------------------------------------+
$> docker run -p 36060:3606 ...
$> mysql --port=36060 ...
Whenever you run a new container specifying an image either from the command line or by using a Dockerfile that defines one:
- the source image is automatically built if not found locally;
- if the image links to a parent image from a Docker registry, the image will be pulled (downloaded);
- when the image for the container has been created and stored on localhost, the container can be created and then run.
Created containers usually remain stored locally when stopped, unless they have been run with the --rm
flag, which kills them when they exit from execution.
-
docker build
will create a new container image from aDockerfile
; -
docker start
/docker stop
will work only on already existing containers; -
docker run
will create a new container from the specified image if missing and run it (build + start); -
docker exec
will execute a command on a running container. For instance, this will open an interactive TTY with a shell run on "my_container":bash $> docker exec -ti my_container sh
Stopped containers can be restarted with docker start
or removed with docker rm
.
Check out the official Docker CLI reference for more examples.
Given no particular configurations or parameters, when you run a new container by default it will be mounted on a dedicated network, named after the container itself, plus a _default
suffix.
You can create multiple custom networks with Docker and add containers to one or more networks. Containers can communicate within networks but not across networks. A container with attachments to multiple networks can connect with all of the containers on all of those networks. This lets you build a “hub” of sorts to connect to multiple networks and separate concerns.
Creating custom networks is specially needed when:
-
You are on the same single host and have several composed containers that need to communicate with each other. In this case, you could have a custom bridge between them to make this networking "invisible" to the parent host, or you could choose to rely on the host network itself to rely the communications (mapping ports correctly).
-
You have more than one composed container, as above, but across different hosts. This case is more complicated because it needs an "overlay network". Check out the referenced articles above for more info (an additional key-value store service is needed before creating the network). In any case, whenever the deployment configuration involves more than 1 host, rely upon Kubernetes 🔗 or Docker Swarm 🔗 for a more high level approach on the management of the resulting container cloud.
Upon installation, Docker creates three networks automatically: bridge
, none
, and host
.
All Docker installations represent the docker0
network with bridge
; Docker connects to bridge by default. Run ifconfig
on the Linux host to view the bridge
network.
Docker automatically creates a subnet and gateway for the bridge
network, and docker run automatically adds containers to it. If you have containers running on your machine, docker network inspect <NETWORK_NAME>
displays networking information for your containers.
Any containers on the same network may communicate with one another via IP addresses. Docker does not support automatic service discovery on bridge
. You must connect containers with the --link
option in your docker run
command.
The Docker bridge
supports port mappings and docker run --link
allows communications between containers on the docker0
network.
Custom Bridge networks (similar to the default docker0
network) offer the easiest solution to creating your own Docker network by using this same "network driver" as base.
For example, this will create a new, isolated custom bridge network (based on bridge
) and attach it to a new container ("my_new_db_container"), created from the latest
tagged image available for mariadb
:
$> docker network create --driver bridge my_isolated_bridge_network
$> docker network ls
$> docker run --net=my_isolated_bridge_network --name=my_new_db_container mariadb
(docker network ls
will just show the existing networks for Docker)
This offers a container-specific network stack that lacks a network interface. This container only has a local loopback
interface (i.e., no external network interface).
This enables a container to attach to your host’s network (meaning the configuration inside the container matches the configuration outside the container).