This article walks you through one way of setting up a Community Edition instance. For this guide, we are using Kubernetes on Google Cloud with our DNS and SMTP services on AWS. This guide is perfect for those familiar with the Hubs Cloud looking to get started quickly.
Introduction
In this step-by-step guide, you will learn how to quickly deploy an instance of Hubs Community Edition on Google Cloud using AWS's Route53 and Simple Email Service (SES). This guide is perfect for Hubs Cloud customers who are familiar with navigating AWS services and interested in learning about how to host Hubs on a new platform like Google Cloud.
To begin, it is important to understand some basic information about the technology that makes up Community Edition, Kubernetes, and how they work together. If you are already familiar with this information, you may skip ahead to the start of the tutorial at the subheading "Deployment Prerequisites".
Understanding the Hubs Community Edition Infrastructure
The product known as "Mozilla Hubs" is composed of several powerful pieces of software. For example, when you visit a Hub with your Web browser, you are interacting with the Hubs Client.
The Hubs Client itself interacts with several other pieces of software, such as:
- Reticulum | Hubs' networking and API server
- Dialog | Hubs' WebRTC voice and video communication server
The Hubs Client, Dialog, and Reticulum are just three components of a larger stack of software. Each of this stack's components are individually configured and networked to other components to make Hubs work properly.
Hubs Community Edition eliminates the need for developers to download, install, configure, connect, and update each of the stack's components individually. Community Edition simplifies and automates most of that complex deployment process using software called Kubernetes, which is a containerized software orchestration system.
An Introduction to Containerized Software
Consider the Web browser you are using right now to read this article:
- Unless that browser was installed onto your device from the factory, you first had to download a version of your browser that corresponds to your device's operating system.
- Next, you installed the browser, perhaps specifying a directory into which its application files were placed.
- After that, you opened the browser and may have signed into a Firefox account or a Google account.
- Then, you may have installed an ad blocker extension or a password manager.
- Finally, you might have navigated to a website and added it to your favorites bar...
Imagine if you could package up the complete state of your Web browser installation -- including its configuration settings, logged-in accounts, extensions, browser history, favorites, and more -- and make use of that package on any other computer, regardless of operating system.
Similarly, imagine if you could package up the complete state of any application -- its dependencies, libraries, configuration files, and application code -- and run that package on any other computer.
This is possible using open-source software called Docker. A Docker Container is a process executed on a computer running its own packaged and configured software. You can learn more about Docker and Docker Containers here on the official docs.
Other examples of popular software that is packed as a Docker Container include:
βWordpress | The blogging website system
βNextcloud | A suite of content collaboration software
βUbuntu | The entire Linux distribution
Many components of Hubs Community Edition run inside separate Docker Containers. By themselves, these containers don't know much about one another. If you were to run a Reticulum container on your computer without also running a Dialog container, anyone who connected to your Hub would be able to see each other, but not hear each other.
Therefore, we need a way for these containers to talk to each other. We need a way for people who connect to a Hub to also connect to that Hub's associated Dialog server. We also need a way to update the Dialog container's code without bringing down the Reticulum container. How do we coordinate all of these containers?
Kubernetes!
Kubernetes Introduction
Kubernetes, often shortened to "K8s", acts as an organizer for containerized software. A Kubernetes deployment, called a "cluster", consists of two parts:
- A control plane that is responsible for maintaining the state of the cluster as defined by an administrator/developer.
- Nodes, which are virtual or physical computers that run software defined by the control plane. Each node contains a set of one or more pods, which share storage and network resources. Each pod runs one or more containers.

