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