On this page
article
Deploying Flask
Deploy Flask applications with Gunicorn, Nginx, Docker, and production configuration best practices.
Flask’s built-in server is for development only. Production deployment uses Gunicorn (or uWSGI) behind Nginx.
Application Factory
# app/__init__.py
from flask import Flask
import os
def create_app():
app = Flask(__name__)
app.config.from_mapping(
SECRET_KEY=os.environ.get("SECRET_KEY", "dev"),
SQLALCHEMY_DATABASE_URI=os.environ["DATABASE_URL"],
SQLALCHEMY_TRACK_MODIFICATIONS=False,
)
from .routes import main
app.register_blueprint(main)
return app
# wsgi.py
from app import create_app
app = create_app()
Gunicorn
pip install gunicorn
gunicorn wsgi:app --bind 0.0.0.0:8000 --workers 4 --timeout 120
Docker
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt gunicorn
COPY . .
EXPOSE 8000
CMD ["gunicorn", "wsgi:app", "--bind", "0.0.0.0:8000", "--workers", "4"]
Environment Variables
Never hardcode secrets:
# .env (not committed)
SECRET_KEY=your-random-secret-key
DATABASE_URL=postgresql://user:pass@db:5432/myapp
FLASK_ENV=production
import os
app.config["SECRET_KEY"] = os.environ["SECRET_KEY"]
Health Check
@app.route("/health")
def health():
return {"status": "ok"}, 200
Production Checklist
-
DEBUG = False - Strong
SECRET_KEYfrom environment - Gunicorn with multiple workers
- Nginx for SSL termination and static files
- PostgreSQL instead of SQLite
- Database connection pooling
- Logging configured
- Health check endpoint
- Rate limiting on public endpoints
Flask’s simplicity extends to deployment — a minimal WSGI setup is all you need.