Docker Compose setup for running a Relay Server for Obsidian. This repository defaults to local filesystem storage and binds the service to localhost for a safe same-machine test.
Relay's server and Obsidian plugin are open source. The Relay Control Plane still provides login, permissions, and server metadata.
- Docker Engine and Docker Compose
- A Relay account
- Obsidian with the Relay plugin
For collaboration from other devices, use a private network such as Tailscale. Do not expose the Relay Server directly to the public internet.
Clone the repository and start the service:
mkdir -p data
docker compose up -d
docker compose logs -f relayThe local endpoint is:
http://127.0.0.1:18080
The root path may return 404; Relay is primarily a WebSocket/API service.
The logs should report Configuration is valid! and
Listening on ws://0.0.0.0:8080.
Check status:
docker compose psOn the same computer as the container:
- Install and enable the Relay community plugin in Obsidian.
- Sign in to your Relay account.
- Open the command palette with
Ctrl+P. - Run
Relay: Register self-hosted Relay Server. - Enter
http://127.0.0.1:18080. - Create a Shared Folder and invite collaborators as needed.
The Free plan supports up to three users per Relay Server. Self-hosting does not remove that seat limit.
Self-hosted Relay can sync images, videos, PDFs, and other file types. The attachment must be inside the Shared Folder.
In Obsidian, set:
Settings -> Files and links -> Default location for new attachments
-> In subfolder under current folder
Use Attachments as the subfolder name. A test folder can look like:
Relay Test/
test.md
Attachments/
image.png
video.mp4
With the default local storage configuration, Relay data is persisted under
the repository's data/ directory. This directory is intentionally ignored
by Git.
Install and authenticate Tailscale on the server:
sudo tailscale up
tailscale statusInstall Docker, clone this repository, and create the storage directory:
mkdir -p dataEdit relay.toml and change the URL to the server's Tailscale MagicDNS name:
url = "http://relay-server.example-tailnet.ts.net:8080"Change compose.yaml so the container is reachable on the server's private
network instead of localhost:
ports:
- "8080:8080"Start Relay:
docker compose up -d
docker compose logs -f relayRegister the same Tailscale URL from Obsidian on each client:
http://relay-server.example-tailnet.ts.net:8080
Every client must be connected to the same Tailscale network. If you use HTTPS
or a custom private VPN, update both the url in relay.toml and the URL
entered in Obsidian.
Local filesystem storage is suitable for testing. For a long-running server,
use S3-compatible storage such as Cloudflare R2, Backblaze B2, AWS S3, or
MinIO. Replace the [store] section in relay.toml with the provider's
configuration and keep credentials out of Git.
For Cloudflare R2, the shape is:
[store]
type = "cloudflare"
account_id = "YOUR_CLOUDFLARE_ACCOUNT_ID"
bucket = "YOUR_BUCKET_NAME"
prefix = ""Provide the R2 access key and secret through the deployment environment as documented by the Relay server template. Never commit credentials to this repository.
Relay is not a backup system. Back up data/ when using filesystem storage,
or configure backups/versioning for your object-storage bucket. Test restoring
a backup before relying on it.
docker compose logs -f relay
docker compose restart relay
docker compose down
docker compose down --volumesThe bind-mounted data/ directory is not deleted by docker compose down.
Delete it separately only when you intentionally want to erase Relay data.