Getting Started with Python Flask
A live example is available at https://flask.nullstone.dev.
This quickstart launches a Python Flask web application to AWS via Nullstone. It also configures a local development environment using Docker that works identical to production, but with debugging enabled.
This quickstart contains a walkthrough for generating a Flask app. A working example is available to fork at nullstone-io/flask-quickstart.
TIP
This quickstart is based on the Flask official quickstart guide.
Create Flask app
Create minimal app
For this quickstart, we are going to create a minimal application. Create a file named app.py
with the following contents.
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
Initialize dependencies
We need to add core dependencies for our new Flask app.
cat <<EOF > requirements.txt
Flask
EOF
Now, install the dependencies:
pip install -r requirements.txt
Prepare for Local
Configure docker locally
In your project's root directory, create a file named docker-compose.yml
with these contents:
version: '3.8'
services:
app:
image: nullstone/flask:local
ports:
- "9000:9000"
environment:
- NULLSTONE_ENV=local
volumes:
- .:/app
- packages:/usr/local/lib/python3.9/site-packages
volumes:
packages: {}
Let's start our app locally.
docker compose up
Visit http://localhost:9000.
Update dependencies
As you add dependencies to your application, ensure that there is an entry for the dependency in requirements.txt
. Then, restart your docker container with docker compose up
or docker compose restart
.
Prepare for Production
Before deploying a Flask app to production, you need to dockerize your app.
Dockerize
Nullstone provides a base Flask image that is ready for production. The only thing you need to do is create a Dockerfile
that uses this base image.
FROM nullstone/flask
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
Launch to Nullstone
Create app
When launching to Nullstone, we're going to be creating an app in the Nullstone UI and attaching capabilities that automatically configure our app. Follow these steps in the Nullstone UI.
- Create an application.
- Name: In this example, we're naming our app
flask-quickstart
- Framework:
flask
- App Type:
Container
- Name: In this example, we're naming our app
- From the Domains tab for the application, add a subdomain. (This will automatically attach a load balancer capability)
- From the Capabilities tab for the application, add a capability named
SECRET_KEY for Python Cookies
. (This will enable secure encryption of cookies)
Provision
Our application is ready to launch. Click "Launch" through the UI or issue up
through the CLI.
nullstone up --wait --app=flask-quickstart --env=dev
Build
Once your application is provisioned, you may build and deploy your app.
You can name your image whatever you want, just remember this image name for the deploy step. In this example, we are using an image name of flask-app
.
docker build -t flask-app .
Deploy
Now, issue launch
to push your docker image and deploy the service with a new version.
nullstone launch --source=flask-app --app=flask-quickstart --env=dev
Troubleshooting
No module named ...
If you created a file that is not named app.py
or did not create app = Flask(__name__)
, you will receive an error like this when deploying to production.
ModuleNotFoundError: No module named 'app'
This is because the base docker image is configured to use app.py
to load your application in the production environment. To resolve this, change your FLASK_APP
in your Dockerfile
to use the correct file name (<app-file>.py
) and variable (<app-var> = Flask(__name__)
).
ENV FLASK_APP=<app-file>:<app-var>
For local, you also need to change FLASK_APP
in your docker-compose.yml
Auto-versioning
When pushing your image, Nullstone performs auto-versioning if you are in a git-tracked directory. Nullstone selects the short commit SHA (a unique 8-character token) from the git repository to tag the docker image.
To use a manual version, issue launch with --version
(this example uses 1.0.0
).
nullstone launch --source=flask-app --app=flask-quickstart --env=dev --version=1.0.0
Version conflicts
Nullstone enforces version/image tag immutability for security reasons.
If you repeatedly push a new docker image without committing anything to git, you will receive an error message like this:
error pushing artifact: error pushing image: tag invalid: The image tag 'c3c7cd83' already exists in the 'periwinkle-louse-fkslv' repository and cannot be overwritten because the repository is immutable.
The easiest way to resolve this is to launch with an indexed version. The following uses the same commit sha, but with a -2
suffix to distinguish the image tag.
nullstone launch --source=flask-app --app=flask-quickstart --env=dev --version=c3c7cd83-2