UPDATE: Apparently, there was not an issue with the ports. I was able to rebind the ports and serve my application on port 80 but I did not solve the issue. The problem is that my app is actually not being deployed correctly on Heroku. This is what is shown through the Heroku build logs:
ORIGINAL QUESTION: I have an issue trying to set up my Flask application on Heroku. I want to have the Flask server running on port 5000, and put up an Nginx proxy to serve traffic from port 80 to port 5000 so that I can still access the webpage from Heroku (which by default serves traffic on port 80).
Currently I have added the heroku-buildpack-runit and heroku-buildpack-nginx to my Heroku configuration, but I'm not sure how to start Nginx correctly to do what I want. My Procfile looks like:
web: bin/start-nginx gunicorn app:app
This is not doing what I would like it to do. In fact, I'm not certain if it is doing anything really at all.
Note, gunicorn is what I am using to start up my Flask app.
Any ideas?
On Heroku you don't get to pick the port you use. You must use the port Heroku assigns to you via the PORT
environment variable. You also don't need Nginx to run Flask. Simply use gunicorn
or another WSGI web server.
From the documentation (emphasis added):
Web servers
Outside of Heroku, web apps are sometimes executed inside a web server container. For example, PHP apps might run as a module inside Apache HTTPD, or Java apps might run inside Tomcat.
On Heroku, apps are completely self-contained and do not rely on runtime injection of a webserver into the execution environment to create a web-facing service. Each web process simply binds to a port, and listens for requests coming in on that port. The port to bind to is assigned by Heroku as the
PORT
environment variable.This is typically implemented by using dependency declaration to add a webserver library to the app, such as Tornado for Python, Unicorn for Ruby, or Jetty for Java and other JVM-based languages. This happens entirely in user space, that is, within the app’s code. The contract with Heroku is for the process to bind to a port to serve requests. Heroku’s routers are then responsible for directing HTTP requests to the process on the right port.
One easy way to use the environment variable if it exists is to do something like this:
import os
# Set up your Flask app here
port = os.getenv('PORT', default='5000')
app.run('0.0.0.0', port=port)
It looks like you're already using gunicorn
, which is great. Your Procfile
should contain something like this:
web: gunicorn my_project.wsgi
where my_project.wsgi
is the name of your WSGI file.