Deploying a Flask App with Gunicorn on Deployxa: A Complete Guide | Deployxa

Flask is the most popular Python microframework, and deploying it with Gunicorn on Deployxa is straightforward. Here is the complete zero-config guide.

← Back to Dispatch Articles
Engineering Log

Deploying a Flask App with Gunicorn on Deployxa: A Complete Guide

Flask is the most popular Python microframework, and deploying it with Gunicorn on Deployxa is straightforward. Here is the complete zero-config guide.

Deploying a Flask App with Gunicorn on Deployxa

Flask is the most popular Python microframework, and it is a favorite of AI assistants for building APIs and simple web apps. It is lightweight, flexible, and has a large ecosystem of extensions. But deploying Flask in production requires a WSGI server (like Gunicorn) to handle concurrent requests, which is a step that vibe coders often miss. Deployxa's zero-config engine handles the Gunicorn configuration automatically, detecting Flask from your requirements.txt and app.py and configuring the deployment. Here is how to deploy a Flask app with Gunicorn on Deployxa.

The direct answer is that Deployxa auto-detects Flask from your requirements.txt (which includes flask) and app.py (or wsgi.py). It configures the build and start commands: the build command is pip install -r requirements.txt, the start command is gunicorn app:app --bind 0.0.0.0:$PORT --workers 3, and the runtime is Python 3.11 with Gunicorn pre-installed. You do not write a Dockerfile, you do not configure Gunicorn manually, and you do not manage the WSGI server. The platform handles all of it, just as it does for FastAPI and Django apps.

Why Flask Is a Great Choice for AI-Generated APIs

Three reasons explain why Flask is a great choice for AI-generated APIs. First, it is simple. Flask's API is minimal (routes, request, response), which means the LLM can generate correct code with minimal guidance. Second, it is flexible. Flask does not impose a specific structure (unlike Django), which means the LLM can generate code that fits the user's request. Third, it has a large ecosystem. Flask has extensions for everything (SQLAlchemy for ORM, Flask-Login for auth, Flask-Mail for email), which means the LLM can leverage existing solutions. For more on Python deployment, see our article on why Python, Streamlit, and Gradio belong on persistent containers.

The Architecture: Flask + Gunicorn + Container

Here is how Deployxa deploys a Flask app.

The Flask container

The ingestion service detects Flask from your requirements.txt and app.py. It configures the build and start commands:

  • Build command: pip install -r requirements.txt
  • Start command: gunicorn app:app --bind 0.0.0.0:$PORT --workers 3
  • Runtime: Python 3.11 with Gunicorn

The Gunicorn configuration

Gunicorn is a WSGI server that handles concurrent requests by running multiple worker processes. The default configuration (3 workers) is appropriate for most apps, but you can adjust it based on your container's CPU (typically 2-4 workers per CPU core).

The reverse proxy

Traefik v3 routes traffic from your custom domain to the Flask container, with automatic SSL via Let's Encrypt.

Step-by-Step: Deploying a Flask App

Here is the exact workflow for a typical Cursor-generated Flask app.

Step 1: Create your Flask app

# app.py
from flask import Flask, request, jsonify
import os

app = Flask(__name__)

@app.route('/')
def hello():
    return jsonify({'message': 'Hello, World!'})

@app.route('/health')
def health():
    return jsonify({'status': 'ok'})

@app.route('/users', methods=['GET'])
def get_users():
    users = [
        {'id': 1, 'name': 'Alice', 'email': '[email protected]'},
        {'id': 2, 'name': 'Bob', 'email': '[email protected]'},
    ]
    return jsonify({'users': users})

@app.route('/users', methods=['POST'])
def create_user():
    data = request.get_json()
    # In a real app, save to database
    return jsonify({'user': data}), 201

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 5000)))

Step 2: Create requirements.txt

flask==3.0.0
gunicorn==22.0.0

Step 3: Push to GitHub

git init
git add .
git commit -m "flask app"
git remote add origin https://github.com/yourname/my-app.git
git push -u origin main

Step 4: Connect to Deployxa

In the Deployxa dashboard, connect your repository. Deployxa auto-detects Flask:

[ingest] Detected Python project
[ingest] Framework: flask
[ingest] Runtime: python 3.11
[ingest] WSGI server: gunicorn
[ingest] Build command: pip install -r requirements.txt
[ingest] Start command: gunicorn app:app --bind 0.0.0.0:$PORT --workers 3

