The public BaudBound editor is available at editor.baudbound.app. Follow this guide only when you want your own server to provide the editor website.
Self hosting the editor does not create a shared project server. Projects remain in each user's browser profile. Users should export important projects as .bbs files because clearing browser storage also removes projects stored in that browser.
You need:
curl for checking the editor from the serverThe examples use editor.example.com as the public hostname. Replace it with the real hostname before starting the container or configuring the reverse proxy.
The container is bound to 127.0.0.1. This makes it reachable from the server itself while preventing direct public access to port 3000. The reverse proxy provides the public HTTPS connection.
Create a directory for the editor deployment:
sudo mkdir -p /opt/baudbound-editor
Open a new Compose file:
sudoedit /opt/baudbound-editor/compose.yaml
Add this configuration:
services:
editor:
image: ghcr.io/baudbound/editor:latest
container_name: baudbound-editor
restart: unless-stopped
ports:
- "127.0.0.1:3000:3000"
environment:
NODE_ENV: production
EDITOR_URL: "https://editor.example.com"
EDITOR_URL controls the canonical URL and social metadata generated by the editor. It must contain the public HTTPS address that users will open.
Enter the deployment directory:
cd /opt/baudbound-editor
Download the editor image:
docker compose pull
Start the container:
docker compose up -d
Confirm that Docker reports the container as running:
docker compose ps
Check the editor directly from the server:
curl --fail http://127.0.0.1:3000/
If the check fails, inspect the container logs:
docker compose logs --tail 100 editor
Continue only after the local check succeeds.
These instructions assume Nginx runs directly on the server. Create /etc/nginx/sites-available/baudbound-editor.conf with this configuration:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name editor.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Enable the site on Debian and Ubuntu:
sudo ln -s /etc/nginx/sites-available/baudbound-editor.conf /etc/nginx/sites-enabled/baudbound-editor.conf
Do not create the link again if it already exists. Test the configuration:
sudo nginx -t
Reload Nginx after the test succeeds:
sudo systemctl reload nginx
Install Certbot by following the official Certbot Nginx instructions. Then request the certificate and enable the HTTPS redirect:
sudo certbot --nginx --redirect -d editor.example.com
Test automatic certificate renewal:
sudo certbot renew --dry-run
Nginx Proxy Manager normally runs in Docker. Attach it and the BaudBound editor to the same private Docker network.
Create the network once:
docker network create proxy
Attach the Nginx Proxy Manager application service to the external network in its Compose file:
services:
app:
networks:
- proxy
networks:
proxy:
external: true
The service name may be different in your deployment. Update the existing service instead of creating another service.
Add the same network to /opt/baudbound-editor/compose.yaml:
services:
editor:
networks:
- proxy
networks:
proxy:
external: true
Recreate both Compose projects so Docker attaches the containers to the network:
docker compose up -d
Run that command once from each edited Compose directory.
Open Hosts > Proxy Hosts in Nginx Proxy Manager and create this host:
| Field | Value |
|---|---|
| Domain Names | editor.example.com |
| Scheme | http |
| Forward Hostname / IP | baudbound-editor |
| Forward Port | 3000 |
| Websockets Support | Enabled |
Open the SSL tab. Request a Let's Encrypt certificate, enable Force SSL, accept the terms, and save the host.
These instructions assume Caddy runs directly on the server. Add this block to /etc/caddy/Caddyfile:
editor.example.com {
reverse_proxy 127.0.0.1:3000
}
Validate the configuration:
sudo caddy validate --config /etc/caddy/Caddyfile
Reload Caddy after validation succeeds:
sudo systemctl reload caddy
Caddy obtains and renews the HTTPS certificate automatically when DNS and firewall access are correct.
If Caddy runs in Docker, attach it and the editor container to a shared network. Use baudbound-editor:3000 as the upstream instead of 127.0.0.1:3000.
This example uses Traefik's Docker provider. It assumes Traefik already has an HTTPS entrypoint named websecure, a certificate resolver named letsencrypt, and access to an external Docker network named proxy.
Create the network when it does not exist:
docker network create proxy
Attach Traefik to that network. Then add the network and labels to /opt/baudbound-editor/compose.yaml:
services:
editor:
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.baudbound-editor.rule=Host(`editor.example.com`)"
- "traefik.http.routers.baudbound-editor.entrypoints=websecure"
- "traefik.http.routers.baudbound-editor.tls=true"
- "traefik.http.routers.baudbound-editor.tls.certresolver=letsencrypt"
- "traefik.http.services.baudbound-editor.loadbalancer.server.port=3000"
networks:
proxy:
external: true
Recreate the editor container:
cd /opt/baudbound-editor
docker compose up -d
Inspect Traefik's logs and dashboard. Confirm that the router has a valid certificate and a healthy editor service.
Complete the tab for the reverse proxy you use. Create the DNS record for editor.example.com first. Make sure ports 80 and 443 reach the reverse proxy.
Check the public HTTPS address:
curl --fail https://editor.example.com/
Open the address in a browser. Create a test project, add a node, save the project, reload the page, and export the package. These checks confirm that the editor loads and browser storage works correctly.
Enter the deployment directory:
cd /opt/baudbound-editor
Download the current image:
docker compose pull
Recreate the container with that image:
docker compose up -d
Check the container and public page after every update:
docker compose ps
curl --fail http://127.0.0.1:3000/
curl --fail https://editor.example.com/
For controlled deployments, replace latest with a reviewed release tag or immutable image digest. Save the previous image reference before updating. Restore that reference and run docker compose up -d if the new version fails verification.
Enter the deployment directory:
cd /opt/baudbound-editor
Stop and remove the container:
docker compose down
Remove the reverse proxy host and DNS record after confirming that the container is gone. Removing the server container does not remove projects stored in users' browsers.
3000 remains bound to 127.0.0.1 or a private Docker networkRunning the runner continuously is a separate task. See Linux Background Service.