To deploy software built using Kubernetes, a developer must supply a Kubernetes executable with a plain-text configuration file describing the cluster's pods, those pods' containers, the computing resources that a container needs to function, networking information, and more. This configuration file is called a deployment spec.
ret.prod.220712.200
of the Reticulum server on port 9100 and version dialog.prod.220303.63
of the Dialog server on port 4443."The control plane would ingest that configuration file and instruct its nodes to download and run that specific, containerized software.
Kubernetes clusters can be deployed on many types of computers, including:
- Your home desktop computer
- Two $35 Raspberry Pi Computers
- Computers owned by a cloud services provider, such as:
β- Google Kubernetes Engine
β- Amazon Elastic Kubernetes Service
β- Microsoft Azure Kubernetes Service
β- DigitalOcean Kubernetes
Community Edition's Containerized Services
Here is a rundown of each container that makes up Hubs Community Edition:
- Hubs | The Hubs Client for Web browsers.
- Spoke | A web-based content authorizing tool used to create custom 3D environments for Hubs.
- Reticulum | Hubs' networking and API server. This handles authorization, avatar positioning, object manipulation, and way more.
- Dialog | A WebRTC audio and video communication server. This contains a WebRTC Selective Forwarding Unit. For more information about how Hubs uses WebRTC, check out this resource.
- Coturn | A TURN and STUN server used for WebRTC communication. For more information about how Hubs uses WebRTC, check out this resource.
- Nearspark | A service used to generate thumbnails from images.
- Speelycaptor | A service used to convert video to a Hubs-compatible format. Uses ffmpeg.
- PgBouncer | A lightweight connection pooler for PostgreSQL. Rather than making new, expensive PostgreSQL database connections for every client or query, a connection pooler creates a long-lived group of connections to a database, and reuses those connections as necessary. This improves database access performance and availability.
- Photomnemonic | A service used to take screenshots of websites.
After deploying your own version of Community Edition, you will be able to see these containerized services running in their own individual pod. Now that all of those details are out of the way, let's get to the deployment tutorial!
Deployment Prerequisites
To successfully deploy Community Edition, certain prerequisites must be met. The requirements discussed below are tailored to this case study and do not precisely match those in the Communit Edition codebase. It is important to note that this tutorial was created using a 2021 M1 Macbook Pro running macOS Ventura 13.1 . The individual commands used to deploy Community Edition may depend on your device and operating system.
Part 1: Before getting started, we need to configure billing on our Amazon Web Services and Google Cloud Platform accounts. This guide does not go through the individual steps of setting up your account and billing information, but you can find more information about the setup process at the following links: AWS | GCP
Part 2: We will be using the following free, 3rd-party applications:
βA. VSCode | A code editor for us to configure and deploy Community Edition.
βB. Lens | An interface where we can inspect and manage our K8s cluster.
Part 3: We need to make sure our computer has the following software installed. We have included the commands that we ran for installation:
A. Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install --cask google-cloud-sdk
C. Kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl"
D. gettext
brew install gettext
Step 1: Configuring your DNS on AWS's Route53
TIf you have set up a Hubs Cloud instance on AWS, you will be familiar with the process of registering a domain on Route53. In fact, you may even have an existing domain that you wish to use for your Community Edition instance. However, unlike Hubs Cloud, you need only one registered domain in order to deploy Community Edition.
If you do not already own a domain that you plan to use for this deployment, you will need to purchase on on AWS Route53:
- Navigate to Route53 on the AWS console.
- Select the "Registered Domains" tab in the left-hand toolbar.
- Select the "Register Domain" button, search for your desired domain, and follow the checkout process to purchase your domain.
- Wait for a confirmation email indicating that your purchase was successful. You will also have to wait for the registration process to complete.
- Lastly, disable Transfer Lock on your domain. This can be done by selecting your domain in the "Registered Domains" tab and clicking the "disable" hyperlink next to "Transfer Lock".
Once we have registered our desired domain, we need to create four records...
- Navigate to the "Hosted Zones" tab in the left-hand toolbar and click on your domain.
- In the domain's details, you will select "Create Record" to create 4 A-records with placeholder values. Don't worry, we will update these later:
a. Record Name: {keep blank}
βRecord Type: A
βValue: 0.0.0.0 (placeholder)
b. Record Name: assets
βRecord Type: A
βValue: 0.0.0.0 (placeholder)
c. Record Name: stream
βRecord Type: A
βValue: 0.0.0.0 (placeholder)
d. Record Name: cors
βRecord Type: A
βValue: 0.0.0.0 (placeholder)
After this is complete, we have properly configured our domain for deployment. Once again, we will come back to update those placeholder record values later in the guide.
Step 2: Configuring your SMTP on AWS's Simple Email Service (SES)
Hubs relies on the ability to associate a user's email address with important account information, such as their Spoke scenes, rooms, avatars, and more. We will need to configure an Simple Mail Transfer Protocol service (SMTP) in order for our instance to send emails to users.
- Navigate to "Amazon Simple Email Service" in the AWS console.
- Select "SMTP settings" in the left-hand toolbar.
- Make note of your SMTP endpoint URL, this will be used later.
- Select the "Create SMTP credentials" button.
- (Optional) On the "Specify User Details" page, you may customize your assigned IAM user name.
- Verify that the following keys in "Permissions policy for user" have the corresponding values:
"Effect": "Allow"
"Action": "ses:SendRawEmail"
"Resource": "*" - Select "Create User".
- Download or copy the SMTP user name and SMTP password. These will be used when configuring the Community Edition deployment spec later in the guide.
Once this is complete, our email service is properly configured for deployment!
Step 3: Create Your Kubernetes Cluster using Google Cloud Kubernetes Engine
Next, we need to create a new Kubernetes cluster to hold our Community Edition containers. We can create this cluster using the command line with google-cloud-sdk installed:
- Log in to the google cloud sdk.
gcloud auth login
2. Check that you are working in the project where you would like to create your cluster. If you need to create a project, follow these steps.
gcloud config list
3. If you are not working in the correct project, run the following command to change to the correct project.
gcloud config set project <YOUR_PROJECT_ID>
4. Create your K8s cluster. We generally recommend assigning your cluster to the zone nearest to your intended user base. You can find more information on zones here.
gcloud container clusters create <YOUR_DESIRED_NAMESPACE> --zone=<YOUR_DESIRED_ZONE>
5. Wait for your cluster to be configured. This may take several minutes. When completed, you will receive confirmation and information about your cluster.
Created [https://container.googleapis.com/v1/projects/YOUR_PROJECT_ID/zones/YOUR_DESIRED_ZONE/clusters/YOUR_DESIRED_NAMESPACE].
Our K8s cluster is now ready to receive our deployment spec for Community Edition!
Step 4: Download, Configure, and Deploy Community Edition
The code that makes up Community Edition currently lives in this section of the Hubs Cloud GitHub repository. In order to deploy it to our K8s cluster, we must download the repository, edit the deployment scripts with information from our chosen services, and deploy the configuration files.
1. Clone the GitHub repository using the command line in VSCode.
git clone https://github.com/mozilla/hubs-cloud.git
2. Move into the community-edition directory.
cd community-edition
3. Editing render_hcce.sh
in VSCode, replace the following required parameters with your chosen services. You will also configure multiple secret passwords that you should save locally on your device:
βHUB_DOMAIN | Your domain from Route53.
βADM_EMAIL | The email address to be assigned admin privileges on creation.
βNamespace | The namespace to use within your Kubernetes cluster.
βDB_PASS | A secret password chosen by you.
βSMTP_SERVER | The SMTP endpoint URL from SES.
βSMTP_PORT | 25
βSMTP_USER | The SMTP user name from SES.
βSMTP_PASS | The SMTP password from SES.
βNODE_COOKIE | A secret password chosen by you.
βGUARDIAN_KEY | A secret password chosen by you.
βPHX_KEY | A secret password chosen by you.
4. (Optional) Editing render_hcce.sh
in VSCode, replace the SKETCHFAB_API_KEY and TENOR_API_KEY with credentials from these services. If you would not like to configure Sketchfab (for searching 3D models) or Tenor (for searching animated GIFs) you can simply leave these values as they are.
5. Once you have finished configuring the deployment script, run the following command to create the deployment spec and apply it to your cluster.
bash render_hcce.sh && kubectl apply -f hcce.yaml
6. Wait for the deployment to complete. This may take several minutes.
7. Verify the deployment with the following command. You should see 11 pods listed in the returned value.
kubectl get deployment -n NAMESPACE_WITHIN_CLUSTER
8. If you would like to look deeper, you can look into the details of each pod to make sure the intended values are present. We recommend verifying the information in the Reticulum pod.
kubectl describe deployment POD_NAME -n NAMESPACE_WITHIN_CLUSTER
render_hcce.sh
were edited from base64 <secret> -w 0
to base64 -i <secret>
in order to run on M1 macOS 13.1.Step 5: Expose Services
Before we can access our Community Edition instance, we need to point our domain to its automatically assigned external IP.
1. Get your instance's external IP address.
kubectl -n NAMESPACE_WITHIN_CLUSTER get svc lb
2. Navigate back to the "Hosted Zones" tab of AWS Route53 and select your domain.
3. Replace the placeholder values of all four A-records you created previously with your instance's external IP address. These should be:
β<HUB_DOMAIN>
βassets.<HUB_DOMAIN>
βstream.<HUB_DOMAIN>
βcors.<HUB_DOMAIN>
4. Save all records and wait a few minutes for the changes to propogate.
Step 6: Verify and Manage Your Instance with Lens
Once you have exposed your IP to your domain, you should now be able to begin using your Community Edition instance at its intended domain.
Connecting to your domain for the first time...
- Attempt to connect to your domain. Since we have not yet configured certificates for our Hub, we will need to 'self-sign' the certificates. Your Web browser will warn you when joining an domain without certificates and will provide you the option to view the page anyway. On Firefox, this is achieved by clicking "Advanced" and "Accept the Risk and Continue".
- The first time you join your URL, you should be prompted to sign-in using your email address.
Looking into Reticulum logs...
- It is useful to look into the backend of your K8s cluster using a free interface called Lens. During the setup process, Lens should automatically detect all accessible clusters associated with your Google Cloud account. You can then look into your individual cluster and its pods using the left-hand toolbar.
- Select the pod for Reticulum and open its logs in the top right-hand corner of the details page. The logs icon is indicated by four horizontal lines with the fourth line shorter than the others.
- After selecting the Reticulum logs, you should be able to view the processes occurring on the backend of your instance.
Verify that SMTP is working correctly...
- With the Reticulum logs open, attempt to sign-in to your instance in the Web browser with your ADM_EMAIL email address.
- If successful, Reticulum should register the request and you should receive an email from noreply@<HUB_DOMAIN>. After this, you can begin to create rooms, upload assets, and deploy scenes to your Hub!
- If unsuccessful, Reticulum should log the reason for the error, which you can then use to troubleshoot.
Verify your configuration values...
1. Back in Lens, select the "Pods" tab in the left-hand toolbar and select your Reticulum pod.
2. Open the "Pod Shell" to ssh into your Reticulum pod. This icon should be immediately left of the "Pod Logs" icon.
3. In the Pod Shell, run the following command:
cat config.toml
4. This will return the values you have used to configure your deployment. Verify the values running match your intended values.
Update configuration values and redeploy...
- You can re-run the command to deploy Community Edition with updated configuration values at any time.
- After re-deploying your configuration, you will have to cycle your current pods for any changes to take effect. This can be achieved by simply deleting all/individual pods using the Lens interface on the "Pods" tab. Thanks to Kubernetes, Community Edition will automatically attempt to create a new pod containing the latest updates.
Step 7: Configure Certificates
The last step of this guide is to configure certificates in order to secure your instance and get rid of the automatic SSL warnings on your Web browser. The Community Edition GitHub README specifies that there are two options for configuring certificates:
A. You can deploy the Hubs team's certbotbot service.
B. You can manually configure certificates using the command line or an interface like Lens.
For this tutorial, we will stick with Option A.
1. Editing cbb.sh
in VSCode, replace the following required parameters with your chosen configurations:
βADM_EMAIL | The same email address you specified in render_hcce.sh
βHUB_DOMAIN | Your domain from Route53.
βNamespace | YOUR_DESIRED_NAMESPACE from your K8s cluster.
2. Once you have configured the required parameters, run the following command to add the service to your K8s cluster.
bash cbb.sh
3. Once applied, verify that the service has been added using the Lens interface. Navigate to the "Pods" tab in the left-hand toolbar. You should see certbotbot-http
present with no visible errors.
4. After a few minutes, attempt to connect to your Community Edition domain. You should no longer encounter the SSL warning on your Web browser.
Conclusion
We hope that this guide has been informative about the technology that makes up Hubs Community Edition and helpful as you set up your own instance. As a reminder, this guide is a quick start and there are many upgrades you should consider to make your version of Community Edition production-ready.
- Scalability | Instances created with this method can support ~15 concurrent users. You can increase capacity by adding additional services for horizontal and vertical scaling.
- AWS SMTP sandbox | Instances created with this method may have limits on the emails they can send to users of their Hub. The process for requesting a limit increase is the same as Hubs Cloud and is documented here.
- Dev Ops for Custom Apps | Instances created with this method will automatically track with the latest version of Hubs codebases. We know that many developers will want to deploy their own versions of the Hubs Client, Reticulum, and Spoke. Doing so will require you to set up your own deployment system. Stay tuned for more documentation about this process in the coming months.
- Migrate Your Hubs Cloud Data | Existing Hubs Cloud customers may want to migrate their existing data to their Community Edition instance. Stay tuned as we release automated tools and documentation over the coming months to make this process fast and easy.
We are so excited to see how the community uses this new technology and can't wait to hear more from you about how to improve Community Edition. The best way to share your thoughts and stay up-to-date on the latest developments is to join our Discord server and check out the #community-edition channel.
Lastly, if you have experience with Kubernetes or self-hosting Hubs and want to share your own documentation, we are currently accepting applications from capable developers for paid documentation commissions. Complete this interest form and we will contact you with more details.