Managing your own Docker Host with XOA

Watch out! This tutorial is over 5 years old. Please keep this in mind as some code snippets provided may no longer work or need modification to work on current systems.
Tutorial Difficulty Level    

If you read our recent tutorial series on using Docker Containers via a web frontend you may also be curious about Docker on the command line.

For those seeking that extra bit of experience, we have created a Docker Host (with Dockly) template inside our Virtualisation Environment here at DkIT. This allows you to run your own Docker host (or cluster via Swarm mode)  and take full control of everything. You can manage your own images and containers at the command line, but still access the DkIT Registry for Push/Pull of images. Let’s take a closer look with an example project.

Login to https://xoa.comp.dkit.ie and fire up a new VM with the Docker Host (with Dockly) template provided.

You will be able to SSH to your new host (even from Windows, natively or with PuTTY) with the usual credentials for all VMs.

ssh administrator@10.108.152.110

The authenticity of host '10.108.152.110 (10.108.152.110)' can't be established.
ECDSA key fingerprint is SHA256:UiU7hry7UcbzaOUGeEMIokSPE8NeyvefaN1vhfE1PCs.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.108.152.110' (ECDSA) to the list of known hosts.
administrator@10.108.152.110's password: 
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-50-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Fri May 17 11:57:00 UTC 2019

  System load:  0.0                Processes:              120
  Usage of /:   45.4% of 11.75GB   Users logged in:        1
  Memory usage: 3%                 IP address for eth0:    10.108.152.110
  Swap usage:   0%                 IP address for docker0: 172.17.0.1

 * Meltdown, Spectre and Ubuntu: What are the attack vectors,
   how the fixes work, and everything else you need to know
   - https://ubu.one/u2Know

2 packages can be updated.
0 updates are security updates.


Last login: Fri May 17 11:50:50 2019
administrator@ubuntu:~$

Once you have done this, let’s create a directory to keep all out Dockerfiles in, and a sub-directory of that for our app (which will be a simple script to let a user send a pre-formatted tweet). This is good practice and something you should always do.

mkdir dockerfiles/
cd dockerfiles
mkdir tweetapp/
cd tweetapp

So far so good. Now to actually start doing Docker stuff. In order to build our image, we need any resources it will utilise plus the Dockerfile to build it. We’re going to create an index.html file and a PNG image (of a Linux penguin) that will be copied into our eventual container.

First, acquire the image from a remote location using the wget command.

wget http://files.comp.dkit.ie/oslab/linux.png

--2019-05-17 12:06:38--  http://files.comp.dkit.ie/oslab/linux.png
Resolving files.comp.dkit.ie (files.comp.dkit.ie)... 10.108.150.36
Connecting to files.comp.dkit.ie (files.comp.dkit.ie)|10.108.150.36|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 22365 (22K) [image/png]
Saving to: ‘linux.png’

linux.png  100%[====================>]  21.84K  --.-KB/s    in 0s      

2019-05-17 12:06:38 (84.6 MB/s) - ‘linux.png’ saved [22365/22365]

administrator@ubuntu:~/dockerfiles/tweetapp$

Now create the index.html file with nano. In there goes all the code our web app will use (mostly html and css).

