In this post we run a python program in a Docker container sourced from the user guide. Look at the various commands that come into play when administering containers, and then briefly setup some real world applications with Docker.
This will be the second post on Docker following on from Docker – Installing and Running (1). If you’re brand new to Docker then the first post linked helps to introduce some of its concepts and theory to better understand the utilities it can provide.
1 – Example Container Application
Pull this training image from the Docker user guide:
-d option tells Docker to daemonise and run the container in the background.
-P maps any required network ports inside the container to your host, and the Python application inside is also executed at the end.
Run the Docker process command to see running container details:
The “webapp” image container shows network ports that have been mapped as part of the image configuration:
In my example here port
5000 (the default Python Flask port) inside the container has been exposed on the host ephemeral TCP port
32768 . Ephemeral port ranges are temporary short lived port numbers which typically range anywhere from 32768 to 61000. These are dynamically used and are never set in stone.
The Docker image decides all this for us, but as an aside it’s also possible to manually sets the ports to use by a container.
This command assigns port
80 on the local host to port
5000 inside the container:
It’s important never to map ports in a 1:1 fashion i.e.
5000->5000/tcp as if we needed multiple containers running the same image, the traffic will use the same host port (
5000) and only be accessible one instance at a time.
If you like you can check the original Python docker container’s port is working by accessing:
Where the port number
32768 is set to your own example container’s ephemeral port.
Another way to see this example containers image’s port configuration is:
To see the front-facing host machine’s mapped ports individually add the number of the internal port to the end of the command:
Now we have this example container up and running we’ll go through multiple administrative commands that are important for when working with containers. These commands if you wish can be tested with the example container, or even better with multiple instances of it. Each and ever command shown may not be completely applicable, however.
2 – Administrative Commands
Here’s a list of select Docker commands to refer to when playing around with or monitoring containers. There are even more to check out as this list is by no means exhaustive.
A few core commands were already mentioned in Docker – Installing and Running (1) so it won’t appear here.
The first command allows you to attach to a running container interactively using the container’s ID or name:
You can detach again from the container and leave it running with
Q for a quiet exit.
To list the changed files and directories in a container᾿s filesystem use diff:
Where in the output the three “event types” are tagged as either:
For real-time container and image activity begin a feed of event output with:
The exec command runs a command of your choosing inside a container without dropping you down into a shell inside the container.
This example creates a container named
ubuntu_bash and starts a Bash session that runs the
Backing up a containers internal file-system as a tar archive is carried out using the “export“ command:
Show the internal history of an image with human readable
To display system wide Docker info and statistics use:
Return low-level information on a container or image using inspect:
You can filter with the
inspect command by adding the parameters described on the previously linked page.
SIGKILL to kill a running container, caution as usual is advised with this:
Pause and unpause all running processes in a Docker container:
If the auto-generated names are not to your taste rename containers like this:
Alternatively when first creating/running a container
--name sets the name from the onset:
Enter a real-time live feed of one or more containers resource usage stats:
Docker has its own top command for containers, to see the running processes inside:
That’s all for these. Some real-world examples of running images from the official Docker Hub repositories are now covered briefly to serve as realistic examples for how you might want to use Docker and its containerisation.
Be mindful that these are not walk-throughs on fully setting up each service, but general starting points for each.
3 – Ghost Image Container
To pull the image itself:
To run a basic Ghost instance named
ghost-blog-name on the mapped port
Then access the blog via http://localhost:8080 or http://your.hosts.ip.address:8080 in a browser.
The image can also be pointed to existing Ghost content on your local host:
Check out Docker Hub – Ghost
4 – irssi Image Container
“irssi is a terminal based IRC client for UNIX systems.”
I’m not sure about the benefits of running your irssi client through Docker but to serve as another example we’ll go through the Docker Hub provided setup process:
Create an interactive shell session in a new container named whatever you choose whilst setting an environment variable named
TERM that is retrieved from the host. The user ID is set with
-u and group ID is set with the
Then stop the log driver to avoid storing “useless interactive terminal data”:
Mount and bind the hosts
/.irssi config home directory to the internal container equivalent:
Mount and bind the hosts
/localtime directory to the internal container equivalent:
Pull down and apply all the previous commands to the
irssi image from Docker Hub:
As everyone who uses irssi has their own configuration for the program this image does not come with any provided pre-sets. So you have to set this up yourself. Other than this you are dropped into the irssi session within the new container.
Check out Docker Hub – irssi
5 – MongoDB Image Container
“MongoDB document databases provide high availability and easy scalability.”
The standard command to pull the image and container is one we’re familiar with by now:
This image is configured to expose port 27017 (Mongo’s default port), so linking other containers to it will make it automatically available.
In brief, this is how to link a new container to a Mongo container named
mongo-container-name. The image at the end is the application/service the new container will run:
grep shows the link:
With the output in my case being:
Check out Docker Hub – MongoDB
6 – NGINX Image Container
“Nginx (pronounced “engine-x”) is an open source reverse proxy server for HTTP, HTTPS, SMTP, POP3, and IMAP protocols, as well as a load balancer, HTTP cache, and a web server (origin server).”
As usual like with all these images to download/pull:
A basic example is given of some static HTML content served from a directory (
~/static-content-dir) that has been mounted onto the NGINX hosting directory within the new container:
Whichever port is auto-assigned to the NGINX container can be used to access the static HTML content.
Find out the port number using either
docker ps or:
For our purpose here we want the second line’s port which in my case is
327773 – as shown:
http://localhost:32773 or http://your.hosts.ip.address:32773 in a browser on the localhost now returns:
The same idea but with a
Dockerfile is better, one that is located in the directory containing our static HTML content:
Then build a new image with the
Dockerfile and give it a suitable name;
nginx-custom-image is what I’m using for this example:
If this is successful output in this form is given:
All that’s left is to run the custom built image, this time with a more typical, user provided port number:
Again accessing http://localhost:8080 or http://your.hosts.ip.address:8080 in a browser on the localhost shows the static HTML web pages:
Check out Docker Hub – NGINX
7 – Apache httpd (2.4) Image Container
To serve static HTML content in a directory named
static-content-dir on port
32775 of the local host machine we can use:
Visiting http://localhost:32755 or http://your.hosts.ip.address:32755 in a browser on the localhost then returns:
With a Dockerfile for configuration, custom setups can be applied. Create the
Dockerfile in the project directory where the static content is hosted from:
Add lines like the below, where line 2 copies a httpd config file from the current working directory, to the internal container’s version. And line 3 copies the entirety of the current working directory (the static HTML files) to the Apache container’s web hosting directory:
Note: If the
my-httpd:2.4configuration file is missing, the next command to build the image will fail.
Build the new custom Apache image defined in the
Dockerfile and give it the name
custom-apache-image which you can of course change if you like:
Successful output for the image build sequence looks like this (or similar):
Lastly, start and run a new container using the custom generated image on port
32756 of the localhost machine:
Visiting http://localhost:32756 or http://your.hosts.ip.address:32756 in a browser on the localhost now returns:
Check out Docker Hub – httpd
8 – Jenkins Image Container
Create a new directory in your user’s home directory for the Jenkins config files. This will be mounted and mapped to the container’s equivalent configuration space:
Run the Jenkins image mapping the two internal ports to ephermal ports on the host side, whilst syncing the config directory we just created to the new container:
Jenkins can be seen at the first port number we mapped. In my example it was
32790 meaning a URL of http://localhost:32790 or http://your.hosts.ip.address:32790 in a browser takes us to the Jenkins application page:
Check out Docker Hub – Jenkins
Remember that there are unofficial image repositories to be found on Docker Hub too, and potentially elsewhere when made available.
The third post on Docker talks a bit more about administration with Docker. As well as details based around how to network containers together.