Getting started with docker may seem complex, but here is some info that might help you get started.
Docker is “like” virtualisation in that your application runs in it’s own space, and thinks it is the only application running in that space (as if it were on a physical machine).
In reality, Docker is process separation - it is your application running on the same host as docker is running, but docker puts it in a jail.
Image - represents an application, specifically a version of an application. When an image is built with
docker buildit has everything it needs for the application to run. All dependencies (libraries, binaries, utilities, etc) are packaged up into the image.
Generally, you use an image to run one or more containers of that image - but you don’t “upgrade” the application inside the image, instead you build a new image. So its not uncommon to have images of application:v1, and application:v1.1.
Container - represents a running instance of an image - like a “virtual machine”. You can run many containers of the same image, and it would be like running many “instances” of the application on the same computing cluster.
By design, containers are intended to be created and destroyed often. In fact, when you get into using “clustering” (Kubernetes, Docker Swarm, etc) - your containers are often destroyed as they float between physical machines.
Because of this, there are important considerations relating to the data inside your container - if you need that data to persist between invocations of a container.
Registry - this is an “App Store” of Images.
Docker is great for many reasons:
Your applications run in a jail, and the only way in the jail is via a network connection. Well, that is not completely true, if you are logged into the host that is running your docker container, then you can “attach” to the console. For the most part however, applications are accessed via a network connection.
Inside the jail, applications can connect to the outside world (assume firewall rules don’t restrict this), but they cannot connect to the host’s file systems unless the container was given access to those filesystems when it was created.
The beauty of this design is, if the network application you are running is compromised by a hacker - then the hacker is inside the jail as well. The only damage they can do is to the data seen inside the jail, and being a good system admin, you backup daily right?
Your application image and it’s corresponding data is portable. You can pick it up and drop it on another host, start the container and it will be none the wiser. (It will be as if you stopped the application and then started it - it has no idea that it was moved to a separate host.)
Application Developers/Vendors will generally create your application image - its like they do the install for you, and when you start your container (based on that image) - you start from “setup”. There is NO installation time required once an image is created (creating the image is by definition installing the application). So it is super quick to “spin up” another copy of an application.
Where is “data” stored? Data adds personality to an application, and for it to persist you’ll need to make sure that those data files are stored in a specific place. The container builder should provide you with those instructions when you first use the container, or you can make “known” data persistent points by starting your image with
What ports do you need to “join to” to access your container? While a webserver in a container might be listening for requests on TCP port 80, that needs to be mapped to from the host - and it could be port 80 on the host. IE: Host port 80 -> Container port 80. If you have many containers running web applications, then you’ll need many mappings from the host - however, the host will need to use unique ports. EG: Host port 80 -> Container A port 80. Host port 81 -> Container B port 80, etc. This is done with
In some cases, containers use shell variables to help with configuration. Again the container builder should provide you with information on what variables are required or useful. They are passed to the container by
Starting containers, is easy, the syntax is
docker run .... When it starts, it will give you a Container ID. If you don’t have the necessary image yet, docker will “pull” it from a registry automatically.
Stopping containers is easy, the syntax is
docker stop <CONTAINER ID>.
Deleting containers is
docker rm <CONTAINER ID>.
Listing running containers is
docker ps. The output looks like this:
deon@p-1-1:~ $ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
459a9fef84c6 debian:deb "exec/sbbs" 2 days ago 2 days 0.0:13023->23/tcp amazing_elion
e793d6d33f52 leenooks/mbse:1.0 "/sbin/init /usr/bin…" 2 days ago 2 days 80/tcp, 60177/tcp, 60179/tcp, 0.0:24554->24554/tcp, 0.0:11022->22/tcp, 0.0:11023->23/tcp bbs_mbse .909vch9fbnqlk9iz3owv0qzu5
0f078a15af0b registry.leenooks.net/leenooks/mysticbbs:1.12a39-armv7l-extras "/sbin/init start" 2 days ago 2 days 0.0:10022->22/tcp, 0.0:10023->23/tcp, 0.0:24555->24554/tcp bbs_mystic .wn6bqs707bx37m40mltbsohyf
97dc2a415f89 nginx:latest "nginx -g 'daemon of…" 2 days ago 2 days 0.0:80->80/tcp nginx_web.298qvanxdy7b4xxps4oqrjlue.ndkntwg19ahrszzbqji5bjthy