A self-hosted rabb.it clone using docker forked from bunny by SimplyLin
Features
- Control a virtual stateless firefox browser served via docker container
- Create user accounts and rooms
- Voice and video chat over p2p, text chat over not p2p
For now this document only covers deploying using AWS EC2 and deploying locally.
Note that this is a work-in-progress and the documentation in this readme is not complete. In fact, if you're an expert on AWS EC2 and can help me out I'd appreciate it
See the wiki page on running locally
You receive 750 free hours of EC2 permonth for 12 months which is more than enough to run this project for a few friends. The exact cost of self-hosting on AWS is still to be determined.
There may be extra work/different charges in deploying to a different cloud based service.
Running the container locally is covered further down.
If you don't already have a aws account sign up for one here
Create a new IAM user on the aws dashboard here. You can find more details on that here.
When prompted for the group, for now make sure the group has full access to EC2.
If you're lazy like me you can simply select AdministratorAccess
to give your user full access to everything.
Once you're at the success screen, take note of the Access Key ID and Secret Access Key.
If you don't already have the aws-cli
, install it here
p.s. the easiest way to install it is probably
pip install awscli
Now run the following line and follow the onscreen instructions. It will ask for the Access Key ID and Secret Access Key you (hopefully) took note of earlier.
aws configure
I would reccomend you use your closest region from this-list.
These steps assume you intend to host the server and web client on aws. For this tutorial, only the virtual browser is required to be hosted on AWS.
Use aws ecr create-repository
to create a private docker repository for the server, client, and virtual browser.
aws ecr create-repository --repository-name turtus/server
aws ecr create-repository --repository-name turtus/web
aws ecr create-repository --repository-name tutus/vb
For each command take note of the repositoryUri
field in the output.
Each repository will be located at [account-id].dkr.ecr.[region].amazonaws.com/[repo-name]
Next log in to your registry using aws get-login
like so:
aws get-login
Please read the example.env
located at the root of the project.
Make sure to pay attention to these variables in particular.
TURTUS_VB_DEFAULT_SIGNAL_SERVER
The
TURTUS_WEB_DEFAULT_SIGNAL_SERVER
... TO BE CONTINUED
First I would reccomend following the instructions for getting the project to run locally. It essentially boils down to setting up the dotenv file then building the virtual-browser docker image.
Once that's done start the development servers for both the server and web client. You can do that by opening two separate terminal windows.
First, inside services/server
:
yarn dev
Then, inside services/web
:
yarn dev
The Virtual Browser is a docker container based on a dockernode image that manages a bunch of processes with the help of a not too complicated node script (bc js is cool).
Those important processes are as follows:
- dbus
- Controls inter process communication.
- This is a dependancy of some of the following processes.
- Xvfb
- Virtual Frame Buffer that implements X11 protocol.
- Basically alows us to run graphical applications without an actual display attached
- xdotool
- What allows
- pulseaudio
- A general purpose sound server.
- Used to capture sound output from the container.
- ffmpeg
- Records video and sound from
- firefox-esr
- The web browser itself.
- Launched fullscreen and installed with ublock-origin (as soon as I figure out how)
The VirtualBrowser is intended to be launched dynamically from a script (i.e. the backend).
The container can be launched using a few arguments.
-s, --signal-server <url>
- The url to the signal server. See server sections for more details.
-t, --timeout <ms>
- Not yet implemented
- The amount of time in ms the browser will wait after the last peer has disconnected before automatically shutting down.
- Defaults to
60000
(1 minute)
After launching the Virtual Browser and establishing the source for the media stream, a wrtc connection is made through the signalling server specifiec using the -s
option.
Whenever a peer connects they receive a copy of the stream via p2p and webrtc.
The Virtual Browser can be shut down either by the client asking it nicely (i.e. sending a shutdown message) or by timing out due to a lack of peers as described above or by the signaling server itself shutting down.
The backend performs webrtc handshake negotiation and serves an api that is used to manage users and rooms. Unlike a traditional application the backend does not serve the web client. Why? Because I read an article on microservices once.
The backend is served over https only because Chrome requires a secure connection for webrtc. This means when developing locally you are required to have a certificate. You can use the one provided in the repository and simply accept the SSL error by navigating to
For mac/linux there is a script /gen_cert.sh
that you can run that will generate the cert and key, localhost.cert
and localhost.key
respectively. Double click on the .cert
file to add it to your keychain / trusted ca.
Windows users....use git bash or bash on windows.
Note: On mac you might have to go a bit futher by right clicking the certificate you just added to the keychain, click "get info", expand the "Trust" dropdown, then set "When using this certificate" to "Always Trust".
Start server with:
yarn dev
Test the server is online with curl:
curl -k https://localhost/
# Returns the time the server received the request
For now there is only one client application: a responsive web application that connects to the virtual browser over p2p.
The app is built using React.
They can convey meaning quickly without having to read. Here's a quick dictionary:
- 🙂Success
- 🤔Info / Warning
- 👎Non-Fatal Error
- ☠️Fatal Error
p2p connections are negotiated over the signal server and work as follows:
- A client connects to the signal server via websocket url
- The signal server sends the client an
identity
packet
- This packet will be attached to every outgoing message.
- One or more clients subsequently connect to the websocket url
- The server negotiates the handshake between existing clients and the new client
- All old clients ask the new client to identify their client type
- If the client type is
vb
then a client must specifically ask for the stream by providing arequest.stream
packet. - Otherwise the client is automatically sent the stream.
Break monolith app into microservices
Deploy Node.js application to AWS
Making and trusting your own certificates