This guide explains how to setup Compass on your own infrastructure.
If you'd rather have a local development setup or use the binaries, see the developer's quickstart.
- OS: Ubuntu
- Platform: Docker
- Reverse-proxy: Caddy
- Frontend:
https://compass.example.com - API:
https://compass.example.com/api
This doc assumes you're comfortable with:
- SSH
- DNS records (pointing a domain at a server's IP)
- Installing Docker on Ubuntu. It'll probably work with other Debian-based distros, but we only test it on Ubuntu
- Editing files on a remote machine
- Whenever you see
compass.example.com, replace with your domain. - A separate API domain like
https://api.compass.example.commay be possible, but it adds cookie and CORS complexity. This guide uses one domain for the first server install.
Plan for 15 to 45 minutes from start to finish.
- Get a VPS with Ubuntu, then install Docker, Docker Compose, and Caddy.
- Point DNS at the server and confirm the server has Docker, Compose, Caddy, and open
80/443. - SSH into the server and install Compass with the self-host installer.
- Configure Caddy to proxy
compass.example.comto127.0.0.1:9080and/api/*to127.0.0.1:3000. - Verify Caddy can reach the local backend over HTTPS.
- Edit
~/compass/compass.yamlto use your public URLs, then restart Compass. - Sign in over HTTPS and run the basic tests below.
If you already have an Ubuntu VPS with Docker, Docker Compose, and Caddy installed, skip to the next step.
Any provider will do, but here are two simple options.
DigitalOcean Droplets. Their Initial Server Setup with Ubuntu guide walks you through region, size, SSH key upload, and firewall setup. A Droplet at $12/month (1 vCPU, 2 GB RAM) is enough for a personal Compass instance.
Hetzner Cloud is a strong low-cost alternative. Their CX22 starts at around $4/month for 2 vCPU and 2 GB RAM.
| Resource | Minimum |
|---|---|
| RAM | 2 GB (4 GB recommended) |
| Storage | 20 GB SSD |
| OS | Ubuntu 22.04 LTS or 24.04 LTS |
| Network | 1 static public IPv4 address |
After the server is created, SSH in and run your provider's initial setup steps (create a non-root sudo user, etc.), then open the ports Caddy needs:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enableThen install Docker Engine, Docker Compose, and Caddy using the official apt packages:
You'll need a domain name to get HTTPS working. If you already have one (me.dev) and are OK with adding a subdomain (calendar.me.dev), you can skip this step.
Two good options for new domains:
Namecheap — straightforward, .com domains ~$9–11/year, free WHOIS privacy included.
Cloudflare Registrar — domains at cost. A good choice if you want fast DNS management in one place.
Type: A
Name: <subdomain> # example: 'cal', 'calendar', 'compass', 'app'
Value: <your-vps-ipv4-address>
That makes the subdomain point at the server's public IPv4 address. DNS is managed wherever your domain's nameservers point. That may be your registrar, but it may also be another host such as Cloudflare or Vercel.
Say you have a domain example.com and create the A record for the subdomain compass. You can confirm the record from your own computer:
dig +short A compass.example.comIt should print your VPS IPv4 address. It might take a few minutes for your DNS record to propagate.
On the server, confirm the basic tools and ports:
lsb_release -a
docker --version
docker compose version
caddy version
sudo systemctl status caddy --no-pager
sudo ss -tulpn | grep -E ':(80|443|3000|9080)\b' || true
sudo ufw status verbose || trueIf the server has been used for other projects, existing web servers, private-network tools, or firewall rules can block Caddy even when the Compass containers are healthy.
For the recommended setup:
- Caddy should run as a system service.
- Public ports
80and443should be available for Caddy. - Ports
3000and9080should be unused before the Compass installer runs. - If UFW or another firewall is enabled, allow inbound TCP
80and443.
Caddy needs port 80 for the first certificate setup and HTTP-to-HTTPS
redirects. It needs port 443 for the final HTTPS site.
We made a bash script that installs Compass. It's designed for convenience, so it handles things like generating valid secrets and populating the compose file.
curl -fsSL https://raw.githubusercontent.com/SwitchbackTech/compass/main/self-host/install.sh | shIf you'd rather do everything yourself, check-out our manual install guide, which has bash commands you can individually copy-paste. This'll give you full visibility and control, but will take longer.
Now that we have Docker, Caddy, and Compass install, we can wire up the proxy to ensure requests flow through your system smoothly.
Edit the Caddyfile, replacing compass.example.com with your domain.
sudo vi /etc/caddy/Caddyfile# Caddyfile
# https://caddyserver.com/docs/caddyfile-tutorial
compass.example.com { # <- this is the only line you need to change
handle /api/* {
reverse_proxy 127.0.0.1:3000
}
handle {
reverse_proxy 127.0.0.1:9080
}
}This tells Caddy to serve your public domain over HTTPS, send /api/* requests
to the Compass backend on 127.0.0.1:3000, and send everything else to the web
app on 127.0.0.1:9080.
Save the file and validate your changes:
sudo caddy validate --config /etc/caddy/CaddyfileIf validation passes, reload:
sudo systemctl reload caddyIf this is the first real HTTPS site on the server, Caddy will fetch a certificate after the reload. That can take a few seconds.
curl -f https://compass.example.com/api/healthA healthy backend returns JSON with "status":"ok".
If the healthcheck fails, Caddy isn't routing to the backend yet. Fix that before moving on. Here are some ideas.
If curl cannot connect to port 443, check that Caddy is listening there:
sudo ss -tulpn | grep -E ':(80|443)\b' || true
sudo systemctl status caddy --no-pager -l
sudo journalctl -u caddy --since '10 minutes ago' --no-pager -lIf another process already owns 443, Caddy cannot serve HTTPS. Common examples
are another web server, an old Caddy process, or a private-network HTTPS feature
such as Tailscale Serve. Stop or move the conflicting service, then restart
Caddy:
sudo systemctl reset-failed caddy
sudo systemctl restart caddyWarning. The default compose file keeps MongoDB, SuperTokens, and Postgres off the public internet. You should probably keep it that way. Don't add public port mappings for those services, don't open their ports in your firewall, and don't move them to public database hosts unless you know how you want to secure them. For this guide, only Caddy should be public, and Caddy should proxy only the web app and
/api.
Warning. Don't change
backend.apiUrluntil the reverse proxy works. The browser usesbackend.apiUrlfor API requests. If it points at an HTTPS URL Caddy can't serve yet, the app can load but cannot reach the backend.
Edit the config file:
cd ~/compass
vi compass.yamlSet:
web:
url: https://compass.example.com
backend:
apiUrl: https://compass.example.com/api
originsAllowed:
- https://compass.example.comCompass reads compass.yaml at startup via a Docker volume mount, so a restart picks up the new values:
cd ~/compass
./compass restart
compassis our minimal Bash CLIFor more info, run
cd ~/compass && ./compass --help
Confirm the public health check still works after applying the config changes:
curl -f https://compass.example.com/api/healthThen tail the backend logs while you open Compass in a browser. This lets you see successful requests and spot backend errors immediately:
cd ~/compass
./compass logs backendFor a final server-side check, run:
cd ~/compass
./compass status
sudo ss -tulpn | grep -E ':(80|443|3000|9080)\b' || true
curl -f https://compass.example.com/api/healthOpen https://compass.example.com in a browser. Run the password-only path first, before adding Google:
- Create an account with email and password
- Sign out
- Sign back in
- Create an event
- Edit the event
- Delete the event
./compass restart- Sign in again and confirm the events are still there
We leave backups and restore up to you, but we have a simple Backups and restore guide that attempts to make that a little easier.
If you want to make custom changes to Compass, see the custom code guide
You don't need to use Google or Google Calendar to use Compass. However, it can be nice to see your Gcal events in Compass and to sync changes. This requires some extra setup, through. See the Google Calendar guide when you're ready to do some more config.
Have an idea on how this guide can be improved? Let us know in this GitHub Discussion.