Deploying a Small Flask App on a NAT VPS

Updated · Autdo Cloud

Run a Flask application behind a production WSGI server, with a deliberate listener and ingress configuration. Flask's development server is for development and should not be treated as a production deployment merely because a NAT port makes it reachable.

Build an isolated environment

On a Debian or Ubuntu guest with Python's venv support installed:

python3 -m venv .venv
.venv/bin/pip install flask gunicorn
sh

Create an app.py in the project directory:

from flask import Flask

app = Flask(__name__)

@app.get("/health")
def health():
    return {"status": "ok"}
python

Start a local test with .venv/bin/gunicorn --workers 1 --bind 127.0.0.1:8000 app:app and request http://127.0.0.1:8000/health inside the VPS. This binds only to loopback, suitable for a guest-local reverse proxy or SSH tunnel.

Add controlled ingress

For public traffic, use a correctly configured proxy that reaches the application and provides the required HTTPS entry point. Do not expose Flask debug mode. If deliberately binding a WSGI server to a guest interface, add authentication and appropriate network controls; NAT alone does not supply them.

Operate it as a service

Use systemd under a nonprivileged account, with absolute executable paths. Set a small worker count on a low-memory VPS and measure memory before adding concurrency. Keep application secrets out of the source and back up persistent data separately.

See systemd deployment, public website networking and memory budgeting.

Reference: Flask production deployment documentation.