Ship Your Flask App to Production
Flask is one of the most popular Python web frameworks — lightweight, flexible, and backed by a huge ecosystem of extensions. It powers everything from simple REST APIs to full-featured web applications. But getting Flask from flask run on your laptop to a real production URL involves a WSGI server, a container, and some cloud plumbing.
PandaStack handles the cloud side. You bring the code and a Dockerfile; PandaStack handles scaling, HTTPS, and deployments.
Prerequisites
- Python 3.11+ installed locally
- Docker installed locally
- A GitHub account
- PandaStack CLI:
npm install -g @pandastack/cli
Step 1 — Create Your Flask Application
mkdir my-flask-app && cd my-flask-app
python3 -m venv venv
source venv/bin/activate
pip install flask gunicornCreate app.py:
from flask import Flask, jsonify
import os
app = Flask(__name__)
@app.route('/health')
def health():
return jsonify({'status': 'ok'})
@app.route('/api/hello')
def hello():
return jsonify({'message': 'Hello from PandaStack!'})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 5000)))Pin your dependencies:
pip freeze > requirements.txtStep 2 — Use Gunicorn as Your WSGI Server
Never run flask run in production — it is single-threaded and not designed for concurrent traffic. Gunicorn is the standard WSGI server for Flask production deployments.
Test Gunicorn locally:
gunicorn --bind 0.0.0.0:5000 --workers 4 app:app
curl http://localhost:5000/healthStep 3 — Write a Production Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "4", "--timeout", "120", "app:app"]The --no-cache-dir flag keeps the image lean. Four Gunicorn workers handle concurrent requests efficiently in a container environment.
Build and test locally:
docker build -t my-flask-app .
docker run -p 5000:5000 my-flask-app
curl http://localhost:5000/api/helloAdd a .dockerignore:
venv/
__pycache__/
*.pyc
.env
*.logStep 4 — Configure pandastack.json
{
"type": "container",
"healthCheckPath": "/health"
}PandaStack polls /health after each deployment. A successful 200 response confirms the app is ready to receive traffic. Failed health checks trigger an automatic rollback.
Step 5 — Push to GitHub and Deploy
git init
git add .
git commit -m "Flask app with Gunicorn and Docker"
gh repo create my-flask-app --public --source=. --pushDeploy with the PandaStack CLI:
panda deployOr go to [dashboard.pandastack.io](https://dashboard.pandastack.io), click New Project, and connect your GitHub repository. PandaStack detects the Dockerfile and starts the build pipeline immediately.
Step 6 — Set Environment Variables
Configure secrets securely through the PandaStack dashboard under Environment Variables:
DATABASE_URL=postgresql://user:pass@host:5432/mydb
SECRET_KEY=your-flask-secret-key
FLASK_ENV=productionAccess them in Flask with os.environ.get('DATABASE_URL').
Step 7 — Connect a Managed Database
Provision a PostgreSQL database for your Flask app:
panda db create --type postgres --name flask-dbInstall psycopg2-binary and SQLAlchemy if needed:
pip install psycopg2-binary flask-sqlalchemy
pip freeze > requirements.txtVerify the Deployment
After the build completes, PandaStack serves your app over HTTPS:
curl https://my-flask-app.pandastack.io/api/hello
# {"message":"Hello from PandaStack!"}Stream live logs from the CLI:
panda logs --followTroubleshooting Common Issues
Port binding errors: Ensure Gunicorn binds to 0.0.0.0, not 127.0.0.1. The container must accept traffic from outside its network namespace.
Missing system dependencies: If your app uses psycopg2 (not psycopg2-binary), add libpq-dev to the Dockerfile:
RUN apt-get update && apt-get install -y libpq-dev && rm -rf /var/lib/apt/lists/*Large image size: Use python:3.12-slim instead of python:3.12. This cuts the image from ~1GB to ~120MB and speeds up deployments significantly.
Summary
Your Flask application is now running in production with Gunicorn, Docker, and automatic GitHub-triggered deployments. Every git push to your default branch builds and deploys a new version. Find the complete reference at [docs.pandastack.io](https://docs.pandastack.io).