Flask is a micro web framework. It is minimalistic and gives developers the flexibility to choose additional libraries. Flask shines for smaller projects or where you don't need batteries-included approach and would rather have smaller codebase, less dependencies, and pick a component for every small task yourself.
If you are looking for other deployment tutorials checkout out one of these:
- Deploy Django on Hetzner Cloud
- Deploy Django to Digital Ocean Droplet
- Deploy Django to AWS Lightsail
- Deploy Django to AWS EC2
- Deploy Django on Linode
- Deploy Django to Google Cloud Platform
In this post:
Create a Flask App¶
Here is the link to the demo repository: https://github.com/appliku/flask_demo
Setup the environment 1. First create an app directory
mkdir flask_demo
cd flask_demo
- Create virtual environment and install packages
python3 -m venv env
source env/bin/activate
pip install Flask SQLAlchemy Flask-SQLAlchemy psycopg2-binary gunicorn
Create a requirements.txt
file with all these dependencies from the current virtual env:
pip freeze > requirements.txt
- Create a new file
app.py
. First, import required libraries and create a Flaskapp
:
import os
from flask import Flask, request
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
app = Flask(__name__)
- Set up the database connection. and setup ORM(Object-Relational Mapping) configuration using SQLAlchemy. It will grab
DATABASE_URL
environment variable for DB connection string.
DATABASE_URL = os.environ['DATABASE_URL']
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
- Create a model for the database table "Messages"
class Message(Base):
__tablename__ = "messages"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
email = Column(String, index=True)
message = Column(String, index=True)
- Initialise the database
# Create the table in the database
Base.metadata.create_all(bind=engine)
- Add a POST endpoint for submitting messages to the database
@app.route('/messages', methods=['POST'])
def add_message():
data = request.get_json()
name = data['name']
email = data['email']
message = data['message']
new_message = Message(name=name, email=email, message=message)
db = SessionLocal()
db.add(new_message)
db.commit()
db.refresh(new_message)
db.close()
return {
"name": new_message.name,
"email": new_message.email,
"message": new_message.message,
"id": new_message.id
}
- Add a home endpoint
@app.route('/', methods=['GET'])
def home():
return 'Hello, world!'
- Run the app:
if __name__ == '__main__':
app.run(host='0.0.0.0')
This is the whole file app.py
:
import os
from flask import Flask, request
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
app = Flask(__name__)
DATABASE_URL = os.environ['DATABASE_URL']
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
class Message(Base):
__tablename__ = "messages"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
email = Column(String, index=True)
message = Column(String, index=True)
# Create the table in the database
Base.metadata.create_all(bind=engine)
@app.route('/messages', methods=['POST'])
def add_message():
data = request.get_json()
name = data['name']
email = data['email']
message = data['message']
new_message = Message(name=name, email=email, message=message)
db = SessionLocal()
db.add(new_message)
db.commit()
db.refresh(new_message)
db.close()
return {
"name": new_message.name,
"email": new_message.email,
"message": new_message.message,
"id": new_message.id
}
@app.route('/', methods=['GET'])
def home():
return 'Hello, world!'
if __name__ == '__main__':
app.run(host='0.0.0.0')
Also create the .gitgnore
file. Main thing to include in this file is python cache files, virtual env and your editor of choice dot directory. Extend the following list for your own setup.
env/
.idea/
__pycache__/
*.py[cod]
*$py.class
.vscode/
.DS_Store
.AppleDouble
.LSOverride
Now we need to initialize a git repository and push it.
git init
git add .
git commit -m'Initial commit'
Create a GitHub or GitLab repository, add the remote and let's deploy it with Appliku.
Push Flask App to GitHub¶
Go to GitHub.com and create a new repository
Copy the git remote add origin
line and run it in your terminal in the project directory
and then run the push command: git push -u origin master
Now your Flask app is ready to be deployed.
Deploy Flask App¶
In order to deploy Flask App you need two things: - Appliku Account - Cloud Provider account
From cloud provider you get a server that will run your apps and databases.
Appliku automates the setup of the server, build the app and deploy it whenever you push new changes to git. Appliku will also issue an SSL certificate for your custom domain, make backups and help you setup scheduled tasks (CRON).
Get your account here: https://app.appliku.com/
Deploy Flask App on AWS EC2¶
AWS is a massive cloud provider that offers hundreds of different types of services for running your apps and additional tools.
Get your account here: https://portal.aws.amazon.com/billing/signup#/start/email
In this section we'll create an EC2 Instance and deploy your Flask app on it.
In Appliku dashboard go to the Servers tab.
If you haven't set up AWS connection then follow instructions to generate required credentials and add them to your team.
When it is done you will be able to create an AWS EC2 Instance.
Select AWS provider.
Select the region, instance type and the disk size. To fit in AWS Free Tier make sure the disk size to be <30GB.
Click "Create EC2 Instance".
You will be taken to the server page where you will see the setup process. When it is finished, go to Applications tab and create a new app from GitHub (or GitLab if you hosted your repository there)
Deploy Flask App on Digital Ocean¶
If you choose to go with Digital Ocean first make sure to create a DO account.
You will need to generate a token here https://cloud.digitalocean.com/account/api/tokens/new
Make sure to select scopes both "Read" and "Write". We recommend to setup expiration to "Never" or "1 Year" to avoid service interruptions.
In Appliku dashboard go to Servers tab and click "Setup Credentials" for Digital Ocean. Paste and save the token and go back to Servers tab. You will be able to select Digital Ocean provider now.
Select the region and Droplet Type. For Droplet Size we strongly recommend to pick at least 1GB RAM instance so your server can build and run your app and the database.
Click "Create Droplet".
Appliku will call Digital Ocean API and create a server for you and begin setup.
When that is finished you will be able to create the app and the database.
Deploy Flask App on Hetzner server¶
Hetzner is an old, cheap and very reliable hosting company and it is our favorite one!
Create an account here: Hetzner Sign Up
When it is setup up - go to Appliku Dashboard -> Servers. Select "Custom"
Copy the SSH Public Key
Now go to Hetzner Cloud https://www.hetzner.com/cloud and create a project. Within the project click on Add Server.
We recommend picking Falkenstein datacenter because there they offer new ARM Ampere servers, which are most cost efficient and way more powerful.
For the Image select Ubuntu 22.04 (selected by default)
For Type select Arm64 (Ampere) and go with the smallest server. Please note how much power and resource you get for the price of roughly $4/mo compared to Digital Ocean or AWS. Same similar amount of resources in Digital Ocean would cost you $24/mo!
Scroll down and click "Add SSH key" and paste the public key you copied from the Appliku Dashboard. When key is added make sure it is selected for the server.
Now you can click "Create & Buy Now".
Creation doesn't take much time, usually server is ready in under 5-10 seconds.
Copy the Public IP address of the server and go back to Appliku dashboard and paste it to the IP address field.
Click Check credentials and add server
You will be brought to the server page. You will see that setup process is started. You can see Setup Logs for details of the process or errors if setup fails.
Server setup is complete:
Deploy Flask App Application with Appliku¶
Click on the "Applications" menu link
If you haven't setup connection to will need to do that by clicking Setup Credentials.
When you are done you will be able to select the service you prefer. For this tutorial we'll go with GitHub
Give your app a name, select repository, branch and the server you have just created and click "Create Application".
After that you will be brought to the Application Overview page. First thing we need to do is to add a database. Click on "Add Database" and create a Postgres 16 instance.
Wait for it to get to "Deployed" status.
Now go back to the application overview and click "Add Processes" button.
Add a web
process with command gunicorn app:app --log-file -
and click the "Save and Deploy" button.
Go back to the application overview page. When the deployment is finished click on the "Open App" dropdown and click on the default domain name to view the app.
You will see a "Not Found" page, but that's okay because we didn't define any endpoint for the root path.
Now go to terminal and run a CURL command to save a message.
Make sure to replace the hostname to match your apps name.
curl --request POST \
--url https://flaskdemo.applikuapp.com/messages \
--header 'Content-Type: application/json' \
--data '{
"name" : "john Snow",
"email": "123@example.com",
"message": "hello"
}'
In the response you will get back the whole data that was sent and the ID
You can now go back to the database and copy the credentials.
Using a PostgreSQL client of your choosing connect to the DB.
I will do it from terminal:
psql postgresql://zsvvnnazpydkfbvl:kzzhiptmyovrwhka@3.79.39.213:8002/skkpcfnwuhuixrpr
psql (16.3)
Type "help" for help.
skkpcfnwuhuixrpr=# \dt
List of relations
Schema | Name | Type | Owner
--------+----------+-------+------------------
public | messages | table | zsvvnnazpydkfbvl
(1 row)
skkpcfnwuhuixrpr=# select * from messages;
id | name | email | message
----+-----------+-----------------+---------
1 | john Snow | 123@example.com | hello
(1 row)
You can see that table is created and there is a record with our message.
Congratulations! You have deployed a fully functional Flask app with a PostgreSQL database!