mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-06-18 12:20:15 +00:00
188 lines
7.3 KiB
YAML
188 lines
7.3 KiB
YAML
# Self-hosted LiveSync — Docker Compose
|
|
# =============================================================================
|
|
# PROFILES
|
|
# --------
|
|
# (default) CouchDB only — LAN/localhost access, no TLS
|
|
# Suitable for desktop-only use or testing.
|
|
#
|
|
# --profile caddy CouchDB + Caddy reverse proxy
|
|
# Auto TLS via Let's Encrypt. Needs public domain + ports 80/443.
|
|
#
|
|
# --profile tailscale CouchDB + Tailscale sidecar
|
|
# No domain required. HTTPS via *.ts.net PKI.
|
|
# Needs a Tailscale account (free tier works).
|
|
#
|
|
# --profile cloudflare CouchDB + cloudflared tunnel daemon
|
|
# Free public HTTPS via Cloudflare. Needs a CF account + tunnel token.
|
|
# NOTE: Enable "Use Request API" in the Obsidian plugin to avoid 524 timeouts.
|
|
#
|
|
# QUICK START (local test):
|
|
# cp .env.example .env && edit .env
|
|
# docker compose up -d
|
|
# curl -u admin:yourpassword http://localhost:5984/_up
|
|
# =============================================================================
|
|
|
|
name: obsidian-livesync
|
|
|
|
services:
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# CouchDB — the only required service
|
|
# ---------------------------------------------------------------------------
|
|
couchdb:
|
|
image: couchdb:latest
|
|
container_name: livesync-couchdb
|
|
restart: unless-stopped
|
|
# NOTE: Do NOT set user: here — the CouchDB entrypoint starts as root to
|
|
# write docker.ini (from env vars), then drops to uid 5984 automatically.
|
|
environment:
|
|
COUCHDB_USER: ${COUCHDB_USER:?Set COUCHDB_USER in .env}
|
|
COUCHDB_PASSWORD: ${COUCHDB_PASSWORD:?Set COUCHDB_PASSWORD in .env}
|
|
volumes:
|
|
- couchdb-data:/opt/couchdb/data
|
|
# Mount to /opt/couchdb/etc/local.ini (NOT into local.d/).
|
|
# Do NOT use :ro — the CouchDB entrypoint runs chmod on this file at startup
|
|
# and will crash with EPERM if the file is read-only. The file is only read
|
|
# at startup; runtime changes go via the REST API into local.d/docker.ini.
|
|
- ./config/livesync.ini:/opt/couchdb/etc/local.ini
|
|
ports:
|
|
# Exposes CouchDB on the host for LAN/localhost access.
|
|
# The tunnel profiles (caddy/tailscale/cloudflare) provide HTTPS on top.
|
|
# You can remove this port mapping once a tunnel profile is in use.
|
|
- "${COUCHDB_PORT:-5984}:5984"
|
|
healthcheck:
|
|
# Test with admin credentials — ensures both CouchDB is up AND auth is ready.
|
|
# ${COUCHDB_USER} / ${COUCHDB_PASSWORD} are expanded by Docker Compose here.
|
|
test:
|
|
- "CMD-SHELL"
|
|
- "curl -sf -u ${COUCHDB_USER}:${COUCHDB_PASSWORD} http://localhost:5984/_session | grep -q ok || exit 1"
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 24
|
|
start_period: 20s
|
|
networks:
|
|
- livesync-net
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# One-shot init container — runs couchdb-init.sh after CouchDB is healthy.
|
|
# Sets single-node cluster, auth requirements, CORS, size limits, creates DB.
|
|
# Restarts on failure (e.g. race at first boot) but won't re-run if already done.
|
|
# ---------------------------------------------------------------------------
|
|
couchdb-init:
|
|
image: curlimages/curl:latest
|
|
container_name: livesync-init
|
|
restart: on-failure
|
|
depends_on:
|
|
couchdb:
|
|
condition: service_healthy
|
|
environment:
|
|
COUCHDB_INTERNAL_URL: http://couchdb:5984
|
|
COUCHDB_USER: ${COUCHDB_USER}
|
|
COUCHDB_PASSWORD: ${COUCHDB_PASSWORD}
|
|
COUCHDB_DATABASE: ${COUCHDB_DATABASE:-obsidiannotes}
|
|
volumes:
|
|
- ./scripts/couchdb-init.sh:/couchdb-init.sh:ro
|
|
entrypoint: ["sh", "/couchdb-init.sh"]
|
|
networks:
|
|
- livesync-net
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# PROFILE: caddy — Caddy reverse proxy with automatic Let's Encrypt TLS
|
|
# Requirements: public domain, ports 80 + 443 open to internet
|
|
# Usage: docker compose --profile caddy up -d
|
|
# ---------------------------------------------------------------------------
|
|
caddy:
|
|
image: caddy:latest
|
|
container_name: livesync-caddy
|
|
profiles: [caddy]
|
|
restart: unless-stopped
|
|
depends_on:
|
|
couchdb:
|
|
condition: service_healthy
|
|
environment:
|
|
COUCHDB_DOMAIN: ${COUCHDB_DOMAIN:?Set COUCHDB_DOMAIN in .env for caddy profile}
|
|
ACME_EMAIL: ${ACME_EMAIL:?Set ACME_EMAIL in .env for caddy profile}
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
volumes:
|
|
- ./config/Caddyfile:/etc/caddy/Caddyfile:ro
|
|
- caddy-data:/data
|
|
- caddy-config:/config
|
|
networks:
|
|
- livesync-net
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# PROFILE: tailscale — Tailscale sidecar for mesh VPN + optional Funnel
|
|
# Requirements: Tailscale account (free), OAuth key, Funnel enabled in ACL
|
|
# Usage: docker compose --profile tailscale up -d
|
|
# The CouchDB port mapping above can be removed for tailscale-only deployments.
|
|
# ---------------------------------------------------------------------------
|
|
tailscale:
|
|
image: tailscale/tailscale:latest
|
|
container_name: livesync-tailscale
|
|
profiles: [tailscale]
|
|
restart: unless-stopped
|
|
hostname: ${TS_HOSTNAME:-livesync}
|
|
environment:
|
|
TS_AUTHKEY: ${TS_AUTHKEY:?Set TS_AUTHKEY in .env for tailscale profile}
|
|
TS_STATE_DIR: /var/lib/tailscale
|
|
TS_SERVE_CONFIG: /config/serve.json
|
|
TS_USERSPACE: "false"
|
|
TS_ACCEPT_DNS: "false"
|
|
TS_EXTRA_ARGS: ""
|
|
volumes:
|
|
- tailscale-state:/var/lib/tailscale
|
|
- ./config/ts-serve.json:/config/serve.json:ro
|
|
- /dev/net/tun:/dev/net/tun
|
|
cap_add:
|
|
- NET_ADMIN
|
|
- SYS_MODULE
|
|
# Share CouchDB's network namespace so Tailscale can reach it on localhost
|
|
network_mode: service:couchdb
|
|
depends_on:
|
|
- couchdb
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# PROFILE: cloudflare — cloudflared tunnel daemon
|
|
# Requirements: Cloudflare account, tunnel token from CF Zero Trust dashboard
|
|
# Usage: docker compose --profile cloudflare up -d
|
|
# NOTE: Enable "Use Request API" toggle in the Obsidian LiveSync plugin settings
|
|
# to avoid Cloudflare's 100-second proxy timeout (524 errors).
|
|
# ---------------------------------------------------------------------------
|
|
cloudflared:
|
|
image: cloudflare/cloudflared:latest
|
|
container_name: livesync-cloudflared
|
|
profiles: [cloudflare]
|
|
restart: unless-stopped
|
|
command: tunnel --no-autoupdate run
|
|
environment:
|
|
TUNNEL_TOKEN: ${CF_TUNNEL_TOKEN:?Set CF_TUNNEL_TOKEN in .env for cloudflare profile}
|
|
volumes:
|
|
- ./config/cloudflared.yml:/etc/cloudflared/config.yml:ro
|
|
depends_on:
|
|
couchdb:
|
|
condition: service_healthy
|
|
networks:
|
|
- livesync-net
|
|
|
|
# =============================================================================
|
|
# Volumes
|
|
# =============================================================================
|
|
volumes:
|
|
couchdb-data:
|
|
driver: local
|
|
caddy-data:
|
|
driver: local
|
|
caddy-config:
|
|
driver: local
|
|
tailscale-state:
|
|
driver: local
|
|
|
|
# =============================================================================
|
|
# Networks
|
|
# =============================================================================
|
|
networks:
|
|
livesync-net:
|
|
driver: bridge
|