Skip to content

flask-deployment/flask-deployment-checklist

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 

Repository files navigation

Flask Deployment Checklist

A practical, copy-pasteable checklist for taking a Flask app to production without forgetting the things that cause 2 a.m. incidents — process supervision, HTTPS, secrets, backups, and monitoring.

Copy the list below into a GitHub issue or PR and tick items off as you go. Each section links to a step-by-step guide on flask-deployment.com for the details.

📖 Prefer an interactive version? See the full production checklist.


Server & environment

  • Provisioned a server (or PaaS) and can reach it over SSH. → Ubuntu VPS guide
  • Created a non-root user to own and run the app.
  • System packages updated (sudo apt update && sudo apt upgrade).
  • Firewall allows only 22, 80, and 443. → Security checklist
  • Python virtual environment created and dependencies pinned in requirements.txt.

Application configuration

  • FLASK_CONFIG=production and FLASK_DEBUG=0 (debug is off). → Config basics
  • A strong, unique SECRET_KEY loaded from the environment, not source. → Env vars & secrets
  • Per-environment config classes (dev / staging / production). → Config environments
  • Secrets stored in a systemd EnvironmentFile (chmod 600) or a secret manager — never committed.

WSGI server (Gunicorn)

  • App served by Gunicorn, not the Flask dev server. → Gunicorn vs Waitress
  • Correct module:app import path verified (gunicorn wsgi:app).
  • Worker count and class tuned for the workload. → Gunicorn tuning
  • Bound to 127.0.0.1/socket (not 0.0.0.0) behind the proxy.

Process supervision (systemd)

  • systemd unit runs Gunicorn as the app user with the right WorkingDirectory. → systemd + Gunicorn
  • Restart=always and the service is enabled (starts on boot).
  • Graceful reload wired (ExecReload=/bin/kill -s HUP $MAINPID). → Zero-downtime deploys
  • systemctl status is active (running) and survives a reboot.

Reverse proxy (Nginx)

  • Nginx proxies to the Gunicorn socket/port; proxy_pass matches the bind exactly. → Nginx + Gunicorn
  • Correct server_name; default site disabled.
  • Forwarded headers set (Host, X-Forwarded-For, X-Forwarded-Proto).
  • nginx -t passes and Nginx is reloaded. → Nginx reverse proxy explained

HTTPS & domain

  • DNS A/AAAA records point to the server. → Domain & DNS
  • TLS certificate issued via Certbot/Let's Encrypt. → HTTPS setup
  • HTTP redirects to HTTPS; certificate auto-renewal tested (certbot renew --dry-run).
  • Secure cookies enabled (SESSION_COOKIE_SECURE, HttpOnly, SameSite).

Database

  • Production database provisioned with a dedicated, least-privilege user. → Flask + PostgreSQL
  • DATABASE_URL injected via environment.
  • Migrations applied (flask db upgrade) — never flask db migrate on the server. → Migrations fix
  • Connection pool sized sensibly relative to Gunicorn workers.

Static & media files

Security

  • Debug mode disabled; no stack traces exposed to users. → Security checklist
  • Gunicorn/app runs as a non-root user.
  • Security headers and request size limits set in Nginx.
  • Dependencies scanned (pip-audit) and kept up to date.

Monitoring, logging & backups

Pre-launch smoke test

  • curl -I https://your-domain returns 200/expected status over HTTPS.
  • Gunicorn reachable directly on its socket/port (rules out proxy issues). → Fix 502
  • Key user flows work against production config and data.
  • Logs are clean of errors after a few real requests.

Related

License

MIT — see LICENSE. Reuse freely; a link back to flask-deployment.com is appreciated.

About

A copy-pasteable production deployment checklist for Flask apps (Gunicorn, Nginx, HTTPS, secrets, backups, monitoring).

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors