Documentation > Installation > Setup on Heroku

Setup on Heroku

Heroku is a Platform-as-a-Service cloud vendor that allows to run applications in so-called Dynos, which are like glorified OS containers.

Application Setup

Crossbar.io can be run on Heroku. Here we describe what you need to do. This walkthrough assumes that you have created an account on Heroku and have installed the Heroku tool belt.

To sign up for a free Heroku account go here.

Once you've created an account install the Heroku toolbelt. You can find the tool belt here.

Heroku also has very thorough walkthroughs for creating apps using a variety of languages.

Installing a Crossbar.io project on Heroku is pretty straightforward once you're familiar with the above but here is a step by step guide in case you need some extra guidance.

  1. Create project folder
  2. Create virtual environment (Optional but strongly recommended): You can find out more about virtual environments here to create a virtual environment:
    1. Install virtual env: If you haven't already, install virtualenv through pip: pip install virtualenv
    2. Go to your project: Open a terminal window and navigate to your project folder: cd my_project
    3. Create the virtual environment: virtualenv venv
    4. Activate the virtual environment: source venv/bin/activate
  3. Install Crossbar: pip install crossbar
  4. Create project (hello:python template): crossbar init --template hello:python
  5. Freeze requirements: Create a requirements file so that Heroku knows what to install for your project: pip freeze > requirements.txt
  6. Create Procfile: Heroku uses a Procfile to determine what commands to use to start your app: echo "web: crossbar start" > Procfile
  7. Modify Config file: Heroku uses a dynamic urls and ports so you'll need to use config file like the one described in the Crossbar.io configuration below (or copy the one below). You can find your config file in the .crossbar directory of your project folder (assuming you followed the steps above)
  8. Create git repo: You deploy to Heroku via Git. If you don't have Git installed you can find out how to do so here. To create a git repository:
    1. cd my_project_path
    2. git init
    3. git add .
    4. git commit -m "Initial commit"
  9. Create the app on Heroku: Now you should be all set to create an instance of the app: heroku create (NOTE: check the output of this command, on the second line it will tell you the URL of your app - it should be something like random-heroku-assigned-name.herokuapp.com. You can also find it through your account page on Heroku)
  10. Deploy: to deploy and start the app you push it using Git and Heroku should take care of the rest: git push heroku master
  11. You can check the logs of your application once it's deployed by using the logs command: heroku logs --tail
  12. Point your browser to the address that Heroku assigned to your app and you should see the Hello WAMP! page (see the hello:python template for more information). (NOTE: Use http instead of https to access the page.)

Crossbar.io configuration

Crossbar.io can create a complete node configuration and "Hello, world". Here is how you would create a Python based "Hello, world" application:

crossbar init --template hello:python

The configuration generated will make Crossbar.io listen on the fixed port 8080 for incoming Web and WebSocket connections.

However, Heroku does not allow to expose fixed ports from Dynos to the outside world, but routes HTTP (and WebSocket) request coming in from the Internet via a Heroku frontend load-balancer to Dynos - to a dynamically assigned port. Read more here.

When a Dyno starts, the Dyno will get assigned an externally visible port, and inside the Dyno, the environment variable PORT will allow you to access the assigned port number.

Because of this, we need to modify the Crossbar.io node configuration:

  1. In the Web transport, insted of 8080, we configure the value "$PORT". This will make Crossbar.io read the value dynamically upon startup from the environment variable.
  2. Since the main transport is now listening on a dynamic port, we start a second (WebSocket) transport on our router on fixed port 9000 for the container worker to connect to

Here is a complete, working configuration:

{
    "controller": {
    },
    "workers": [
       {
          "type": "router",
          "options": {
             "pythonpath": [".."]
          },
          "realms": [
             {
                "name": "realm1",
                "roles": [
                   {
                      "name": "anonymous",
                      "permissions": [
                         {
                            "uri": "*",
                            "allow": {
                               "call": true,
                               "register": true,
                               "publish": true,
                               "subscribe": true
                            }
                         }
                      ]
                   }
                ]
             }
          ],
          "transports": [
             {
                "type": "websocket",
                "endpoint": {
                   "type": "tcp",
                   "port": 9000
                }
             },
             {
                "type": "web",
                "endpoint": {
                   "type": "tcp",
                   "port": "$PORT"
                },
                "paths": {
                   "/": {
                      "type": "static",
                      "directory": "../hello/web"
                   },
                   "ws": {
                      "type": "websocket"
                   }
                }
             }
          ]
       },
       {
          "type": "container",
          "options": {
             "pythonpath": [".."]
          },
           "components": [
             {
                "type": "class",
                "classname": "hello.hello.AppSession",
                "realm": "realm1",
                "transport": {
                   "type": "websocket",
                   "url": "ws://127.0.0.1:9000",
                   "endpoint": {
                      "type": "tcp",
                      "host": "127.0.0.1",
                      "port": 9000
                  }
                }
             }
          ]
       }
    ]
}