Maincloud is now LIVE! Get Maincloud Energy 90% off until we run out!

Self Hosting SpacetimeDB

This tutorial will guide you through setting up SpacetimeDB on an Ubuntu 24.04 server, securing it with HTTPS using Nginx and Let's Encrypt, and configuring a systemd service to keep it running.

Prerequisites

  • A fresh Ubuntu 24.04 server (VM or cloud instance of your choice)
  • A domain name (e.g., example.com)
  • sudo privileges on the server

Step 1: Create a Dedicated User for SpacetimeDB

For security purposes, create a dedicated spacetimedb user to run SpacetimeDB:

sudo mkdir /stdb
sudo useradd --system spacetimedb
sudo chown -R spacetimedb:spacetimedb /stdb 

Install SpacetimeDB as the new user:

sudo -u spacetimedb bash -c 'curl -sSf https://install.spacetimedb.com | sh -s -- --root-dir /stdb --yes' 

Step 2: Create a Systemd Service for SpacetimeDB

To ensure SpacetimeDB runs on startup, create a systemd service file:

sudo nano /etc/systemd/system/spacetimedb.service 

Add the following content:

[Unit]
Description=SpacetimeDB Server
After=network.target

[Service]
ExecStart=/stdb/spacetime --root-dir=/stdb start --listen-addr='127.0.0.1:3000'
Restart=always
User=spacetimedb
WorkingDirectory=/stdb

[Install]
WantedBy=multi-user.target 

Enable and start the service:

sudo systemctl enable spacetimedb
sudo systemctl start spacetimedb 

Check the status:

sudo systemctl status spacetimedb 

Step 3: Install and Configure Nginx

Install Nginx

sudo apt update
sudo apt install nginx -y 

Configure Nginx Reverse Proxy

Create a new Nginx configuration file:

sudo nano /etc/nginx/sites-available/spacetimedb 

Add the following configuration, remember to change example.com to your own domain:

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
    }

    # This restricts who can publish new databases to your SpacetimeDB instance. We recommend
    # restricting this ability to local connections. 
    location /v1/publish {
        allow 127.0.0.1;
        deny all;
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
    }
} 

This configuration contains a restriction to the /v1/publish route. This restriction makes it so that you can only publish to the database if you're publishing from a local connection on the host.

Enable the configuration:

sudo ln -s /etc/nginx/sites-available/spacetimedb /etc/nginx/sites-enabled/ 

Restart Nginx:

sudo systemctl restart nginx 

Configure Firewall

Ensure your firewall allows HTTPS traffic:

sudo ufw allow 'Nginx Full'
sudo ufw reload 

Step 4: Secure with Let's Encrypt

Install Certbot

sudo apt install certbot python3-certbot-nginx -y 

Obtain an SSL Certificate

Run this command to request a new SSL cert from Let's Encrypt. Remember to replace example.com with your own domain:

sudo certbot --nginx -d example.com 

Certbot will automatically configure SSL for Nginx. Restart Nginx to apply changes:

sudo systemctl restart nginx 

Auto-Renew SSL Certificates

Certbot automatically installs a renewal timer. Verify that it is active:

sudo systemctl status certbot.timer 

Step 5: Verify Installation

On your local machine, add this new server to your CLI config. Make sure to replace example.com with your own domain:

spacetime server add self-hosted --url https://example.com 

If you have uncommented the /v1/publish restriction in Step 3 then you won't be able to publish to this instance unless you copy your module to the host first and then publish. We recommend something like this:

spacetime build
scp target/wasm32-unknown-unknown/release/spacetime_module.wasm ubuntu@<host>:/home/ubuntu/
ssh ubuntu@<host> spacetime publish -s local --bin-path spacetime_module.wasm <module-name> 

You could put the above commands into a shell script to make publishing to your server easier and faster. It's also possible to integrate a script like this into Github Actions to publish on some event (like a PR merging into master).

Step 6: Updating SpacetimeDB Version

To update SpacetimeDB to the latest version, first stop the service:

sudo systemctl stop spacetimedb 

Then upgrade SpacetimeDB:

sudo -u spacetimedb -i -- spacetime --root-dir=/stdb version upgrade 

To install a specific version, use:

sudo -u spacetimedb -i -- spacetime --root-dir=/stdb install <version-number> 

Finally, restart the service:

sudo systemctl start spacetimedb 

Step 7: Troubleshooting

SpacetimeDB Service Fails to Start

Check the logs for errors:

sudo journalctl -u spacetimedb --no-pager | tail -20 

Verify that the spacetimedb user has the correct permissions:

sudo ls -lah /stdb/spacetime 

If needed, add the executable permission:

sudo chmod +x /stdb/spacetime 

Let's Encrypt Certificate Renewal Issues

Manually renew the certificate and check for errors:

sudo certbot renew --dry-run 

Nginx Fails to Start

Test the configuration:

sudo nginx -t 

If errors are found, check the logs:

sudo journalctl -u nginx --no-pager | tail -20 
Edit On Github