Step 5: Configure environment variables

In the Deployxa dashboard, add any environment variables your app needs (e.g., DATABASE_URL, SECRET_KEY). The pre-flight scanner will warn you about any that are clearly required but missing.

Step 6: Deploy

Click Deploy. The build installs your dependencies, the container starts with Gunicorn, and your app is live within 60 to 90 seconds.

Step 7: Add a custom domain

Add a custom domain in the Deployxa dashboard. SSL is provisioned automatically.

Step 8: Verify with deployxa doctor

Run deployxa doctor to verify health. The 14-point readiness engine checks SSL, DNS, environment variables, health endpoints, and container status.

Common Pitfalls and Troubleshooting

The first pitfall is using the development server in production. Flask's built-in server (app.run()) is for development only and is not suitable for production, because it is single-threaded and cannot handle concurrent requests. The fix is to use Gunicorn (or uWSGI) in production, which Deployxa does automatically. The second pitfall is the PORT environment variable. Flask apps often hardcode the port (e.g., app.run(port=5000)), but Deployxa assigns a dynamic port via the PORT environment variable. The fix is to use int(os.environ.get('PORT', 5000)) in your development code, and to let Gunicorn handle the port in production (via --bind 0.0.0.0:$PORT). The third pitfall is the WSGI app variable name. Gunicorn's start command is gunicorn app:app, where the first app is the module name (app.py) and the second app is the Flask app variable name. If your Flask app variable has a different name (e.g., application), you need to adjust the start command (e.g., gunicorn app:application). The fourth pitfall is static files. Flask's static_folder serves static files in development, but in production, you should serve them via a CDN or a reverse proxy for better performance. The fifth pitfall is the number of Gunicorn workers. The default (3 workers) is appropriate for most apps, but for high-traffic apps, you might need more (typically 2-4 per CPU core). The fix is to adjust the --workers flag based on your container's CPU.

Performance: Flask vs FastAPI vs Django

Flask, FastAPI, and Django are the three leading Python web frameworks. Flask is the simplest (microframework), FastAPI is the fastest (async, type-safe), and Django is the most full-featured (batteries-included). For simple APIs, Flask is a great choice, because it is simple and flexible. For high-performance APIs (especially async), FastAPI is the better choice. For full-stack apps with ORM, auth, and admin, Django is the better choice. Deployxa supports all three equally, with the AutoRepairService and the zero-config engine handling each framework automatically. For more on framework comparisons, see our articles on deploying a FastAPI + Next.js monorepo and deploying Django + React.

Advanced Flask Patterns

Beyond the basics, Flask apps benefit from several advanced patterns. The first is Blueprints. Flask's Blueprints let you organize your app into modules (e.g., auth, api, admin), which makes the code more maintainable. The second is Flask-SQLAlchemy. Flask-SQLAlchemy integrates SQLAlchemy (the most popular Python ORM) with Flask, which makes database operations easy. The third is Flask-Login. Flask-Login handles user authentication and session management, which simplifies the auth flow. The fourth is Flask-Migrate. Flask-Migrate handles database migrations (via Alembic), which lets you evolve your database schema over time. The fifth is testing. Flask has built-in support for testing via pytest and Flask's test client, which makes it easy to write unit and integration tests. For more on testing, see our article on the testing void. For more on Flask deployment, see our articles on deploying a Go Fiber API and deploying a Rust Axum API.

Conclusion: Flask with Gunicorn Without the Configuration

Flask is the most popular Python microframework, and deploying it with Gunicorn should be as simple as pushing to Git. Deployxa's zero-config engine makes it so: no Dockerfile, no Gunicorn configuration, no WSGI server management. Stop configuring Gunicorn and start shipping.

Ready to deploy your Flask app? Drag your project to Deployxa Drop for an instant live preview, or install the CLI with npm i -g @deployxa/cli and deploy from your terminal. For more on framework deep-dives, see our articles on deploying an Express app with PM2 and deploying a Spring Boot app. Learn about deploying a Phoenix app with Elixir and deploying a Ruby on Rails app in our companion articles. Explore our free developer tools to speed up your workflow.

Ready to deploy with Deployxa?

Deploy your apps globally with automatic SSL and AI diagnostics.

Start Free Now