Deploying to Heroku

This guide describes how to deploy a websockets server to Heroku. We’re going to deploy a very simple app. The process would be identical for a more realistic app.

Create application

Deploying to Heroku requires a git repository. Let’s initialize one:

$ mkdir websockets-echo
$ cd websockets-echo
$ git init .
Initialized empty Git repository in websockets-echo/.git/
$ git commit --allow-empty -m "Initial commit."
[master (root-commit) 1e7947d] Initial commit.

Follow the set-up instructions to install the Heroku CLI and to log in, if you haven’t done that yet.

Then, create a Heroku app — if you follow these instructions step-by-step, you’ll have to pick a different name because I’m already using websockets-echo on Heroku:

$ $ heroku create websockets-echo
Creating ⬢ websockets-echo... done
https://websockets-echo.herokuapp.com/ | https://git.heroku.com/websockets-echo.git

Here’s the implementation of the app, an echo server. Save it in a file called app.py:

#!/usr/bin/env python

import asyncio
import os

import websockets

async def echo(websocket, path):
    async for message in websocket:
        await websocket.send(message)

start_server = websockets.serve(echo, "", int(os.environ["PORT"]))

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

The server relies on the $PORT environment variable to tell on which port it will listen, according to Heroku’s conventions.

Configure deployment

In order to build the app, Heroku needs to know that it depends on websockets. Create a requirements.txt file containing this line:

websockets

Heroku also needs to know how to run the app. Create a Procfile with this content:

web: python app.py

Confirm that you created the correct files and commit them to git:

$ ls
Procfile         app.py           requirements.txt
$ git add .
$ git commit -m "Deploy echo server to Heroku."
[master 8418c62] Deploy echo server to Heroku.
 3 files changed, 19 insertions(+)
 create mode 100644 Procfile
 create mode 100644 app.py
 create mode 100644 requirements.txt

Deploy

Our app is ready. Let’s deploy it!

$ git push heroku master

... lots of output...

remote: -----> Launching...
remote:        Released v3
remote:        https://websockets-echo.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/websockets-echo.git
 * [new branch]      master -> master

Validate deployment

Of course we’d like to confirm that our application is running as expected!

Since it’s a WebSocket server, we need a WebSocket client, such as the interactive client that comes with websockets.

If you’re currently building a websockets server, perhaps you’re already in a virtualenv where websockets is installed. If not, you can install it in a new virtualenv as follows:

$ python -m venv websockets-client
$ . websockets-client/bin/activate
$ pip install websockets

Connect the interactive client — using the name of your Heroku app instead of websockets-echo:

$ python -m websockets wss://websockets-echo.herokuapp.com/
Connected to wss://websockets-echo.herokuapp.com/.
>

Great! Our app is running!

In this example, I used a secure connection (wss://). It worked because Heroku served a valid TLS certificate for websockets-echo.herokuapp.com. An insecure connection (ws://) would also work.

Once you’re connected, you can send any message and the server will echo it, then press Ctrl-D to terminate the connection:

> Hello!
< Hello!
Connection closed: code = 1000 (OK), no reason.