installing Necessary Packages
We have to create a virtual environment first. So run the following command:
$ python -m venv venv
Then activate the virtual environment using:
For windows
.\venv\Scripts\activate
For Linux
source venv/bin/activate
Update pip
and setuptools
pip install --upgrade pip setuptools
or
python -m pip install --upgrade pip setuptools
Install necessary packages
pip install flask gunicorn
Project Structure
Even though we are writing a small application I prefer the Flask application factories. That is why the Project structure looks like below:
post_1
├── Project
│ ├── __init__.py
│ └── main.py
└── app.py
The Project
directory basically acts like a python package. In the __init__.py
, we wrote application factories. The main.py
file contains a blueprint.
__init__.py
file:
from flask import Flask
def create_app():
app = Flask(__name__)
from .main import main_bp
app.register_blueprint(main_bp)
return app
as we mentioned earlier the main.py
file contains the blueprint and main our index page will return simply a hello world:
from flask import Blueprint
main_bp = Blueprint("main_bp", __name__)
@main_bp.get('/')
def index():
return {
"msg": "Hello World"
}
Actually, we can run this project using the following commands:
For Windows:
$ set FLASK_ENV=development
$ set FLASK_APP=Project
$ flask run
For Ubuntu:
$ export FLASK_ENV=development
$ export FLASK_APP=Project
$ flask run
However, in order to run this app easily, I wrote app.py
which will import the create_app
function from Project Package
. Then we can use the app.run()
method so that we can run the app just using the python app.py
app.py
from Project import create_app
app = create_app()
if __name__ == "__main__":
app.run()
Dockerizing Flask Application
Now we have to create a requirements
file using:
pip freeze > requirements.txt
My requirements.txt
file looks like this:
click==8.0.1
colorama==0.4.4
Flask==2.0.1
gunicorn==20.1.0
itsdangerous==2.0.1
Jinja2==3.0.1
MarkupSafe==2.0.1
Werkzeug==2.0.1
Now we have to create a Dockerfile
as I have given below:
FROM python:3.8-alpine
LABEL maintainer="Arun K Soman <arunksoman5678@gmail.com>"
WORKDIR /flask_docker_post1
RUN apk --update --no-cache add python3-dev libffi-dev gcc musl-dev make libevent-dev build-base
COPY requirements.txt requirements.txt
RUN python -m pip install --upgrade pip setuptools
RUN pip install -r requirements.txt
EXPOSE 8080
COPY . .
- Build an image starting with the Python 3.8 alpine image. Alpine is a lightweight Linux distribution.
- The
LABEL
is used to write the name of the maintainer and his email address. It is optional - Set the working directory to /flask_docker_post1.
- Update alpine Linux, Install gcc and other dependencies
- Copy requirements.txt.
- Install the Python dependencies
- Add metadata to the image to describe that the container is listening on port 8080
- Copy the current directory. in the project to the
workdir
. in the image.
If you have previous experience with docker you might notice that I didn't write CMD
in this Dockerfile
. It is because, I have to extend this project in future to integrate more services like MySQL, Redis, Celery, NGINX etc. So I am creating docker-compose.yml
which is given below:
version: '2.2'
services:
web:
container_name: flask_post1
build:
context: "."
command: gunicorn --bind 0.0.0.0:8080 app:app
ports:
- "8080:8080"
This docker-compose.yml
file is quite self-explanatory.
In order to check everything works perfectly run the following command:
docker-compose up --build
After building the container successfully I hope you can see the following lines on terminal:
Starting flask_post1 ... done
Attaching to flask_post1
flask_post1 | [2021-07-17 14:39:03 +0000] [1] [INFO] Starting gunicorn 20.1.0
flask_post1 | [2021-07-17 14:39:03 +0000] [1] [INFO] Listening at: http://0.0.0.0:8080 (1)
flask_post1 | [2021-07-17 14:39:03 +0000] [1] [INFO] Using worker: sync
flask_post1 | [2021-07-17 14:39:03 +0000] [9] [INFO] Booting worker with pid: 9
Now use postman
or browser to hit http://localhost:8080
you can see ✌:
You can find out codes on GitHub