Skip to content

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.

python
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.

shell
cat <<EOF > requirements.txt
Flask
EOF

Now, install the dependencies:

shell
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:

yaml
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.

shell
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.

docker
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.

  1. Create an application.
    • Name: In this example, we're naming our app flask-quickstart
    • Framework: flask
    • App Type: Container
  2. From the Domains tab for the application, add a subdomain. (This will automatically attach a load balancer capability)
  3. 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.

shell
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.

shell
docker build -t flask-app .

Deploy

Now, issue launch to push your docker image and deploy the service with a new version.

shell
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.

shell
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__)).

docker
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).

shell
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:

shell
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.

shell
nullstone launch --source=flask-app --app=flask-quickstart --env=dev --version=c3c7cd83-2