Last week I published my latest Pluralsight course, Developing Python Apps with Docker! This was exciting for me because over the years I have grown to love Python and I work in Docker on a day-to-day basis. So when I saw the opportunity, I jumped on it. In this post I break down what is covered in the course and what you can expect to learn.
Overview
The course starts from the very basics of Docker by walking through how Dockerfiles work and how to create one for a simple Python Flask application. Then it builds out the simple application into a multi-container application, including a web proxy, a Flask web service, and a MySQL database, leveraging Docker Compose. Next, it explores how to make the application production-ready, using logging, external configuration, Docker Volumes, Docker Secrets, and Docker Networks. Finally, it demonstrates how to use both Visual Studio Code as well as JetBrains Pycharm to debug a Python application while it's running inside a Docker container.
Course Breakdown
Let's review the four modules in the course and what you'll learn in each.
Getting Started with Python and Docker
This module walks you through the setup of a Python development environment using Python's venv
module. Next, you'll learn how to build a simple Flask RESTful web service, which
will be extended into a production-quality application throughout the course, that manages products for a fictious company named "Wired Brain Coffee". This initial version is simple,
but it includes defining GET, POST, PUT, and DELETE HTTP methods in your Flask application. Finally you will build a Dockerfile and run your Flask application in a Docker container.
Essentially, this module is a primer for configuring and running a Python application in a Docker container.
Running Multiple Containers with Docker Compose
Running a stand-alone web service in a container is nice, but it is not what we do in production applications. This module helps you take the leap from a "Hello, World" Python Docker application into something more substantial. Docker Compose allows you to run multiple containers that comprise a single application. In other words, it does not simply provide the ability to run multiple containers, but rather the containers defined in the Docker Compose YAML file comprise a single application.
In this module, we create three containers:
- Nginx: Nginx provides a web front-end that proxies web service requests to your RESTful web service
- Product Service: the Product Service is the Flask RESTful web service that manages products
- MySQL: the MySQL container hosts products in a relational database
In order to make all of these containers work together, this module introduces SQL Alchemy as an object-relational mapping tool to persist products to and from MySQL. While it might have been simpler to hand-write SQL, I wanted this course to build an application that is production-like, so I opted to use an industry standard tool for managing data persistence.
Before we close out this module, I provide an introduction to PostMan and we create a collection of web requests that are used throughout the rest of the course to test the application.
Making Your Application Production-ready
The application is looking pretty good at this point, but it's far from ready to be deployed to a production environment. In this module we add a host of features that make the application production-ready. Specifically we explore ths following:
- Logging: we use the Python Logging Module to write log messages to the standard output device. The module includes aspects of the 12-factor methodology and one of the most important factors for managing production applications is logging to the standard output device so that logs can eventually get published to a log management solution, such as rsyslog or Splunk.
- Configuration: we use Python's ConfigParser module to externalize the configuration of our database connection. Hard-coding your configuration in your source code is never a good idea, and ConfigParser provides a standardized way to externalize your application configuration.
- Docker Volumes: in this section we use two different types of docker volumes: host volumes and named volumes. Externalizing your application configuration to a configuration file and then packaging that configuration file in your container defeats the purpose of being able to change the behavior of your application without rebuilding your containers. Instead, we use Docker hosted volumes to mount our logging and database configurations to the container from the local filesystem. Additionally, we create a named volume to host our database data files so that nothing is lost whenever we restart the database container.
- Docker Secrets: Docker Secrets are used to mount sensitive information to a running container. We define a secret to host our database password and then update the application to use it.
- Docker Networks: Finally, we define multiple Docker networks to harden our application. We ensure that our Nginx container can only talk to the Product Service, that the Product Service can talk to both the Nginx container and the database, and that the database can only talk to the Product Service. Essentially, we ensure that if our Nginx container is compromised, it will not be able to directly communicate with the database, and vice versa.
After completing this module, you will understand how to make your own Python Docker applications production-ready!
Debugging Python Applications Running in Containers
With the application built and ready for production, we have one more topic to cover: what happens when things go wrong? Some problems that occur while an application is running in production only occur with specific user behaviors and production datasets. This module explores how to connect a debugger to your container so that you can set breakpoints and step through your code. I provided a section on debugging with Visual Studio Code and a section on JetBrains Pycharm.
Conclusion
If you're a Python developer looking to get started running your applications in Docker, then this is the course for you! Not only will you learn how to Dockerize a Python application, you will learn how to setup multi-container Python applications, using industry standard technologies, and make your applications production-ready. I hope you will join me in learning how to build production-ready Python applications running in Docker in the Developing Python Apps with Docker course!