How do I get Flask to run on port 80?
Categories:
Running Flask Applications on Port 80

Learn how to configure your Flask application to run on the standard HTTP port 80, addressing common permission issues and deployment considerations.
By default, Flask's development server runs on port 5000. While this is suitable for local development, web applications are typically served on standard HTTP port 80 (or HTTPS port 443). Running an application on port 80 often requires special permissions, as it's considered a 'privileged port' on Unix-like systems (ports below 1024). This article will guide you through the necessary steps and best practices to get your Flask application accessible via port 80.
Understanding Port Privileges
On Linux and other Unix-like operating systems, ports below 1024 are designated as privileged ports. This means that only processes running with root privileges can bind to these ports. Directly running your Flask development server as root is generally discouraged due to security implications. A more secure and robust approach involves using a reverse proxy or granting specific permissions.
flowchart TD A[User Request] --> B{Port 80} B --> C{Privileged Port?} C -- Yes --> D[Requires Root/Special Permissions] C -- No --> E[Standard User Access] D --> F[Security Risk (if direct app)] D --> G[Recommended: Reverse Proxy] G --> H[Flask App (e.g., Port 5000)] E --> H
Flowchart illustrating port privilege considerations for web applications.
Method 1: Using a Reverse Proxy (Recommended for Production)
The most common and secure way to expose a Flask application on port 80 in a production environment is by using a reverse proxy like Nginx or Apache. The reverse proxy listens on port 80, handles incoming requests, and forwards them to your Flask application running on a non-privileged port (e.g., 5000). This setup offers several benefits, including load balancing, SSL termination, static file serving, and enhanced security.
server {
listen 80;
server_name your_domain.com www.your_domain.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
After configuring Nginx, ensure it's enabled and running. Your Flask application should be running on the specified internal port (e.g., 5000) using a production-ready WSGI server like Gunicorn or uWSGI.
Method 2: Granting CAP_NET_BIND_SERVICE
Capability (Linux Only)
For development or specific scenarios where a reverse proxy might be overkill, you can grant your Python executable the CAP_NET_BIND_SERVICE
capability. This allows it to bind to privileged ports (like 80) without running the entire process as root. This method is specific to Linux and should be used with caution, as it still elevates privileges for the Python interpreter.
sudo setcap 'cap_net_bind_service=+ep' $(which python3)
CAP_NET_BIND_SERVICE
to your Python interpreter means any Python script run by that interpreter can bind to privileged ports. This is a security risk and generally not recommended for production environments. It's best suited for controlled development setups.After granting the capability, you can run your Flask application directly on port 80:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
Method 3: Port Forwarding (Less Common, Development Only)
Another approach, primarily for development or testing on a local machine, is to use iptables
(Linux) or similar tools to forward traffic from port 80 to your Flask application's default port (e.g., 5000). This doesn't change the port your Flask app binds to, but rather redirects incoming traffic.
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 5000
sudo iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 5000
iptables
rules are temporary and will be lost on reboot. To make them persistent, you'll need to save them using iptables-save
and restore them on startup, or use a tool like netfilter-persistent
.Deployment Considerations
When deploying a Flask application to a production server, always use a production-ready WSGI server (like Gunicorn or uWSGI) in conjunction with a reverse proxy (Nginx or Apache). The Flask development server (app.run()
) is not designed for production use due to its lack of security features, performance, and stability.
1. Install Gunicorn
Install Gunicorn, a popular WSGI HTTP server for Unix, using pip: pip install gunicorn
.
2. Run Flask with Gunicorn
Start your Flask application using Gunicorn on a non-privileged port, for example: gunicorn -w 4 -b 127.0.0.1:5000 your_app_module:app
(replace your_app_module
and app
with your actual module and Flask app instance name).
3. Configure Nginx
Set up Nginx as a reverse proxy to forward requests from port 80 to your Gunicorn-served Flask application, as shown in Method 1.
4. Manage with Systemd
Create a Systemd service file to ensure Gunicorn starts automatically on boot and can be managed easily. This ensures your application is always running.