Desktop Games in Browsers

I used to spend some time with Apache Guacamole before. Basically, it is a remote desktop viewer in your browser. In other words, you don't need to install a VNC client to view your remote desktop.

I had this idea to create a game streaming service when Cuphead came out, so that people could:

  1. Play the game in their browser, on operating systems that the game does not support: OSX, ChromeOS, etc.
  2. Share one copy of the game without buying many copies from Steam.
  3. Have their progresses saved independently, i.e. to have multiple game copies.

I installed guacamole server on a Windows VM on AWS last time, so I still have the procedure to do that. But since we are playing with Docker, why not try that? Maybe it is simpler.

It is well-known that Docker has trouble with X GUI application. But some great folks had figured it out. Let's use a docker-compose file find here.

As a comment, the architecuture of guacamole can be confusing. But basically you install guacd on the remote host; you install guacamole client (act as the frontend) on any machine that can access the remote host(itself included), which listens on 8080 to handle connection from browsers. Here with Docker, we install both on remote host as docker containers.

Visit http://docker:8080/guacamole/ shows the login screen for guacamole, use the default admin password and we are in!


Unfortunately, I tried to create new VNC connection but the server crashed and I can no longer login, even after re-creating Docker images. I tried to fix this with no luck. After a long time, I figured out that there's a persistent volume that keeps config. I removed it by: docker-compose rm, docker volume rm guacamole_data.

So I turned to another compose file. The plus side is that this also launches a seperate vnc server. Doesn't work either. But I tried the rdp container and it works well.

So I composed my own docker-compose file by combining the two:

version: '3'

services:
  db:
    hostname: db
    build:
      context: .
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}

  guacd:
    hostname: guacd
    image: guacamole/guacd:0.9.12-incubating
    restart: always
    links:
      - rdp

  guacamole:
    image: guacamole/guacamole:0.9.12-incubating
    restart: always
    ports:
      - 8080:8080
    links:
      - guacd
      - db
    environment:
      GUACD_HOSTNAME: guacd
      MYSQL_HOSTNAME: db
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}

  rdp:
    image: dohsimpson/rdp-game

After deploying. I logged on the web UI of guacamole. I add two new users: u1 and u2. Their password is both 123.

Then I created 2 new rdp connection called rdp1 and rdp2, giving access for each user to one of them, The connections point to the ip of the rdp container, which I found with docker inspect. I also set the initial program of rdp to /usr/games/doom, so that the user would be taken to the game directly.

Here's the result. Left is u1 and right is u2. They are playing their own games without interfering with each other, except the saving feature, they save to the same save file.

Finally, The game is really low on frames, but I proved my point. Mission accomplished! There goes 5 hours of my day again.

Guacamole Doom game available here: http://project.enting.org:8080/guacamole/. Login info see above.

Lesson learned

  • There are so many Dockerfiles on the web, but so many of them are broken or poorly written, for this and that reason. So I guess docker is overpromised on its immutability. For example, if you run docker build on someone else's Dockerfile, you might fail or get a totally different image because a package has been updated.