Demo

Contributors: Alicia Wang, Conner Swenberg

Suppose we have an application with a similar structure to our previous assignments:

src/
 |-app.py
 |-db.py
 |-requirements.txt

How do we containerize this application?

Setup image configuration

A Dockerfile tells Docker what exactly we need to build into our image to run our application and exist in our src directory where the rest of the application code lives.

Dockerfile
FROM python:3.7

RUN mkdir usr/app
WORKDIR usr/app

COPY . .

RUN pip install -r requirements.txt
CMD python app.py

FROM python:3.7

This FROM command will set up our environment from a prebuilt Python distribution that Docker provides. We will be using Python 3.7, but a list of other distribution versions can be found here.

RUN mkdir usr/app

This RUN command executes the shell command mkdir to create the directory usr/app in the root directory

WORKDIR usr/app

The WORKDIR command sets the working directory for any subsequent RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile. We will be using three of them.

COPY . .

This COPY command will copy all of our files in our current local directory . (which is src in our demo) to the root directory in the Docker image.

RUN pip install -r requirements.txt

This RUN command will execute the shell command pip install -r requirements.txt, which will install our required Python packages.

CMD python app.py

This CMD command will run our Python server when instantiating our container.

Ignore unnecessary files

There are some automatically generated files that we don’t need to run our application, so we want to tell Docker to ignore those files when copying our source code over. We can do this with a .dockerignore file:

.dockerignore
__pycache__
venv

Any files or directories listed in .dockerignore will not be included when copying our files with COPY . ..

Build an image

We can build an image using the Dockerfile located in the current directory:

>>> docker build .

To list all previously built images:

>>> docker images

We should see that the image was created with a specific image ID. These IDs are hard to keep track of, so we can give them a tag (or an alias) so that we know which image corresponds to which program. If we wanted to name our newly created image “demo”, we could run:

>>> docker build -t demo .

Run a container

To run the application specified on the image:

>>> docker run -p "5000:5000" -it demo

The -p flag represents the port mappings. Because the application runs on a specified port but that port isn’t exposed outside of the container, we want to specify that the app’s port 5000 will listen to the container’s port 5000. The -it flag lets us run the container interactively, meaning that we can ctrl-c (force stop) the session if we so desire.

docker-compose

These flags can be hard to keep track of, so if we want to run the container a certain way every time, we can instead specify a docker-compose file which will specify any extra settings you need. In addition, you can use docker-compose to run multiple container applications as one.

docker-compose.yml
version: "3"
services:    
    demo:        
        image: demo            
        ports:                
            - "5000:5000"        
    <EXAMPLE OF MULTI-CONTAINER>        
    webapp:            
        image: webapp            
        ports:                 
            - "3000:3000"            
        depends_on:                
            - demo

Now to run a container(s) from an image(s), instead of using docker run, we can instead use:

>>> docker-compose up -d

The -d flag is the detached mode, meaning that the container(s) will run in the background.

To enter a running container and view and interact with it with bash commands:

>>> docker exec -it [CONTAINER_ID] bash

To stop running the current container:

>>> docker-compose down

Stop a running container

To (forcefully) stop a running container, you will need its container ID, which you can find by viewing all running containers:

>>> docker ps

Then to stop the container:

>>> docker kill [CONTAINER_ID]

>>> docker kill [container_id]

Docker Hub

Docker Hub is an online service that allows us to open-source the images we built. We can share them with others who may want to run our application. To use Docker Hub, you must first create an account on Docker Hub's website, and then login to your account locally:

>>> docker login

DockerHub requires image tags to be unique. We can ensure our tags’ uniqueness by having our tags be prepended with our account username:

>>> docker tag demo cswenberg/demo

Finally we can push our built image to DockerHub, where it can be pulled by anyone else:

>>> docker push cswenberg/demo

Last updated