How to Serve a Flask App
TUTORIAL
Introduction
Amazon Lightsail is an easy-to-use virtual private server that offers a containers service. Follow along this tutorial to learn how to serve a Flask app on Lightsail containers service.
In this tutorial, you create a Flask application, build a Docker container, create a container service on Lightsail, and then deploy the application.
Overview
In this tutorial, you will set up a Docker container on your local machine, setup a container in the Amazon Lightsail service, and launch "Hello, World!" applications.
Prerequisites
Before starting this tutorial, you will need:
- An AWS account: If you don't already have an account, follow the Setting Up Your Environment getting started guide for a quick overview.
- A properly configured AWS Command Line Interface (CLI): For more information on how to set up the AWS CLI, please refer to the AWS CLI documentation. Be sure to use the latest version of the AWS CLI which is v2. Finally, be sure a region is set by default or you will need to specify the region when issuing Lightsail deploy commands.
- Docker installed on your local machine.
- Installed and configured Amazon Lightsail Control (lightsailctl) plugin: For more information on how to install Lightsail Control, refer to the Lightsail Control documentation.
AWS experience
Intermediate
Time to complete
30 minutes
Cost to complete
Free Tier eligible. See the Lightsail Pricing page for more details.
Requires
Active AWS Account
AWS CLI
Amazon Lightsail Control
Docker
Services used
Amazon Lightsail
Last updated
October 17, 2023
Implementation
Step 1: Create a Flask application
Complete the following steps on your local machine that is running Docker. These steps walk you through the process of creating the Flask application files.
Step 1a: In the command line of your local machine, create a new project directory and switch to that directory.
mkdir lightsail-containers-flask
cd lightsail-containers-flask
Step 1b: Create a new file named app.py with the following code:
This minimal Flask application contains a single function hello_world that is triggered when the route “/” is requested. When it runs, this application binds to all IPs on the system (“0.0.0.0”) and listens on port 5000, which is the default Flask port.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return "Hello, World!"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000)
Step 1c: Create a new file, requirements.txt. Edit the file and add the following code. Then, save the file.
The requirements.txt files are used to specify what Python packages are required by the application. For this minimal Flask application there is only one required package, Flask.
flask===3.0.0
Step 1d: Create a new file named Dockerfile. Edit the file and add the following code to it. Save the file.
The Python alpine image ensures the resulting container is as compact and small as possible. The command to run when the container starts is the same as if run from the command line: python app.py
# Set base image (host OS)
FROM python:3.12-alpine
# By default, listen on port 5000
EXPOSE 5000/tcp
# Set the working directory in the container
WORKDIR /app
# Copy the dependencies file to the working directory
COPY requirements.txt .
# Install any dependencies
RUN pip install -r requirements.txt
# Copy the content of the local src directory to the working directory
COPY app.py .
# Specify the command to run on container start
CMD [ "python", "./app.py" ]
Step 1e: At this point, your directory should contain the following files:
$ tree
.
├── app.py
├── Dockerfile
└── requirements.txt
0 directories, 3 files
Step 2: Build your container image
Step 2a: Build the container using Docker. Use the following command from the same directory as the Dockerfile:
This command builds a container using the Dockerfile in the current directory and tags the container “flask-container”.
docker build -t flask-container .
Step 2b: Once the container build is done, test the Flask application locally by running the container.
docker run -p 5000:5000 flask-container
Step 2c: The Flask app will run in the container and will be exposed to your local system on port 5000. Browse to http://localhost:5000 or use curl from the command line and you will see “Hello, World!”.
$ curl localhost:5000
Hello, World!
Step 3: Create a container service
Complete the following steps to create the Lightsail container service using the AWS CLI, and then push your local container image to your new container service using the Lightsail control (lightsailctl) plugin.
Step 3a: Create a Lightsail container service with the create-container-service command.
The power and scale parameters specify the capacity of the container service. For a minimal flask app, little capacity is required.
The output of the create-container-service command indicates the state of the new service is “PENDING”. Refer to the second code block to see this.
aws lightsail create-container-service --service-name flask-service --power small --scale 1
Step 3b: Use the get-container-services command to monitor the state of the container as it is being created.
Wait until the container service state changes to “READY” before continuing to the next step. Your container service should become ready after a few minutes.
aws lightsail get-container-services
Output:
{
"containerService": {
"containerServiceName": "flask-service",
...
"state": "PENDING",
Output:
{
"containerService": {
"containerServiceName": "flask-service",
...
"state": "READY",
Step 3c: Push the application container to Lightsail with the push-container-image command.
Note: the X in ":flask-service.flask-container.X" will be a numeric value. If this is the first time you’ve pushed an image to your container service, this number will be 1. You will need this number in the next step.
aws lightsail push-container-image --service-name flask-service --label flask-container --image flask-container
Image "flask-container" registered.
...Refer to this image as ":flask-service.flask-container.X" in deployments.
Step 4:Deploy the container
Complete the following steps to create deployment and public endpoint configuration JSON files, and then deploy your container image to your container service.
Step 4a: Create a new file, containers.json. Edit the file and add the following code.
Replace the X in :flask-service.flask-container.X with the numeric value from the previous step.
Save the file.
The containers.json file describes the settings of the containers that will be launched on the container service. In this instance, the containers.json file describes the flask container, the image it will use and the port it will expose.
{
"flask": {
"image": ":flask-service.flask-container.X",
"ports": {
"5000": "HTTP"
}
}
}
Step 4b: Create a new file, public-endpoint.json.
Edit the file and add the following code.
Save the file.
The public-endpoint.json file describes the settings of the public endpoint for the container service. In this instance, the public-endpoint.json file indicates the flask container will expose port 5000. Public endpoint settings are only required for services that require public access.
After creating containers.json and public-endpoint.json files, your project directory should contain the following files:
- app.py
- containers.json
- Dockerfile
- public-endpoint.json
- requirements.txt
{
"containerName": "flask",
"containerPort": 5000
}
Step 4c: Deploy the container to the container service with the AWS CLI using the create-container-service-deployment command.
The output of the create-container-servicedeployment command indicates that the state of the container service is now “DEPLOYING” as shown.
aws lightsail create-container-service-deployment --service-name flask-service --containers file://containers.json --public-endpoint file://public-endpoint.json
Output:
{
"containerServices": [{
"containerServiceName": "flask-service",
...
"state": "DEPLOYING",
Step 4d: Use the get-container-services command to monitor the state of the container until it changes to “RUNNING” before continuing to the next step.
The get-container-service command also returns the endpoint URL for container service.
After the container service state changes to “RUNNING”, which typically takes a few minutes, navigate to this URL in your browser to verify your container service is running properly. Your browser output should show “Hello, World!” as before.
aws lightsail get-container-services --service-name flask-service
Output:
{
"containerServices": [{
"containerServiceName": "flask-service",
...
"state": "RUNNING",
... "url": "https://flask-service...
Congratulations! You have successfully deployed a containerized Flask application using Amazon Lightsail containers.
Step 5: Clean up resources
Complete the following steps to the Lightsail container service that you created as part of this tutorial.
Step 5a: To cleanup and delete Lightsail resources, use the delete-container-service command.
The delete-container-service removes the container service, any associated container deployments, and container images.
aws lightsail delete-container-service --service-name flask-service
Step 5b: Verify there are no containers running by using the get-container-services command.
aws lightsail get-container-services
Output:
{
"containerServices": []
}
Conclusion
Congratulations! You have successfully deployed a containerized Flask application using Amazon Lightsail containers.
Amazon Lightsail is a great choice to develop, build, and deploy a variety of applications like WordPress, websites, and blog platforms.