Understanding containers (part 04): multiple containers
Thank for all the feedback after the previous parts of this #UnderstandContainers series. I hope you enjoyed as well some exercises with OrientDB database.
Let’s keep digging into containers!
I assume that you have the container
myorientdb01 running, e.g. by running it with
docker start myorientdb01, if it was stopped in the meantime.
Let’s run the 2nd instance of OrientDB server – attempt #1
Not for any practical reasons other than for the sake of today’s exercise, let’s run the second instance
myorientdb02 of OrientDB database server. As you might remember from part 01 we can use the following statement:
docker run --name myorientdb02 -d -p 2480:2480 -p 2424:2424 -e ORIENTDB_ROOT_PASSWORD=root orientdb
which looks good, but … should fail! And return the message “
docker: Error response from daemon: driver failed programming external connectivity on endpoint myorientdb02 (...): Bind for 0.0.0.0:2480 failed: port is already allocated.” should be clear, that the port
2480 on your host computer (your laptop, I assume) is already used to bind the same port for container
What’s more: even though the container was not started, it was created and the name had been assigned. You can check with the command
docker ps --filter='ancestor=orientdb' --all to list all containers that were created using
orientdb as the image. Or, for short:
docker ps -f='ancestor=orientdb' -a
So, before we move on, please delete that failed container with
docker container rm myorientdb02, or for short:
docker rm myorientdb02
Ok, so we are back to the situation with only one OrientDB server container
Let’s run the 2nd instance of OrientDB server – attempt #2
Now at least we know that with every next container on the same host we need to assign different ports from the host. We can do this manually, by using the option
-p 2481:2480 -p 2425:2424, where we manually ordered Docker to try mapping application ports
2424 from inside the container to our host ports
2425. This will work if ports
2425 are not used yet.
The other option we are going to use is
-P. It will automatically pick free ports on the host to map ports exposed (we will get deeper into this later) by the image.
So, let’s run the following command:
docker run --name myorientdb02 -d -P -e ORIENTDB_ROOT_PASSWORD=root orientdb
and — once the new container has been successfully created — check its assigned host ports:
docker container port myorientdb02
On my laptop it was something like this.
So, the port of OrientDB Studio running in the second container was assigned to the host’s port
32768. Let’s check it by running
localhost with the proper IP address, if running Docker Toolbox; and 32768 with the port assigned on your machine).
So, there are two instances of OrientDB running as can be seen by connecting to two different instances of their Studio apps on different ports.
But, what’s the point…
…of running these two instances?
Well, to show one important container’s feature, that makes it different from traditional VMs.
Run this command to display all containers based on
orientdb image plus their sizes by adding the
-s for short) option. Please note that because of a single hyphen
-as is a combination of two options
-s, not a single “
as” option as if it would be with double hyphens
docker ps -f='ancestor=orientdb' -as
Now we got something interesting here to understand. Let’s look at “
…because in containers SIZE matters
Image credit: The Size Matters Coffee Mug
So, what does container size means? It is one of the key differentiators between containers and traditional VMs.
container’s virtual size = image size + container’s delta file system size.
What it means is that a container’s file system is not a separate copy of the image, but is just a read/write layer of files on top of read-only layers of files from the image.
What do I mean? Let’s first check the size of the image itself with
docker image list orientdb, or for short:
docker images orientdb
So the size of all files in the image is 333MB.
And then the size of both
myorientdb02 container layers are currently around 100KB only! Should we start the 3rd, 4th and so on instances on OrientDB server they all will reuse the same read-only image.
So, what’s in a container’s layer?
We can check this using
docker container diff myorientdb02 command, or for short:
docker diff myorientdb02
A are files/catalogs added comparing to the image. And
C are changed.
In that way, multiple containers can share access to the same underlying image and yet have their own data state.
What about modifying/deleting image files in containers?
That was my first question when I learned about the read-only image and read/write the container’s layer. Let’s check.
docker exec myorientdb02 ls -l docker exec myorientdb02 rm readme.txt docker exec myorientdb02 ls -l
myorientdb02 we deleted the shared file
/orientdb/readme.txt, which is the file from the
What happened with that file in
myorientdb01 container then?
It is still there. Why? Let’s check
myorientdb02 container’s layer once again.
docker diff myorientdb02
The file was just marked as deleted
D in that container. So, it is not visible in that container anymore, but is still existing in the other one.
Disk vs Memory footprint
So far we’ve been looking at disk size of images and containers. But what about the memory?
We can check this with
docker container stats, or for short:
Each image has its own memory, and each of them is using around 1.1GiB of RAM currently.
Quick note on where this
MEM LIMIT of 12GB comes from, because it is important to smoothly run your containers:
- In Docker Desktop, it is the limit you assign in advanced preferences:
- In Docker Toolbox, it is a “Base Memory” setting for the VM hosting the Docker Machine:
This post does not exhaust the topic…
…of storages yet, so stay tuned for another post to discuss Docker volumes.
Ok, my train is arriving…
Yet this is not the end of my travels today. Tonight I am going to Walldorf to join SAP Inside Track. My presentation “Learning Docker from Scratch … with SAP Data Management” is on Saturday. Will you be there?
We will keep digging into Docker and containers in the next posts. I will tag these posts UnderstandContainers for easy search.
-Vitaliy (aka @Sygyzmundovych)