<html>
    <head>
        <style>
        body {
        	background-image: linear-gradient(-74deg, transparent 90%, rgba(255, 255, 255, 0.23) 20%),
                              linear-gradient(-74deg, transparent 83%, rgba(255, 255, 255, 0.18) 15%),
                              linear-gradient(-74deg, transparent 76%, rgba(255, 255, 255, 0.1) 15%),
                              linear-gradient(to top, #f25a02, #f26818, #f97e36);
    		background-size: cover;
    		margin-bottom: 0px!important;
        }
        div{
            font-family: 'Geomanist', sans-serif;
  			font-weight: normal;
  			color: white;
            width: 50%;
            margin: 0 auto;
            position: relative;
            top: 50%;
            transform: translateY(-50%);
        }
        </style>
    </head>

    <body>
        
               <img src=https://www.docker.com/sites/all/themes/docker/assets/images/brand-full.svg width=20%></img>
        
               <div class="inner">
                    <center><h1>Linux Tweet App!</h1></center>
        
                    <center><img src="./linux.png"></img><P>
        
                    You've successfully deployed the Linux tweet app! Why not let the world know?
        
                      <p>
        
                     <a href="https://twitter.com/intent/tweet?button_hashtag=#Docker" class="twitter-hashtag-button" data-size="large" data-text="I'm learning how to deploy #Docker containers at #DkIT." data-url="http://www.docker.com" data-lang="en" data-show-count="false">Tweet</a><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
              </div>
    </body>

</html>

It’s time to create out Dockerfile! Name the new file just that, “Dockerfile” and put the following in there:

FROM nginx:latest
MAINTAINER Joe Bloggs (D0001234@student.dkit.ie)

COPY index.html /usr/share/nginx/html
COPY linux.png /usr/share/nginx/html

EXPOSE 80 	

CMD ["nginx", "-g", "daemon off;"]

As you can see, we are using the official nginx image as our base, copying our files to the correct locations in the system, opening port 80 and finally running the nginx command using the switches explained in  a previous tutorial. You’ll notice we don’t use ENTRYPOINT as before. However, The CMD specifies arguments that will be fed to the ENTRYPOINT, so it’s the same result. We’re just mixing things up a bit.

Now we can Build our image. We want to tag it locally as “tweetapp”, so the command is:

docker build –tag=tweetapp .

Here’s the output:

Sending build context to Docker daemon  27.65kB
Step 1/5 : FROM nginx:latest
latest: Pulling from library/nginx
743f2d6c1f65: Pull complete 
6bfc4ec4420a: Pull complete 
688a776db95f: Pull complete 
Digest: sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68
Status: Downloaded newer image for nginx:latest
 ---> 53f3fd8007f7
Step 2/5 : COPY index.html /usr/share/nginx/html
 ---> f7036b2d7c6c
Step 3/5 : COPY linux.png /usr/share/nginx/html
 ---> ca2485fb09ac
Step 4/5 : EXPOSE 80
 ---> Running in d47c7f38084a
Removing intermediate container d47c7f38084a
 ---> 5f2c569aff31
Step 5/5 : CMD ["nginx", "-g", "daemon off;"]
 ---> Running in 003730fd51e9
Removing intermediate container 003730fd51e9
 ---> 68a549f30862
Successfully built 68a549f30862
Successfully tagged tweetapp:latest

Looks good. A quick docker image ls will show our image now exists in Docker, along with the nginx image it depends on.

administrator@ubuntu:~/dockerfiles/tweetapp$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
tweetapp            latest              68a549f30862        2 minutes ago       109MB
nginx               latest              53f3fd8007f7        9 days ago          109MB

Great! Now let’s fire up a container and see if our code actually works. The command to use here is:

docker container run –detach -p 80:80 tweetapp

This will start and map port 80 on the container to port 80 on our VM. Run dockly to see your container details:

Dockly has some nice features, like quick stopping and restarting of your container, as well as easy removal and comprehensive info about a container at the touch of a button (i):

You can now visit your VM’s IP Address in a browser to check the output of your web app.

Wow, that look’s promising! Just test your Tweet button to be sure:

Perfect.

Our image has now been proven to work, and could actually be useful. We should tag it for addition to the DkIT Registry so we can use it again later (ie. Pull) from future instances of the Docker Host (with Dockly).

As we’re adding to the share registry, we should tag it appropriately with using our student ID.

docker build –tag=docker01.comp.dkit.ie:5000/d001234_tweetapp .

and Push it to the registry

docker push docker01.comp.dkit.ie:5000/d001234_tweetapp

(read lots more about the power of tagging here and how to tag AFTER the image is created here).

We can check that was uploaded properly by visiting the registry in our browser (only works inside the college).

Much success!

Did we mention this now means your image is available to Pull from other Docker hosts in DkIT?

docker pull docker01.comp.dkit.ie:5000/d001234_tweetapp

Did we mention this includes http://docker01.comp.dkit.ie? Because it does! Check it out:

And when deployed:

Boom!

So have fun, the more you try, the more you will learn about Docker.

Here is a quick cheat sheet of the commonly used commands to get started:

PURPOSE COMMAND
Build an image docker build –rm=true .
Install an image docker pull ${IMAGE}
List of installed images docker images
List of installed images (detailed listing) docker images –no-trunc
Remove an image docker rmi ${IMAGE_ID}
Remove all untagged images docker rmi $(docker images | grep “^” | awk “{print $3}”)
Remove all images docker rm $(docker ps -aq)
Run a container docker run
List containers docker ps
Stop a container docker stop ${CID}
Find IP address of the container docker inspect –format ‘{{ .NetworkSettings.IPAddress }}’ ${CID}
Attach to a container docker attach ${CID}
Remove a container docker rm ${CID}
Remove all containers docker rm $(docker ps -aq)

There’s also an excellent article covering the basic commands here.