How to Deploy a Flask Application on Cloudzilla
Imagine you want to create a simple blog where people can read posts, and you’d like it to be live on the internet. Flask, a lightweight Python web framework, is perfect for this because it’s quick to set up and flexible. Cloudzilla, meanwhile, is a cloud platform that makes deploying such an app straightforward while keeping you in control. By the end of this, your blog will be up and running, accessible to anyone with its URL.
This guide walks you through creating a simple Flask blog, preparing it for deployment, and getting it live on Cloudzilla. Each piece of code is followed by an explanation of what it does and why it’s necessary, so you understand the process fully.
Prepare Your Flask Application
We’ll create a basic blog application with a homepage to list posts and individual pages for each post. This section sets up the foundation.
Set Up Your Project
mkdir flask_blog
cd flask_blog
Creating a dedicated directory organizes your project files. Navigating into it prepares you to work within this space.
Create a Virtual Environment
python3 -m venv venv
source venv/bin/activate # On Windows, use `venv\Scripts\activate`
A virtual environment isolates your project’s dependencies. Activating it ensures that packages you install stay specific to this application.
Install Flask
pip install flask
Flask is the framework powering your web app. Installing it here makes it available within the virtual environment.
Building the Blog
So now we need the actual working Flask app to deploy. Let’s set up the blog with a homepage and individual post pages.
Here’s the code for the main Flask application file, app.py:
from flask import Flask, render_template
app = Flask(__name__)
posts = [ {"id": 1, "title": "First Post", "content": "This is the first blog post."}, {"id": 2, "title": "Second Post", "content": "This is the second blog post."}, ]
@app.route('/') def index(): return render_template('index.html', posts=posts) @app.route('/post/<int:post_id>') def post(post_id): post = next((post for post in posts if post['id'] == post_id), None) if post is None: return "Post not found", 404 return render_template('post.html', post=post) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=True)
This code creates a Flask app with two routes. The homepage route (/) displays a list of blog posts, and the post route (/post/<post_id>) shows a single post’s details. The posts variable holds sample data, and the app runs on port 5000 with 0.0.0.0 as the host. Flask is the engine that handles web requests, and defining these routes makes your blog interactive. Running on 0.0.0.0 allows external access, which is essential for testing and deployment, while port 5000 is a common choice that we’ll configure Cloudzilla to use later.
Next, create the homepage template in templates/index.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Blog Homepage</title> </head> <body> <h1>Welcome to My Blog</h1> <ul> {% for post in posts %} <li><a href="{{ url_for('post', post_id=post.id) }}">{{ post.title }}</a></li> {% endfor %} </ul> </body> </html>
This HTML file uses Jinja2 templating to loop through the posts and create clickable links to each post’s page. The url_for function generates URLs dynamically based on the post route. Separating the presentation (HTML) from the logic (Python) keeps your code organized and easier to update, and dynamic links ensure users can navigate your blog seamlessly. Now, add the post template in templates/post.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{{ post.title }}</title> </head> <body> <h1>{{ post.title }}</h1> <p>{{ post.content }}</p> <a href="{{ url_for('index') }}">Back to Homepage</a> </body> </html>
This template displays a single post’s title and content, with a link back to the homepage. The {{ post.title }} and {{ post.content }} placeholders pull data from the Flask app. This completes the blog’s functionality by giving each post its own page, and the back link improves user navigation, which is critical for a good experience.
Getting Ready for deployment
Install the required packages:
pip install gunicorn
This installs Gunicorn, a WSGI server for production. Flask powers your app, but its built-in server isn’t suited for real-world use. Gunicorn handles multiple requests efficiently, making it ideal for cloud deployment.
Generate a requirements.txt file:
pip freeze > requirements.txt
This command lists all installed packages (like Flask and gunicorn) with their versions in a file. Cloudzilla will use this to install the same dependencies during deployment. This guarantees that the cloud environment matches your local setup, avoiding issues from mismatched versions.
Create a Dockerfile with this content:
FROM python:3.9-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . EXPOSE 5000 CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
Note: Ensure to name your Dockerfile with a capital “D” as cloudzilla is case sensitive.
This Dockerfile starts with a slim Python 3.9 image, sets /app as the working directory, copies and installs dependencies, adds your app files, exposes port 5000, and runs Gunicorn. Cloudzilla doesn’t natively support Flask, so containerizing your app with Docker ensures it runs consistently by defining its entire environment, which Cloudzilla then builds and deploys.
Test your app locally with Gunicorn:
gunicorn --bind 0.0.0.0:5000 app:app
This runs your app on port 5000, accessible at http://127.0.0.1:5000.
Testing with Gunicorn mimics the production setup, confirming everything works before deployment.
Push Your Code to GitHub
Cloudzilla deploys from GitHub, so you need to upload your project.
Initialize a Git repository:
git init
This command turns your project folder into a Git repository. Git tracks changes, making it easy to manage your code. Version control is essential for deployment, and Cloudzilla relies on GitHub to access your app.
Create a .gitignore file:
echo "venv/" > .gitignore echo "__pycache__/" >> .gitignore echo "*.pyc" >> .gitignore
This excludes the virtual environment and Python cache files from Git. These files are local-specific and shouldn’t be deployed. It keeps your repository clean and avoids uploading unnecessary data to GitHub. Commit your code:
git add . git commit -m "Initial Flask blog app with Dockerfile"
This stages all files and commits them with a message. Committing creates a versioned snapshot Cloudzilla can deploy. This prepares your code for upload and tracks its state. Go to your github, create a new repository and name it “flask-blog”
This is where we will be pushing our code to.
To push to github:
git remote add origin https://github.com/yourusername/flask-blog.git git branch -M main git push -u origin main
Replace your username with your GitHub username after creating a flask-blog repository. This links your local repo to GitHub, sets main as the default branch, and uploads your code. We’re pushing to Github because Cloudzilla needs your code online to pull and deploy it.
Deploy to Cloudzilla
Log in to Cloudzilla with your github account and select Import Repository.
This lets Cloudzilla access your flask-blog repo, select it from the list of repo’s available. We use this option because it connects your GitHub code to Cloudzilla for automated deployment.
This connects your GitHub account by installing the Cloudzilla GitHub App and granting access to your repo. It lets Cloudzilla add a workflow file for deployment and enables seamless builds via GitHub Actions.
Cloudzilla detects the Docker framework from your Dockerfile. Since Flask isn’t natively supported, the Dockerfile tells Cloudzilla how to handle your app. It automatically detects it and ensures compatibility by packaging your app completely.
Use the default workspace or create one like “flask-projects”, select the main branch, set the port to 5000 (matching the Dockerfile), and note that build and start commands come from the Dockerfile. These settings define where your app lives, which version to deploy, and how traffic reaches it. All this aligns Cloudzilla with your app’s structure for a successful launch.
Optionally, you can add environment variables (e.g., DATABASE_URL) in Cloudzilla if your app needs them. This blog doesn’t, but variables configure runtime settings securely. This may be needed for apps with external dependencies, though not required here.
Choose a deployment region like North America.
Cloudzilla optimizes placement within the region for performance
Click Deploy. Cloudzilla builds a Docker container from your Dockerfile and deploys it with automatic SSL. and Boom your project is online within a few seconds
Verify and Monitor
After deployment, Cloudzilla provides a URL (e.g., https://empty-hill-7008.czapps.net). Visit it to confirm your blog is live. It verifies deployment worked, so you’re confident it’s accessible.
Monitor your app viaCloudzilla’s dashboard, which shows traffic, logs, and deployment details. This helps you track performance and spot issues.
Your site should now be hosted and accessible.
If the build fails, check GitHub Actions logs for Dockerfile or dependency errors. For port issues, ensure Cloudzilla’s port matches 5000. If the app doesn’t load, verify Gunicorn is in requirements.txt and the Dockerfile’s CMD is correct.
Conclusion
You’ve deployed your Flask blog on Cloudzilla! Using a Dockerfile made it compatible with Cloudzilla’s containerization, while GitHub integration streamlined the process. Your app is now live, secure, and ready for visitors, with full control over its environment. Explore Cloudzilla’s features to scale or enhance it further as needed.
About the Author
Omu Inetimi is a developer and writer who’s passionate about explaining complex concepts to both technical and non-technical audiences. With experience writing for a variety of technical publications, Omu focuses on creating accessible, engaging content that empowers readers to build effective solutions. When not coding or writing, you’ll find him playing chess online or sharing insights on Twitter.