4

As I understand from other questions on SE, it is not possible to use multiple ports in a Heroku app as Heroku assigns a port with an environment variable.

Is there a recommended way of getting around this? I've seen some use a proxy module with subdomains:

Heroku + node.js: I have a server which uses multiple ports. How can I get Heroku to allocate them?

However, in this post:

How to create a subsubdomain for an app on heroku: (e.g. sub.myapp.herokuapp.com)

it indicates that subdomains are no longer possible in heroku.

In my application, I'm currently serving up my content with express and have a websocket server for synchronizing some real time content, both requiring a port. My question is, are subdomains possible in heroku and what is the recommended way to serve a web app that requires multiple ports?

Community
  • 1
  • 1
Flaminator
  • 564
  • 6
  • 17

2 Answers2

4

So, to answer your questions:

You cannot have a single application that runs on multiple ports on a single Heroku dyno.

You CAN, however, have multiple Heroku dynos running, and each one running different commands. This allows you to run different 'types' of servers on Heroku within the same project. The way you do this is by specifying how to run your different types of servers in your Procfile, for instance:

web: node server.js
other-web: node other-server.js

To run one instance of server.js, and one instance of other-server.js, you could simply tell Heroku to run those processes as dynos, like so:

$ heroku ps:scale web=1 other-web=1

Now -- in regards to websockets, Heroku supports them natively, as of a couple years ago (you can read more about this here: https://devcenter.heroku.com/articles/websockets). This means you can use native websocket applications on Heroku by following typical websocket patterns.

In the documentation I just linked you to, there's an example Node app -- it also outlines how it works, specifically.

Finally -- regarding subdomains -- the other Stack Overflow post you linked to is no longer accurate. Heroku added support for wildcard domains (usually for multi-tenancy purposes) a long time ago.

This means that if you're building an application where you want to dynamically serve pages to a user based on subdomains: you're in luck! This is fully supported. You can do it by saying:

$ heroku domains:add *.example.com

When you update your DNS to point to the wildcard, you should start seeing all subdomain requests come into your Heroku app.

To learn more about the Heroku + subdomain stuff, they have an excellent article about it here: https://devcenter.heroku.com/articles/custom-domains#add-a-wildcard-domain

rdegges
  • 32,786
  • 20
  • 85
  • 109
  • Nice solution. I ended up finding a way to refactor to use both websockets and http on the same port (see my answer below), but am marking this one as the correct one since the question was about how to do it for multiple ports and this does solve that. – Flaminator Jan 21 '17 at 22:26
  • 1
    While you can have multiple dynos listed in your Profile, only `web` will take inbound http requests. See https://devcenter.heroku.com/articles/http-routing (This may be different for Private Spaces) – seph Aug 12 '20 at 04:41
1

I ended up finding that you can actually use the same port for both the websocket and the http. Using socket.io for example, you just need to do the following...

var SocketIO = require('socket.io');
var express = require('express');

var app = express();

// Put your middleware and routes here...

const server = app.listen(port, function(err){
      console.log("Express server running on port:" + port);
});

var io = SocketIO(server);

Since the return value when doing app.listen is the server, you can actually just pass this right into socketIO. From there you can do io.on(...) etc.

Flaminator
  • 564
  • 6
  • 17