This is an introduction on how to use Docker. You can create Docker containers to improve the for example the administration of hosted services on your server.
A Linux server is used in this introduction.
What is Docker?
Docker allows you to create and run containers that can contain every kind of applications or services. All configurations and packages of the service/application are saved in a container. The most positive part about this is, that you can easily move the container between different services and environments. A Docker container is an own environement that can be run on a server (Linux, Windows, etc.) and it replaces a virtual machine.
The architecture of Docker
You Docker instance on your server can be split into a daemon and a client. The daemon comes with a RESTful API and it communicates with the client through the HTTP protocol with the help of RESTful API. The user gets information from Docker or sends instructions (e.g.: to a Docker container) through the client, which then communicates through HTTP protocol and sends commands in the RESTful API (GET, POST commands, etc.) to the Docker daemon. The daemon takes care of the Docker containers and images (more about that later in this Tutorial). The client acts as a middle man between the user and the RESTful API, which is used as mentioned before for the communication with the daemon.
The Docker instance runs usually on a private network. The daemon on it connects to the (official) public Docker hub registry (hosted by the company of this software) to download for example Docker images (that are ready to use). It can also connect to other registries, if it is configured like that.
But every Docker instance has a private Docker registry which stores Docker images, that were for example created or downloaded. This registry is private and only the daemon can communicate with it through HTTP.
The most important parts of Docker are the docker container and volume.
A volume contains the data (storage) and meta data (port mappings and environment variables) and it is used by one or several containers. The container is the process which runs the service or application.
Docker can be installed through the apt package manager. You can install Docker through this command:
apt-get install docker.io
Important Docker commands
Command to build a Docker image
Run a Docker image as a container
Commit a Docker container as an image
Tag a Docker image with a certain tag (sets an identifier for the container)
How to build an application with docker
This part of the tutorial will show how you can build a Docker application. You will learn about important commands and functionalities such as port mapping.
1. Create a dockerfile
A docker application needs firstly a Docker image. There are a few different methods to create a Docker image. But here we will use a Dockerfile to create our Docker image. This is essentially a text file which contains commands that will be run when the Docker application will start to run.
We will install the NodeJS application "todo". Create a new folder for the application and change to the new created folder. In that folder create a new text file with the name "Dockerfile", which contains the following:
FROM - Defines the used base image. We use here the node image to run this NodeJS application and have access to all the NodeJS libraries.
LABEL maintainer - set a label for maintainer information
RUN - Run a command on the shell commandline. Here we clone a git repository, install the application and define the file permissions.
WORKDIR - The directory that should be used. Use here the new created folder for the Docker application that we are creating.
EXPOSE - The ports that should be opened for this applications (We use here port mapping). You can also write only the port number if you want to use both UCP, TCP protocol.
CMD - Call a defined command on startup, when this docker container starts. Here we start the NodeJS application. This command has this following syntax (preferred syntax form):
In "executable" the program that you want to use is called with parameters, that are called afterwards. Another syntax form is: CMD command param1 param2
If you want for example to edit Shell environment variables, then you should use the command sh. Example: CMD ["sh","-c","echo $HOME"]
With the command "sh" you can execute commands directly through the shell and not through Docker.
2. Build the created dockerfile
Now we will build a Docker image from the created dockerfile. If you are in the same folder as the dockerfile, then call this command with ".":
docker build .
If you are in a different folder as the dockerfile, then write the folder path here instead of ".".
When you run the above mentioned command, then you will get the output of all the commands that are in the dockerfile.
The last line is the important line. There you can see the id of the new created Docker image.
Example output (only the last line is shown):
Successfully built 56c32xda05ba
You will get a differend id than the here shown id "56c32xda05ba".
Now define a label for this id, so you can use the label instead to refer to this created Docker image:
docker tag 56c32xda05ba todoapplication
3. Run / Start a Docker container
Use the command "docker run" with its parameters and the name of the created Dockerimage (here: "todoapplication") to start the new created container.
docker run -i -t -p 8000:8000 --name ContainerName todoapplication
-p - This parameter defines how the ports of the container and application should be mapped to the ports on the server and host system. Here we connect the port 8000 (first number) in the container with the port 8000 (second number) on the server.
Syntax: Host_Port:Container_Port. This syntax (host:container) is also used for mapping of filepaths, etc. We can access the application now through the port 8000.
-name - Gives the container a name, that can be used to call this container.
-t - Run the Docker container and foreground and connect it to the shell that we use.
-i - Keeps the Docker container open for any inputs on the shell.
-v - Mount a volume. You can share the file system (path) of a Docker container with the server (host) file system (path).
Other commands can be looked up on the Docker official documentation, which is mentioned at the end of this tutorial.
In production - use this:
Run the Docker container in background
To run the Docker container in background mode (like as a Daemon) use the command "-d":
docker run -d -i -t -p 8000:8000 --name ContainerName todoapplication
Get an overview over Docker containers
Show only running Docker containers
Show all Docker containers
docker ps -a
Show Docker container with certain name or id
docker ps -f "name=containername"
docker ps -f "id=56c32xda05ba"
Show files affected by any type of file operation (add, delete, etc.) in the Docker image
You can use this command (and also other commands too) with the ID or name of the Docker container
docker diff todoapplication
docker diff 56c32xda05ba
You can get an output similar to this:
A /run/nginx.pid C /var/lib/nginx/tmp A /var/lib/nginx/tmp/logs
A - Means that a file or directory was added
D - A file or directory was deleted
C - A file or directory was changed
Show logs of a Docker container
If you want to display logs of a certain Docker container, then use the command "docker logs" with the container name or ID.
Default: All logs will be displayed.
Show logs with timestamps
docker logs -t 56c32xda05ba
Show only the last part of the logs (tail)
docker logs --tail 56c32xda05ba
Attention: Please do be aware of the difference between the command arguments "--tail" and "-t".
Show and leave the display of the logs open (Follow the log output)
docker logs -f 56c32xda05ba
Stop a running Docker container
If your Docker container is running in foreground, then you could stop it by the keyboard command "CTRL-Z". But (in production use) you would normally run the Docker container as a daemon. Therefore you need to stop the Docker container by using the id of the container or container name.
docker kill containername
docker kill containerID
You can also use a certain Linux POSIX signal (SIGINT, SIGHUP, etc.) to stop your container.
docker kill --signal=SIGHUP containername
Show CPU usage of Docker containers
Show CPU usage for all running Docker containers
Show CPU usage for a certain Docker container
docker stats containername
Show Docker version number
Some advanced Docker commands
You can use these commands as a kind of a cheat sheet to administrate your Docker containers and images in a faster way.
Stop all running Docker containers
docker stop $(docker ps -q | paste -sd " " -)
Stop and remove all Docker containers
docker rm -f $(docker ps -aq | paste -sd " " -)
Stop and remove all Docker images
docker rmi -f $(docker images -aq | paste -sd " " -)
Docker is also recommended if you use many containers and you want to scale your usage to more than 100 Docker containers.
This is possible because of Docker layering. The file system that will be used by a Docker container is saved in a Docker image, which can be used by many containers. A lower disk space usage is possible through the copy-on-write mechanism.
The copy-on-write mechanism goes like this. If a running container wants to write to a file, then it needs to record the change by copying the item to a new area of a disk. When a Docker commits and is done performing this operation, then this new area of a disk is frozen and recorded as a layer with its own id (identifier).
Docker can be used for example to create and host your software application, but also to host services (like a web server, mail server, etc.) on your server. It allows you a much better workflow and scalability.
If you want to use Docker only to setup (web) services (like Wordpress, apache web server, etc.) more easily, then please check out the other Docker tutorial about using Docker to setup and run a web service with existing Docker images.
But if you want to know more about the Docker commands, then please go also the documentation site on docker.com.
More about the command "docker run":
More about the command "docker build":
More about the command "docker commit":