12

Have you managed to make your node + nginx proxy setup on Heroku work?

Could you, please, tell me how have your organized the directories structure and the files in each directory before doing "git push heroku master"? Which buildpack did you use?

I am getting the message "Push rejected, no Cedar-supported app detected" every time I do "git push heroku master". I have put a "nginx.conf.erb" file in a "/conf" directory.

Thank you.

verybadalloc
  • 5,768
  • 2
  • 33
  • 49
T900M
  • 149
  • 2
  • 5
  • I guess because Heroku doesn't allow you to install nginx proxy etc. Heroku provides a web server and a cache you can provision as add-on. – stiebitzhofer Aug 21 '13 at 14:11
  • If you just want a proxy, in place of nginx you can use substacks bouncy or nodejitsus http proxy – jpillora Aug 23 '13 at 16:20

3 Answers3

12

I have used a Node.js + NGINX setup on heroku for many projects. This way, you can have nginx handle serving static files, caching, proxying to other servers, and proxying to several node processes.

Use the multi-buildpack buildpack (https://github.com/ddollar/heroku-buildpack-multi).
It allows you to specify a .buildpacks file which refers to several buildpacks. In my .buildpacks file, I use the default Heroku Node buildpack, and a fork of an nginx buildpack that I rebuilt to include SSL support.

https://github.com/theoephraim/nginx-buildpack.git
https://github.com/heroku/heroku-buildpack-nodejs.git

The nginx buildpack uses a nginx.conf.erb file that can reference ENV vars. You must tell it to listen on the port specified by heroku in the environment variable called "PORT"

listen <%= ENV["PORT"] %>;

Then you have your node server start up on whatever port you choose, say 5001, and in your nginx config, you can set up a proxy pass to your node app:

location / {
  proxy_pass      http://127.0.0.1:5001;
}

Note - your procfile needs to use a special start-nginx command (part of the nginx buildpack) that then calls whatever else you pass it. In my case I use forever to run my node app:

web: bin/start-nginx ./node_modules/.bin/forever app.js

And within your main node file, you must create a file when it has started up successfully to signal to the nginx buildpack that it should begin listening

fs.openSync('/tmp/app-initialized', 'w');

There is a full explanation of how to use the nginx buildpack in the readme @ https://github.com/theoephraim/nginx-buildpack

theozero
  • 592
  • 5
  • 8
  • 1
    How are you able to create another node app running on port 5000? From what I am experiencing you can only use one port and that is the ENV default one. Please advise me how to do this if this is not the case. Thanks. – droid-zilla Nov 06 '15 at 05:14
  • 1
    You could start several "apps" running on whatever ports you want. The key is that Heroku will only pass http traffic through on a single port of their choosing (set as the PORT env var). So if you wanted to expose multiple apps to the web, you would need to use the nginx proxy that is listening on that port to pass traffic through to node apps. – theozero Nov 13 '15 at 22:34
  • On Heroku, you cannot specifiy a specific port in my experience for me the following works: upstream node_entry { server unix:/tmp/nginx.socket fail_timeout=0; } server { listen <%= ENV['PORT'] %>; server_name localhost; keepalive_timeout 5; location / { [other settings…] proxy_pass http://node_entry; } } Then you can connect with: Server.listen(‘/tmp/nginx.socket’); – droid-zilla Nov 14 '15 at 19:37
  • Your answer helped me but I'm stuck somewhere else. Would be very nice from you if you had a look: http://stackoverflow.com/questions/42787420/heroku-node-parse-server-nginx-not-working – Laurent Meyer Mar 14 '17 at 13:36
2

On Heroku, this setup is used in production by me successfully once the buildpack is installed:

upstream node_entry {
    server unix:/tmp/nginx.socket fail_timeout=0;
}
server {
    listen  <%= ENV['PORT'] %>;
    server_name localhost;
    keepalive_timeout 5;
    location / {
        [other settings…]
        proxy_pass http://node_entry;
    }
}

Then, in your app.js file you can connect with:

Server.listen(‘/tmp/nginx.socket’);
droid-zilla
  • 536
  • 7
  • 8
  • didn't work for me. got `buildpack=nginx at=exit process=nginx` then `State changed from starting to crashed`. – paradite Jan 11 '17 at 07:51
  • @paradite Can you post your node code? It will work :-) – droid-zilla Jan 12 '17 at 17:38
  • @droid-zilla - would you mind posting your git repository if possible? I want to setup a reverse proxy so my client proxies calls to the api which is on a different heroku dyno/server/url. Or if you know of an example I could check out? Thanks – Spencer Bigum May 23 '17 at 02:28
0

This article contains instructions on setting up nginx as a proxy on Heroku, in conjunction with OpenResty, Lua, and LuaRocks. node.js isn't mentioned. It uses this buildpack. Haven't tried it myself but seems someone has got it working.

Josh Diehl
  • 2,913
  • 2
  • 31
  • 43