Setup Flask, NextJs Application with Docker
Recently, I’m working on my side-hustle and launch passporr.com. Passporr.com is a platform that allows international students to search and find anything related to their studies. It can help international students by providing them with free tools and knowledge base of the question and answer from the community. I build the platform using Flask (Python web framework), NextJS (React Framework) and wrap everything in Docker. Before build passporr, I can’t find a good tutorial on how to serve flask and ReactJS application using docker. So I decided to write one now.
In this post, I’ll share how I set up my local development using Docker and
docker-compose. I also share how I use
docker-machine to deploy it directly to DigitalOcean. The focus of this post is more on how I set up the codebase to work with Docker and
docker-compose. In the future post, I’ll make more detail example for both the Flask and NextJS.
The application that I’ll showcase here consists of:
- Flask application (Backend API)
- Endpoint for authentication
- An endpoint to GET, POST, PUT user
- NextJS application (Frontend)
- Anonymous user-accessible routes (Homepage, Component page, Login page)
- Secure routes (Profile page)
If you go to the Github and clone the repo, you’ll see the codebase consists of three main folders,
nginx. In each the folder, you’ll find a
Dockerfile that constructs the container for each of the service. You will also see a file name
Dockerfile-prod is a docker file that we’re going to use for deploying to production. We’ll come back to that file when we talk about deployment.
# Base Image
For the development image, I use
python:3.7.2-slim as the base image and run the application with the built-in web-server from flask. If you look at another file in
api folder, you’ll find
Dockerfile-prod file where I use
gunicorn to serve the flask application.
In addition to the flask application image, inside
api/project folder, you’ll find a folder name
db which contain a sql file for creating database and a dockerfile for postgres.
Dockerfile for NextJS application
The image for NextJS application is pretty straightforward. I use node:10.16.0-alpine for the base image and run
dev script to get the hot-reloading running as well.
To connect the flask API and NextJS app, I use Nginx for that. This part shows how I set up the configuration for Nginx.
From the above Nginx configuration, we can see that the call to
/api is re-routed to flask application which is on port 5000. The rest of the requests is routed to NextJS application. I use port
8080 for the default port that Nginx listen to avoid conflict with other port in my machine.
In addition to the above config, the following is the dockerfile for Nginx that is very straightforward.
Lastly, to run everything at once, I use
docker-compose to orchestrate all of the services.
docker-compose.yml file above, we’ll have four services running (
client). You can open the main application from http://localhost:8080 or separately access the flask application from http://localhost:5002 or NextJS application from http://localhost:3008. You can also access the Postgres database from port
After you have everything set, you can run the whole configuration by running
docker-compose up -d --build
docker-machine you can easily deploy your application directly to cloud providers such as DigitalOcean or AWS. In this post, I’ll show how to deploy it to digital ocean, for more information on deploying to AWS you can see it here. Before doing the following steps, please make sure you have
- DigitalOcean account. Use this link to create one if you don’t have. If you’re a student, you can also take advantage of Github Education Pack to get $50 in platform credit on DigitalOcean
- A personal access token for DigitalOcean
The first thing to do is to create a docker-machine instance on DigitalOcean.
docker-machine create --driver digitalocean --digitalocean-access-token <your_personal_access_token> <name-for-your-docker-machine>
After it successfully created, you can check it with
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
The following commands will connect you to the instance in DigitalOcean, and you can deploy the application using
- Activate the docker-machine. Replace
<docker-machine-name>with the actual docker-machine name from the previous step.
$ docker-machine env <docker-machine-name>
- Activate shell configuration
$ eval $(docker-machine env <docker-machine-name>)
- Run docker-compose
$ docker-compose -f production.yml up -d --build
To check if the application running, you can run
$ docker ps
Make sure you have three containers running there. You can also access the application from
Using docker from development and push it to production has helped me develop the application quickly. I also have more confidence because my application has the same environment setting in both development and production. The steps that I show here for deployment from local machine maybe not ideal for team-setting or more robust application. For that case, you may need to try an option using CI/CD setting.
I hope this help, and please put your feedbacks or questions if any.
Setup Flask, NextJs Application with Docker