Start a minimal Flask app
# hello.py
from flask import Flask
app = Flask(__name__)
@app.get("/")
def hello():
return {"status": "ok"}
# Start it from the project environment
flask --app hello run --debug
The terminal should print http://127.0.0.1:5000. Use that exact URL and keep the terminal open so request logs and exceptions remain visible.
Diagnose before changing configuration
| Symptom | Meaning | Action |
|---|---|---|
ERR_CONNECTION_REFUSED | No listener at the requested address and port. | Read the startup error and inspect port 5000. |
Address already in use | Another process owns 5000. | Identify it or run Flask with --port 5001. |
| HTTP 404 | Flask received the request, but no route matched. | Check the route path, slash, blueprint prefix, and HTTP method. |
| HTTP 405 | The path exists but does not allow that method. | Compare GET, POST, PUT, and the route’s methods. |
| Works locally, not from phone | The default loopback bind is local to the computer. | Bind deliberately to a LAN interface and apply firewall controls. |
# Windows PowerShell
Get-NetTCPConnection -LocalPort 5000 -State Listen
# macOS or Linux
lsof -nP -iTCP:5000 -sTCP:LISTEN
# Direct request
curl -i http://127.0.0.1:5000/
Address already in use
Flask’s own documentation recommends identifying the existing program or selecting a different port:
flask --app hello run --port 5001
On macOS Monterey and later, AirPlay Receiver may occupy port 5000. If the listener belongs to that system service, either choose 5001 or disable AirPlay Receiver in System Settings when you do not use it.
Do not blindly kill the reported PID. Confirm the executable and whether another project or system feature depends on it.
The root works, but /login or /api fails
That is an application-routing issue, not a localhost failure. Flask routes are explicit and method-specific:
@app.get("/api/health")
def health():
return {"status": "ok"}
@app.post("/login")
def login():
...
A browser address bar sends GET. It will receive 405 from a POST-only /login route. If the route is registered on a blueprint with url_prefix="/api", include that prefix in the request.
LAN and Docker access
# Reachable on the local network; development only
flask --app hello run --host 0.0.0.0 --port 5000
# Docker host mapping
docker run --rm -p 5000:5000 your-image
In a container, Flask must listen on 0.0.0.0 inside the container as well as having a published host port. From another device, browse to the computer’s LAN IP, not localhost—“localhost” always means the device making the request.
Flask’s development server and interactive debugger are not for production. The debugger can execute Python code. Keep it on trusted development networks only.
Official references
- Flask: Development serverDefault URL, debug workflow, port conflicts, macOS AirPlay, and production warning.
- Flask: QuickstartMinimal app, routing, external binding, and debugger risk.
- Flask: Deploying to productionWhy a production WSGI server is required.