Python Console App with Docker

Today I want to write about dockerizing a python app, for instance, a python script.

Let’s imagine we want to run this script in different machines and we can’t control what python version they have, or even worse, we don’t know if python is installed or not, and what dependencies they have installed.

Docker helps us separate the code from the infrastructure so this blog post will be about this.

Create the Python script

#src/script.pyprint('hello world!')

Create the Dockerfile

#DockerfileFROM python:3.6RUN mkdir /application
WORKDIR "/application"
# Upgrade pip
RUN pip install --upgrade pip
# Update
RUN apt-get update \
&& apt-get clean; rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
ADD requirements.txt /application/
ADD src/ /application/
RUN pip install -r /application/requirements.txtCMD [ "python", "" ]

FROM tells Docker which image you base your image on. In the example, Python 3.

RUN tells Docker which additional commands to execute in bash console. In the example, we create a folder called application and we later install the requirements with the pip library we installed earlier.

CMD tells Docker to execute the command when the image loads. In the example, our python script.

How to run

docker build -t python-script .

And then run it

docker run python-blog-scraper

You should now get a ‘hello world’ printed 🙂


So let’s test this out with some requirements.


Now let’s use these requirements in our script. For instance, let’s make a GET request to my blog and let’s scrape the contents of it, maybe the title of the blog posts and the first sentence. Print these in our console.

Note: Scraping is better done with Selenium in my opinion, but just as an example, let’s just use beatifulsoup’s library.
import requests
from bs4 import BeautifulSoup
class BlogPost:
title = None
first_sentence = None
def __init__(self, title, first_sentence):
self.title = title
self.first_sentence = first_sentence
def __str__(self):
return str(self.title) + '\n' + str(self.first_sentence)
def scrape(url):
r = requests.get(url)
if r.status_code == 200:
soup = BeautifulSoup(r.content, features="html.parser")
# print(soup.prettify())
for article in soup.find_all('article', attrs={'class': 'post'}):
title = article.find('h2', attrs={'class': 'entry-title'}).string
first_sentence = article.find('div', attrs={'class': 'entry-content'}).find('p').string
blog_post = BlogPost(
print('Whoops! Something went wrong!')

For readability, I created a model that has the information we want to keep to print later. We’re printing as we run the loop here, not saving anything to an array or database (this is just as an example so we can use libraries we just installed). Also, I renamed this, so don’t forget to update your Dockerfile!

ADD requirements.txt /application/
ADD src/ /application/
RUN pip install -r /application/requirements.txtCMD [ "python", "" ]

Now let’s rebuild the image and run it.

docker build -t python-script .
docker run python-blog-scraper

And there we have it, you should have the blog posts being printed in your console!

Conclusion and Resources

I’ve uploaded the source code in GitHub here.
Link to Python library Beautifulsoup docs.
Link to Python library Requests docs.

Happy coding! 🙂

Originally published at Joey’s blog.

Coder, Entrepreneur, Co-founder at SlowCode

Coder, Entrepreneur, Co-founder at SlowCode