Hot-reloading on a dockerized flask app

Michael Xian
Aug 17 · 4 min read

At Hootsuite, my team was working with a dockerized flask app. Because we hadn’t set up hot-reloading, when we were making updates to the flask app and testing locally, we had to manually tear down the containers and bring them back up between each change. This took some time, and was mildly disruptive to our workflow, so I worked on setting up hot-reloading.


Table of Contents

Prerequisites

Setting up the flask app

First, let’s create a directory to house the code.

mkdir hot-reloading
cd hot-reloading

Create a file.

touch requirements.txt

And add flask to the file

Now let’s make the actual app.

Check that the app is working.

export FLASK_APP=app.py
flask run

We export to tell flask where to find our application. has to be run in the same terminal as is run.

Example output:

* Serving Flask app "app"
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Visit the site, and you should see something like this:

Image for post
Image for post

Creating the dockerized flask app

If you skipped the previous step, you can use this starter code

Create the dockerfile for our flask app

We’ll have a separate dockerfile for Nginx, so let’s call this .

We start with the base Python 3 image.

FROM python:3

Create and designate as the work directory.

RUN mkdir /app
WORKDIR /app

Expose the port for our app.

EXPOSE 5000

Because of how docker caches, it’s best to first copy the files that we don’t expect to change often. For this project, that’s the file.

COPY requirements.txt .

Install the requirements.

RUN pip install -r requirements.txt

Copy the rest of the files.

COPY . .

Run with a config file.

CMD [ "uwsgi", "--ini", "app.ini" ]

Create the app.ini config for uwsgi

Add uwsgi to the file

Create the dockerfile for Nginx

Start with the image.

FROM nginx:latest

Expose port 80 for .

EXPOSE 80

Replace the default config with a custom config

RUN rm /etc/nginx/conf.d/default.confCOPY app.conf /etc/nginx/conf.d

Create the app.conf for Nginx

Create the docker-compose yaml

defines the name of the image, which can be anything we want

tells docker where to look for files to build the image

defines the dockerfile to use, which is just the dockerfiles we created in the previous steps.

volumes:
- "./:/app"

This mounts the root directory of our project on the host machine () onto a directory named app under the root directory in the container ().

ports:
- 5000:80

This maps port 5000 on our machine to port 80 on the container. This is important because listens on port 80 by default, but our app is running on port 5000.

You should now be able to reach the app on after running

Adding hot-reloading

If you skipped the previous steps, you can use this starter code

has a configuration which allows us to designate a file to cause an update whenever the command is applied on it. However, we can only supply one file, so we use to detect updates in our python files, and run to trigger the reload. I’ll be using a dedicated file named . To do this, add to the file.

To check for updates to our python files, we can run .

specifies the pattern for which files to watch for changes. Specifically, we’re looking for any file that ends in () at any level () in our project.

tells watchman to run whenever it detects an update. This will then trigger to reload, since it’s watching the file.

tells watchman to wait until there is 1 second without any updates before running . This essentially means that it will wait for you to stop typing for 1 second before triggering the reload, so it’s not constantly triggering reloads as you’re typing.

Now, if we run the command after , the project will reload whenever you make an update to a file. We can use to run this automatically instead.

We run with the flag so it runs in a detached state. This allows the terminal to hit the command without shutting down the containers.

With this makefile, we can start the project with with , and stop it with (after terminating the command).

Now if you run , you should be able to see your changes in real time. Try changing the to something else!

Finalized hot-reloading dockerized flask app

Creation of dockerized flask app based on this article

Hootsuite Engineering

Hootsuite's Engineering Blog

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store