js:void(0);

Setting up a self-hosted Deepstream auth service

• deepstream

Lately, I’ve been playing with deepstream.io@3.1.1 making a realtime game engine (read: wrapper) on top of it. This has provided me with an innumerable amount of challenges. One of them, today, was trying to set up an authentication service for my self hosted Deepstream instance. Reason being, I’m transitioning away from DSHub, because my needs will not scale with their plans. So, I took the plunge and worked on setting up the basics to get my small project working again.

So, to do that, I needed token auth (at least, something to test with) and anonymous auth.

Deepstream provides identifiers for each client and provider that connects, which you can get via data.id after a successful login. For some reason, I was not getting my own back from my auth service. As it turns out, you need to set a username AND send the id back in the clientData section. The current docs don’t explain this super well.

Here is my resulting service, maybe it can help someone else struggling with this problem:

const express = require('express');
const bodyParser = require('body-parser');
const app = express();

const uuid = require('uuid/v4');

app.use(bodyParser.json());

const ONLY_VALID_TOKEN = 'adKTi3fEg99ZeOsgRIaVJr8D9fZq0XNT';

app.post('/local-deepstream-auth', (req, res) => {
  const { authData } = req.body;

  const generatedId = uuid();

  if(authData && authData.token) {
    if (authData.token === ONLY_VALID_TOKEN) {
      res.json({
        username: generatedId,
        clientData: { id: generatedId },
        serverData: { hasAuthority: true }
      });

      return;
    }

    res.status(403).send('Invalid token');
    return;
  }

  res.json({
    username: generatedId,
    clientData: { id: generatedId },
    serverData: {}
  });
});

app.listen(3871, () => console.log('Local Deepstream Auth running on 3871.'));

Moving To Scaleway (From Any NodeJS PaaS)

• server, and dokku

Or, really, any PaaS, but my examples will use JS.

There are a lot of NodeJS PaaS’ that I’ve worked with previously - I really wanted to take the headache out of managing my own infrastructure. They provide headaches of their own, though. What if:

Sure, you can contact support and hope it gets fixed. And to their credit, some of these providers have fantastic and nearly immediate support. But after you put up with these issues periodically for a while, you get fed up. I got fed up.

A few months ago, someone put a bug in my ear for Scaleway. I dismissed it because I didn’t want to manage my own infrastructure. Nevertheless, I kept my ears open at projects like Dokku for when things would inevitably get out of control. Today, I decided to take a leap and finally move away from my provider and host my project myself. It only took an hour.

Before I talk about how I did it, let me give you a table comparing specs that shows why Scaleway was such a good choice (I wanted LetsEncrypt support, and MongoDB was a bonus):

Provider Cost (per month) CPU RAM LetsEncrypt Included MongoDB
Scaleway €2.99 2 CPU 2GB RAM no no
Scaleway €11.99 4 CPU 8GB RAM no no
Heroku $7 / Dyno (Hobby) ??? 512MB RAM no no
Heroku $25 / Dyno (Standard) ??? 512MB RAM no no
Clever Cloud €4.50 1 CPU 256MB RAM no no
Clever Cloud €14.40 1 CPU 1GB RAM no no
evennode €6 ??? 512MB RAM yes yes
evennode €13 ??? 768MB RAM yes yes

I mean, from this, I was willing to accept lower performance to have an included MongoDB and have LetsEncrypt taken care of. It made sense in my mind. However, looking strictly at the numbers, Scaleways lowest tier provides an immense amount of value.

So, lets talk about how easy it was to get my project off of a provider, and onto Dokku.

After purchasing a Scaleway server, you can create a server and spec it out however you want. For me, the defaults were more than sufficient, and I ended up going with a tier inbetween the one I posted above (4 cores, 4GB RAM), so I named my server and within a minute or two it was ready. You’ll want to be familiar with the command line, and ideally have an SSH key ready to give to Scaleway so you can actually get into your server, too.

Once you’re into your server, it’s time to set up Dokku. It’s two commands:

wget https://raw.githubusercontent.com/dokku/dokku/v0.10.5/bootstrap.sh
sudo DOKKU_TAG=v0.10.5 bash bootstrap.sh

Easy peasy. After it’s done, head over to the IP for your server and click confirm to finish setup.

Next, lets add your project. Mine is called landoftherair and I have a server for it at server.rair.land, so keep that in mind when you see these commands:

dokku apps:create landoftherair
dokku config:set landoftherair MONGODB_URI mongodb://myserver.mlab.com # Hosted on mLab
dokku config:set landoftherair ... # the rest of your environment variables

Now lets get the app running. What I did next was went into my Google Domains DNS panel and created an A record pointing to my server IP for server (this ultimately makes server.rair.land point to my scaleway server).

Next, I went into my project and created a dokku remote, pushed to it, and let it deploy the app:

git remote add dokku dokku@server.rair.land:landoftherair
git push dokku master

Afterwards, I set up LetsEncrypt with a few more commands:

sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
dokku config:set --no-restart landoftherair DOKKU_LETSENCRYPT_EMAIL=kyle@seiyria.com
dokku domains:add landoftherair server.rair.land
dokku letsencrypt landoftherair
dokku letsencrypt:cron-job --add

And that’s it. Now my project is running on a custom server running Dokku, with a renewable LetsEncrypt SSL cert.

730 Days of Github

• life,, javascript,, and github

Today marks 2 years of my doing “one thing a day” on Github.

contribution graph

I’ve got work to do today, but I wanted to blog first, so today appears empty

I posted about last year, and now I’m posting about this year! I’m not going to do monthly graphs or anything this time around, but I’ll talk about a bunch of projects that I worked on. I’ll split it between my own projects, and other projects. Here are my projects (or projects I’m affiliated with):

Reactive Retro: Proof of Concept

• reactive-retro

Hey folks!

So I have a proof of concept build for Reactive Retro ready. What is Reactive Retro, you say? Well, it’s a location-based game that aims to be like an older JRPG, with a focus on cooperative play. Right now, there isn’t a whole lot though.

365 Days of GitHub

• javascript,, github,, and life

So, today marks my 365th day of GitHub contributions. I started last year on June 25th, and today is June 24th. I’d like to talk about what I did, and why I did it. Maybe some tidbits about discipline, too.

Code Quality and You

• javascript, and quality

Welcome! Today I’d like to talk about another subject which can’t be emphasized enough: Code Quality. This entails a lot of tools and patterns that ultimately come together to make your game more solid and programmer friendly. Even if you’re working alone on a project, these tools can save you some precious debugging time by pointing out simple errors, if not more complex ones. I’ll be using my current project, c as an example where possible.

Common Pitfalls in JS-based Games

• javascript, and incremental

Welcome! You might be reading this out of curiosity, or because you want to improve your programming capabilities to stop people from exploiting your JS games. Given that the first thing I do when I open a new incremental is open the terminal and start messing around with your games, I figured it’s about time to write something about what I see and how I break your games. Consequently, I’ll describe ways you can protect your games from the basic code manipulations I perform. Some might say “you’re just ruining the game for yourself!” while I’m going to turn around and say “I don’t care” – that’s not the point of this!

NB: This will only apply to vanilla JS applications, which I see more commonly. Frameworks like AngularJS and such are out of scope for this post. Advanced techniques such as using a debugger, while slightly more on topic, will also be disregarded for now.