Flask Hosting with Gunicorn and Git Deploy
Host a Flask 3.1 app on VeloxaHost: Python 3.11, Gunicorn as the default start command, pip install from requirements.txt on every Git deploy, free HTTPS.
Flask is the app a VeloxaHost Python site expects out of the box. A new
Python site starts with a placeholder Flask app, and its default start
command is gunicorn -b 127.0.0.1:8000 app:app: Gunicorn serving the app
object from app.py. If your project follows that layout, you deploy it
without setting anything.
Each site is its own container with Python 3.11 and a virtual environment at
/opt/app/venv. The app runs as a system service called veloxa-app. The
site's web server answers on your domain with a free Let's Encrypt
certificate and forwards requests to Gunicorn on 127.0.0.1:8000.
Deploy from Git
Prepare the repository
Put a requirements.txt at the root of the app with Flask and Gunicorn in
it. The deploy installs from that file; it does not read pyproject.toml.
Flask>=3.1
gunicorn
Keep the app in app.py as app = Flask(__name__) and the default command
works. With an app factory, use a start command such as
gunicorn -b 127.0.0.1:8000 -w 2 'hello:create_app()', the form Flask's own
Gunicorn guide shows.
Behind the site's proxy, wrap the app with Werkzeug's ProxyFix so
request.remote_addr is the visitor's address and generated URLs use your
domain and https:
from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1)
One proxy sets these headers, so 1 is the right count.
Create and deploy the site
- In the console, open Websites and click Add Website.
- Enter your domain and pick Python under Hosting type.
- Leave Start Command empty for the default, or enter your own. It runs
from
/opt/appwith the virtual environment's programs, so it must start with something your requirements install, such asgunicorn, and listen on127.0.0.1:8000. - Click Create Website, then add the DNS records shown under DNS — point your domain here. HTTPS is issued once they resolve.
- In the Deploy from Git card, click Deploy and fill in the Repository URL (https), the Branch, an optional Subdirectory, and Auto-deploy: Manual / webhook only, Every hour or Every day.
- Click Deploy Now. The deploy makes a shallow clone, replaces the
contents of
/opt/appwith it (keepingvenv), runspip install -r requirements.txtand restarts the app. Refresh the page to see the result under Recent deploys. - For push-to-deploy,
POSTto the CI Webhook URL from your CI, for examplecurl -fsS -X POST "$VELOXAHOST_DEPLOY_HOOK". Only one deploy runs per site at a time.
Secrets and settings
Open the console (Advanced > Open Console) and add them to the app's service, where deploys do not touch them:
systemctl edit veloxa-app
# [Service]
# Environment=SECRET_KEY=change-me
# Environment=DATABASE_URL=postgresql://...
systemctl restart veloxa-app
Read them in Flask with os.environ. A .env file in the repository would
be public, because the deploy only clones public repositories.
Supported versions
| Component | Version |
|---|---|
| Python | 3.11, from Debian 12's packages |
| Flask | 3.1 (supports Python 3.9 and newer) |
| Gunicorn | Whatever your requirements.txt installs |
Python 3.11 gets security fixes until October 2027. There is no version picker; for another Python, use a VPS.
Which plan fits
A Flask app is light. Launch ($6.99/month: 1 vCPU, 1 GB RAM, 3 websites) runs a small app with two or three Gunicorn workers. Grow ($12.99/month: 2 vCPU, 4 GB RAM, 10 websites) suits busier apps or several of them. Each site can use up to its plan's RAM and vCPU, and gets 5 GB of disk on Launch and Grow, 2 GB on Scale and Business. Yearly billing is ten times the monthly price. Compare them on pricing.
Limits and when to use a VPS
- No database server on a Python site. SQLite works if you keep the file
outside
/opt/app, because each deploy replaces that folder. For PostgreSQL, MySQL or Redis, run them on a VPS. - One process. Gunicorn workers are fine; a Celery or RQ worker, or a scheduler, needs a process manager the site does not offer. A VPS with the Python (Docker) app runs those.
- No build step. A deploy installs requirements and restarts; that is all.
- Five minutes for the install. A failed
pip installdoes not fail the deploy today, so checkjournalctl -u veloxa-appif the app stops answering after a deploy.
For a bigger framework with an admin and migrations, see Django hosting; for async APIs, see FastAPI hosting.
FAQ
Do I need to set a start command for Flask?
Not if your app object is app in app.py and Gunicorn is in
requirements.txt. The default command is
gunicorn -b 127.0.0.1:8000 app:app.
Which port should Flask listen on?
Gunicorn should bind 127.0.0.1:8000. The site's web server forwards your
domain there and handles HTTPS, so the app speaks plain HTTP.
Can I use the Flask development server?
No. flask run is for development. Use Gunicorn, which the default start
command already does.
How do I see errors from my app?
Gunicorn writes to the service's journal. In the console, run
journalctl -u veloxa-app -n 100 to read the last hundred lines.
Can I deploy a private repository?
Not today. The Git deploy clones public repositories over https and stores no credentials or deploy keys.
Flask sites run on any managed hosting plan, from Launch at $6.99/month. Framework facts were checked on 2026-10-18 against: flask.palletsprojects.com/en/stable/installation, flask.palletsprojects.com/en/stable/deploying/gunicorn, flask.palletsprojects.com/en/stable/deploying/proxy_fix, gunicorn.org/reference/settings, packages.debian.org/bookworm/python3.
Ready to deploy?
Start a free trial, or compare plans to match your team's scale.