EthioDeploy/Docs
HomePricing
Overview

Overview

  • Getting started
  • How deploys work

Frameworks

  • Framework guides

Configuration

  • Web services & background workers
  • Environment variables
  • Addons
  • Database & Redis tools
  • Branch deployments
  • Custom domains
  • Analytics

Domains

  • Buying a domain

Agent mode

  • Agent mode
  • Agent plans & credit

CLI

  • Command-line tool

Account

  • Team access
  • Billing

Help

  • Troubleshooting
  • Still stuck?
Deploy guides
  • Next.js
  • Node.js
  • Python
  • SvelteKit
  • Django
  • FastAPI
  • Flask
  • Express
  • Laravel
  • Go
  • Lovable
  • Bolt
  • Firebase Studio
  • Claude Code & Cursor
Compare
  • AI coding agent
  • Hosting in Ethiopia
  • vs Heroku
  • vs Vercel
  • vs Render
  • vs Railway
  • vs Fly.io
  • vs Netlify
  • Heroku alternatives
Deploy guidesFlask

Deploy a Flask app

Flask needs one thing before it deploys: a gunicorn start command. Add ProxyFix so URLs and cookies know they're on HTTPS, then push.

Last updated October 23, 2026

Detected by
requirements.txt, pyproject.toml or Pipfile
Install
pip install -r requirements.txt (or poetry / uv / pdm)
Build
none by default
Start
none (set your own, or a Procfile web line)

These are the defaults. Override any of them in Settings → Build.

Flask has no default start command

Without one, the build stops with No start command could be found. Add gunicorn to your requirements and set the Start command to gunicorn app:app (module app.py, variable app). Gunicorn binds 0.0.0.0:$PORT on its own when PORT is set, which we do.

Prepare your app

flask
gunicorn

Pick the start command that matches your layout:

# app.py with app = Flask(__name__)
gunicorn app:app

# application factory in myapp/__init__.py
gunicorn "myapp:create_app()"

# two workers (Pro and above)
gunicorn -w 2 app:app

Coming from Heroku? A Procfile with a web: line is used as the start command, so you can leave it in the repo. Pin Python with a .python-version file; runtime.txt is not read.

HTTPS and ProxyFix

HTTPS ends at the platform's proxy. Tell Flask to trust the forwarded headers so url_for(..., _external=True) builds https:// links and redirects stay on HTTPS:

from werkzeug.middleware.proxy_fix import ProxyFix

app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1)
app.config.update(
    SECRET_KEY=os.environ["SECRET_KEY"],
    SESSION_COOKIE_SECURE=True,
)

Set SECRET_KEYin the project's env vars. Without a fixed key, sessions and flashed messages break on every deploy.

Add a health route

Every deploy requests your health check path (/ by default) and only goes live once it returns a 2xx or 3xx status. The platform keeps checking it after that. If / returns 404 or needs a login, add a route like /healthz that returns 200 and set it as the Health Check Path in Settings. Otherwise the deploy fails and the previous version keeps serving.

@app.get("/healthz")
def healthz():
    return "ok"

Add a database

Add a Postgres addon and DATABASE_URL is injected automatically. Flask-SQLAlchemy uses SQLAlchemy 2.x, which rejects the postgres:// scheme the URL comes with:

app.config["SQLALCHEMY_DATABASE_URI"] = os.environ["DATABASE_URL"].replace(
    "postgres://", "postgresql+psycopg://", 1
)

Add psycopg[binary] to your requirements. With Flask-Migrate, run migrations at start:

flask --app app db upgrade && gunicorn app:app

Deploy

  1. Sign in with GitHub and install the EthioDeploy app on the repo.
  2. Click “New Project” and pick the repo.
  3. Watch the build in the dashboard. When the health check passes, your app is live at <project-slug>.ethiodeploy.com. Every push to the default branch redeploys, and the old version keeps serving until the new one is healthy.

Troubleshooting

Build fails: No start command could be found

Cause: Flask has no default start command.

Fix: Set the Start command to gunicorn app:app, or add a Procfile web: line.

Failed to find attribute 'app' in 'app'

Cause: The gunicorn target doesn't match your module or variable name.

Fix: Use module:variable, or "module:create_app()" for a factory.

Logins don't stick or flashed messages vanish after a deploy

Cause: SECRET_KEY changes on each start.

Fix: Set a fixed SECRET_KEY env var.

Can't load plugin: sqlalchemy.dialects:postgres

Cause: SQLAlchemy 2.x doesn't accept the postgres:// scheme.

Fix: Rewrite it to postgresql+psycopg:// as shown above.

Redirects or external URLs use http://

Cause: Flask doesn't know the original request was HTTPS.

Fix: Wrap the app in ProxyFix.

Still stuck? Check the deployment's build log in the dashboard, or see Troubleshooting.

Questions

Can I host a Flask app for free?

Yes. The Free plan runs one project with a 512 MB Postgres database at no cost. It sleeps after 30 minutes without traffic, and the container has 256 MB of memory, enough for a small app with one or two gunicorn workers.

Do I still need a Procfile?

No. Set the start command in Settings → Build. If your repo already has a Procfile, its web line is used and you can skip the setting.

Can I run flask run in production?

Don't. flask run starts Werkzeug's development server, which isn't built for production traffic. Use gunicorn.

Ready to deploy? Sign in with GitHub and pick your repo. No Dockerfile, no YAML.

Other framework guides

Next.jsNode.jsPythonSvelteKitLovableBoltClaude Code & CursorDjangoFastAPILaravelExpressGoFirebase Studio

See the full docs for custom domains, env vars, addons, and billing.

On this page

  • Prepare your app
  • HTTPS and ProxyFix
  • Add a health route
  • Add a database
  • Deploy
  • Troubleshooting
  • Questions

Product

  • Pricing
  • Documentation
  • AI coding agent
  • Agent mode docs
  • Domains
  • Hosting in Ethiopia

Deploy guides

  • Next.js
  • Node.js
  • Python
  • SvelteKit
  • Django
  • FastAPI
  • Flask
  • Express
  • Laravel
  • Go
  • Lovable
  • Bolt
  • Firebase Studio
  • Claude Code & Cursor

Compare

  • EthioDeploy vs Heroku
  • EthioDeploy vs Vercel
  • EthioDeploy vs Render
  • EthioDeploy vs Railway
  • EthioDeploy vs Fly.io
  • EthioDeploy vs Netlify
  • Heroku alternatives

Company

  • About
  • Support
  • Contact
  • Terms
  • Privacy

EthioDeploy: agentic first development and deployment, started in Ethiopia, built for developers everywhere.