Dockerizing a Flask Application

John Miner
5 min readDec 10, 2020

Have you ever been building a project and testing it locally then find out you can’t get it to run in production for the life of you? I know I have and I expect most developers experience this at some point as well. The problem might not be too obvious or maybe it is obvious but the platform that you are trying to deploy to such as Heroku doesn’t support what you are trying to do. It can be quite frustrating to know you can get a project working locally but not be able to show it to the world. So what can you do?

The answer isn’t too obvious, at least for me it wasn’t. That particular project called playground went undeveloped for about a year before I was able to deploy it properly and I’m about to tell you how I did it.

You’ll need some things for this project:

  • First, you’ll need an application I’m using a simple flask one, but you could probably follow along with any language or framework that you are familiar with.
  • You’ll need Docker installed on your system
  • You’ll want a Domain name. Don’t have one? You can register one at name.com
  • You’ll need a server that can run docker. Don’t have one? You can rent one on digital ocean, I suggest that you use the one with Caprover installed. Which you can find here. Having Caprover on your server makes deploying with docker a breeze.

Setting things up for your application.

You’ll need to add a Dockerfile at the root of your project.

$ cd ~/your/project/root/directory
$ touch Dockerfile

You’ll need to define how you’re application is set up in the Dockerfile. You can find more information on Dockerfile documentation here.

# Inside the Dockerfile# Our first step is to install a base image.
# I'm using python so I'll be using a python image.
# Please use an image optimised for your language or find a defualt # image like ubuntu or alpine linux
# STEP 1: Install base image.
FROM python:3.7-slim-buster
# STEP 2: Copy the source code in the current directory to the
# container. Store it in a folder named /app.
ADD . /app
# STEP 3: Install any requirements that you might have.
RUN python3 -m pip install -r /app/requirements.txt
# STEP 4: Set working directory to /app so we can execute commands
# in it
WORKDIR /app
# STEP 5: Declare any needed environment variables
ENV FLASK_APP=app.py
ENV FLASK_ENV=development
# STEP 6: Expose the port that your app is running on.
EXPOSE ${PORT}
# STEP 7: Give the command to run your application.
CMD ["python3", "app.py"]

If you have made a docker file you are now ready to try and run your application in a local dockerization. We’ll have to build our docker container. Make sure you use -t to tag it with a readable name or else it’ll end up as a hash. Then use docker run to run your application, use -d to daemonize it if you want, and use -p exposedport:port to connect the port you exposed in step 6 to your machine. Make sure your application is set up to run on 0.0.0.0 or else you won't be able to see it from outside of the docker container.

$ cd ~/your/project/root/directory
$ docker build -t yourapps/tagname .
$ docker run -p portnumber:portnumber yourapps/tagname

After running the above commands your application should be reachable at http://localhost:portnumber.

Optional next step (suggested if using Caprover)

For Caprover to work properly you’ll need a captain-definition file.

$ cd ~/your/project/root/directory
$ touch captain-definition

Inside the file, you can specify some info but we’ll just point it to our Docker file. More info about the captain definition file can be found here. Inside the file you’ll just need:

{
"schemaVersion": 2,
"dockerfilePath": "./Dockerfile"
}

Optional next step (to easily run your dockerized app)

There is another file we can add to manage the application, it can control how it's built and connect the exposed ports. The file is called docker-compose.yml it makes it extremely easy to run your app for someone who’s not familiar with your project and it can be used to add docker volumes (permanent storage for docker apps) though I didn’t need them.

$ cd ~/your/project/root/directory
$ touch docker-compose.yml

Inside the file, you’ll need to define where you are building your app, what command it needs, and you can specify the ports you want to connect. More info can be found here. Here’s what mine looks like:

version: '3.7'
services:
web:
build: .
command: python3 app.py
ports:
- "5000:5000"

Pretty short and simple. Now to run your app all you need to do is just

$ docker-compose up

and your app will start up like magic without having to pass in the ports or anything. Easy-peasy!

Alright, I’ve dockerized my app. Now what?

If you have gotten your app to run in a local docker container you have gotten past the hard part. The next step is to update our domain name’s a-record to point to our server’s IP address. If you used digital ocean you can find your IP address right where I covered mine up ;) Ps. Don’t ever expose your server IP, it’ll make it easier to get hacked.

Okay, I found the IP address now how do I update the a-record?

It depends on where you registered the domain name but if you used name.com you click more info about your domain name, scroll to the section domain details and click on manage DNS records under the DNS heading. When adding the a-record you should see something like this.

The *.dev isn’t required but is strongly suggested if you are using Caprover.

Not using Caprover?

You might find this tutorial helpful.

Configure Caprover and deploy the app!

To configure Caprover you can navigate to your server's IP address:3000 to access it. It’ll present you with a login screen the default password is captain42. You’ll need to give Caprover your root domain which you registered and pointed to the server earlier. Probably go to settings and update your password as well.

Now go to apps and make a new one. Go to deployment and pick a deployment method to try. To test it out I like to just upload a .tar file, but Caprover’s command-line interface is very nice as well. After your application is uploaded go to app configs to add any environment variables you might need and to add any sort of port mappings. Hit save and update. Then go to HTTP settings and set Container HTTP Port to whatever port your app is running on. Hit save and update. You should see a link under Your app is publicly available at: if you go there you should now be able to see your app live!

Bonus steps

Setting up a site like freshping to keep track of if your website is up.
Setting up Capprover with continuous integration by adding the github repo of your app in the deploy section.

--

--

John Miner

I hope you my articles help! Please leave comments because I'm always open to learning new things. Connect https://www.linkedin.com/in/john-miner-61b95618a/