Install Code Interactively

In this section, we will explore the first half of a typical development workflow: installing an application interactively within a running docker container.

Note

Prerequisites: You should have access to a terminal with Docker installed.

Set Up

Before we begin, make a new directory somewhere on your local computer, and create an empty Dockerfile inside of it. It is important to carefully consider what files and folders are in the same PATH as a Dockerfile (known as the ‘build context’). The docker build process will index and send all files and folders in the same directory as the Dockerfile to the Docker daemon, so take care not to docker build at a root level. For example:

$ cd ~/
$ mkdir python-container/
$ cd python-container/
$ touch Dockerfile
$ pwd
/Users/username/python-container/
$ ls
Dockerfile

Next, grab a copy of the source code we want to containerize:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env python3
from random import random as r
from math import pow as p
from sys import argv

# Make sure number of attempts is given on command line
assert len(argv) == 2
attempts = int(argv[1])
inside=0
tries=0
ratio=0.

# Try the specified number of random points
while (tries < attempts):
    tries += 1
    if (p(r(),2) + p(r(),2) < 1):
        inside += 1

# Compute and print a final ratio
ratio=4.*(inside/(tries))
print("Final pi estimate from", attempts, "attempts =", ratio)

You can cut and paste the code block above into a new file called, e.g., pi.py, or download it from the following link:

https://raw.githubusercontent.com/TACC/containers_at_tacc/master/docs/scripts/pi.py

Now, you should have two files and nothing else in this folder:

$ pwd
/Users/username/python-container/
$ ls
Dockerfile     pi.py

Important Considerations

The most reproducible way to build a container is via a Dockerfile. We looked at pre-formed Dockerfiles in the first section of this workshop. But, now we want to build a Dockerfile from scratch. The questions you must ask yourself when starting a new Dockerfile include:

  1. What is an appropriate base image?
  2. What dependencies are required for my program?
  3. What is the install process for my program?
  4. What environment variables may be important?

Start an Interactive Session

Let’s work through these questions by performing an interactive installation of our python script. In our hypothetical scenario, let’s say our development platform / lab computer is a Linux workstation with Ubuntu 18.04. We know our code works on that workstation, so that is how we will containerize it. Use docker run to interactively attach to a fresh Ubuntu 18.04 container:

$ docker run -it -v $PWD:/code ubuntu:18.04 /bin/bash

Here is an explanation of the options:

docker run      # run a container
-it             # interactively attach terminal to inside of container
-v $PWD:/code   # mount the current directory to /code
unbuntu:18.04   # image and tag from Docker Hub
/bin/bash       # shell to start inside container

If this is your first time calling an Ubuntu 18.04 container on your laptop, then Docker will first download the image. The command prompt will change, signaling you are now ‘inside’ the container.

Update and Upgrade

The first thing we will typically do is use the Ubuntu package manager apt to update the list of available packages and install newer versions of the packages we have. We can do this with:

root@56c60cac8833:/# apt-get update
...
root@56c60cac8833:/# apt-get upgrade
...

Note

On the second command, you may need to choose ‘Y’ to install the upgrades.

Install Required Packages

For our python script to work, we need to install python3:

root@56c60cac8833:/# apt-get install python3
...
root@56c60cac8833:/# python3 --version
Python 3.6.9

An important question to ask is: Does this version match the version you are developing with on your local workstation? If not, make sure to install the correct version of python.

Install and Test Your Code

Since we are using a simple python script, there is not a difficult install process. However, we can make it executable, make sure it is in the user’s PATH, and make sure it works as expected:

root@56c60cac8833:/# cd /code
root@56c60cac8833:/# chmod +rx pi.py
root@56c60cac8833:/# export PATH=/code:$PATH

Now test with the following:

root@56c60cac8833:/# cd /home
root@56c60cac8833:/# which pi.py
/code/pi.py
root@56c60cac8833:/# pi.py 1000000
Final pi estimate from 1000000 attempts = 3.142804

Wrapping Up

We have a functional installation of pi.py! Now might be a good time to type history to see a record of the build process. When you are ready to start working on a Dockerfile, type exit to exit the container.

Hands On Exercise

What (if any) Docker images do you currently have on your machine? What (if any) Docker processes are currently running? If you have an Ubuntu base image, try removing it.