Dockerized Python Development
First, get docker. If you are on a Mac and do not have an XCode, you will need to install that first from the App Store. The download and install may be lengthy, it took about 15 min for me
After docker installation, you should have a docker-compose utility installed, check that by running docker-compose
which should not error out and look somewhat like this:
After docker installation, you should have a docker-compose utility installed, check that by running docker-compose
which should not error out and look somewhat like this:
$ docker-compose Define and run multi-container applications with Docker. Usage: docker-compose [-f <arg>...] [options] [--] [COMMAND] [ARGS...] docker-compose -h|--help ...
This is what my directory structure looks like:
├──Dockerfile defines how to build docker image ├──requirements.txt requirements file ├──docker-compose.yml defines how to run the docker image └──src/ application code └── flask_app.py the flask server
flask_app.py
from flask import Flask, jsonify, request, abort app=Flask(__name__) data=[{'fname':'Steve', 'lname':'Jobbs'},{'fname':'Bill', 'lname':'Gates'}] @app.route('/createperson', methods=['POST']) def create_person(): print(request.json) if not request.json or not 'person' in request.json: abort(400) data.append(request.json['person']) return jsonify({'data' : data}), 201 @app.route('/data', methods=['GET']) def get_data(): return jsonify({'data' : data}) @app.route('/data/', methods=['GET']) def get_data_byid(id): return jsonify({'data' : data[id]}) if __name__ == "__main__": app.run(host='0.0.0.0', port=5000)
requirements.txt
flask == 1.1.2 markupsafe >=1.0,<2.0
Following file defines how the docker image should be built
Dockerfile
# which base image we will use for the container #https://hub.docker.com/search?type=image&category=base FROM python:3.8 # your container will have some folders/files already installed #this line creates a new folder at the root of the container #that will be used as a work directory #after the working directory is created, assume you are inside it WORKDIR /code # copy the dependencies file to the working directory COPY requirements.txt . # install dependencies RUN pip install -r requirements.txt # copy the content of the local src directory to the working directory COPY src/ . # command to run on container start CMD [ "python", "./flask_app.py" ]
Following file tells Docker how to run your application
docker-compose.yml
# build from Dockerfile version: "3.8" services: web: #build from Dockerfile in the current directory build: . ports: # host:container = 127.0.0.1:5000 in your browser will map to 500 in container - "127.0.0.1:5000:5000"
Now we can build our image:
$ docker-compose build Building web Step 1/6 : FROM python:3.8 ---> 9756fa8d7b9d Step 2/6 : WORKDIR /code ---> Running in 7917f6eb3663 Removing intermediate container 7917f6eb3663 ---> 41fe8bff45d7 Step 3/6 : COPY requirements.txt . ---> d9b9e9eac29f Step 4/6 : RUN pip install -r requirements.txt ---> Running in 9cddfd6b1864 Collecting flask==1.1.2 Downloading Flask-1.1.2-py2.py3-none-any.whl (94 kB) Collecting markupsafe<2.0,>=1.0 Downloading MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl (32 kB) Collecting itsdangerous>=0.24 Downloading itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB) Collecting Jinja2>=2.10.1 Downloading Jinja2-2.11.2-py2.py3-none-any.whl (125 kB) Collecting click>=5.1 Downloading click-7.1.2-py2.py3-none-any.whl (82 kB) Collecting Werkzeug>=0.15 Downloading Werkzeug-1.0.1-py2.py3-none-any.whl (298 kB) Installing collected packages: itsdangerous, markupsafe, Jinja2, click, Werkzeug, flask Successfully installed Jinja2-2.11.2 Werkzeug-1.0.1 click-7.1.2 flask-1.1.2 itsdangerous-1.1.0 markupsafe-1.1.1 Removing intermediate container 9cddfd6b1864 ---> bf8e35ceea43 Step 5/6 : COPY src/ . ---> a58f689d48c6 Step 6/6 : CMD [ "python", "./flask_app.py" ] ---> Running in d216702be611 Removing intermediate container d216702be611 ---> 729c92da104c Successfully built 729c92da104c Successfully tagged docker_app_web:latest
If you have the docker dashboard open you will see the new image appear - docker_app_web
Now you can run your image using following command:
docker-compose up
docker-compose up
$ docker-compose up Creating network "docker_app_default" with the default driver Creating docker_app_web_1 ... done Attaching to docker_app_web_1 web_1 | * Serving Flask app "flask_app" (lazy loading) web_1 | * Environment: production web_1 | WARNING: This is a development server. Do not use it in a production deployment. web_1 | Use a production WSGI server instead. web_1 | * Debug mode: off web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) web_1 | 172.19.0.1 - - [07/Nov/2020 08:18:30] "GET /data HTTP/1.1" 200 -
And you should be able to access the app from your browser