This guide explains how to configure a Flask application to run on a specific network interface on a macOS server with multiple NICs.
- macOS server with multiple network interfaces
- Python installed
- Flask installed (
pip install flask
)
First, find the IP address of your internal network interface (the one with a 10.x.x.x address):
ifconfig
Look for an interface with an address that starts with 10.x.x.x and note both the interface name and the exact IP address.
Example output:
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
...
inet 192.168.1.5 netmask 0xffffff00 broadcast 192.168.1.255
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
...
inet 10.0.0.15 netmask 0xffffff00 broadcast 10.0.0.255
In this example, en1
is the internal network interface with IP 10.0.0.15
.
Create a file named app.py
with the following content:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello, World!"
if __name__ == '__main__':
# Replace with your actual internal IP address
app.run(host='10.x.x.x', port=5000, debug=True)
Replace 10.x.x.x
with your actual internal IP address (e.g., 10.0.0.15
).
python app.py
export FLASK_APP=app.py
flask run --host=10.x.x.x --port=5000
Replace 10.x.x.x
with your actual internal IP address.
Install Gunicorn:
pip install gunicorn
Run with Gunicorn:
gunicorn -b 10.x.x.x:5000 app:app
Your Flask application should now be accessible only from your internal network at http://10.x.x.x:5000
.
-
Check firewall settings:
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
If the firewall is active, you may need to add an exception:
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --add /path/to/python
-
Verify the application is binding to the correct interface:
lsof -i :5000
-
Test local connectivity:
curl http://10.x.x.x:5000
To have your Flask application start when your Mac boots:
- Create a launch agent in
~/Library/LaunchAgents/com.yourusername.flaskapp.plist
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.yourusername.flaskapp</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/python3</string>
<string>/path/to/your/app.py</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardErrorPath</key>
<string>/tmp/flaskapp.err</string>
<key>StandardOutPath</key>
<string>/tmp/flaskapp.out</string>
</dict>
</plist>
- Load the launch agent:
launchctl load ~/Library/LaunchAgents/com.yourusername.flaskapp.plist
For better security, consider using environment variables:
import os
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello, World!"
if __name__ == '__main__':
# Get values from environment or use defaults
host = os.environ.get('FLASK_HOST', '10.x.x.x')
port = int(os.environ.get('FLASK_PORT', 5000))
debug = os.environ.get('FLASK_DEBUG', 'False').lower() == 'true'
app.run(host=host, port=port, debug=debug)
Then run with:
FLASK_HOST=10.x.x.x FLASK_PORT=5000 FLASK_DEBUG=True python app.py