micasa

Self-Hosting

micasa syncs your household data across machines through an encrypted relay. Run your own with Docker Compose.

What you need#

  • A machine with Docker and Docker Compose
  • A domain name (optional, for TLS)

The relay runs two containers: PostgreSQL for storage and the relay binary for sync traffic. PostgreSQL holds encrypted sync operations, encrypted document blobs, device registrations, and invite state. All household data is end-to-end encrypted — the relay never sees plaintext. PostgreSQL row-level security provides an additional isolation layer, ensuring one household’s data is invisible to queries from another even if application code has a bug.

Quick start#

Clone the repo and copy the example env file:

git clone https://github.com/micasa-dev/micasa.git
cd micasa/deploy
cp .env.example .env

Edit .env and set a real password and encryption key:

# Generate an encryption key first:
openssl rand -hex 32
# Copy the output, then edit .env:
POSTGRES_PASSWORD=something-strong-here
RELAY_ENCRYPTION_KEY=paste-the-64-char-hex-key-here

Start the stack:

docker compose up -d

The relay is now running on port 8080. Verify:

curl http://localhost:8080/health
# {"status":"ok"}

Connect micasa to your relay#

On each machine, initialize with your relay URL:

micasa pro init --relay-url http://your-server:8080

On the first machine this creates a new household. On additional machines, generate an invite on the first machine and join from the second:

# Machine 1:
micasa pro invite

# Machine 2:
micasa pro join <code> --relay-url http://your-server:8080

Sync happens automatically after that.

Adding TLS#

For production use, add TLS via the included Caddy overlay. Set your domain in .env:

DOMAIN=sync.example.com

Point your DNS A record to the server, then start with both compose files:

docker compose \
  -f docker-compose.yml \
  -f docker-compose.caddy.yml \
  up -d

Caddy automatically obtains and renews a Let’s Encrypt certificate. The relay is no longer exposed on port 8080 — all traffic goes through Caddy on 443.

Connect micasa using the HTTPS URL:

micasa pro init --relay-url https://sync.example.com

Configuration#

All configuration is via environment variables in .env.

VariableDefaultDescription
POSTGRES_PASSWORD(required)PostgreSQL password.
RELAY_ENCRYPTION_KEY(required)32-byte hex key for encrypting device tokens at rest. Generate with openssl rand -hex 32.
BLOB_QUOTA0Per-household blob storage limit. Accepts human-readable sizes (5GB, 500MB). 0 = unlimited.
DOMAIN(unset)Domain for TLS via Caddy. Only needed with the Caddy overlay.

Blob storage#

Documents attached in micasa are synced as encrypted blobs. By default, self-hosted relays have no storage limit per household. To set a limit:

# 5 GB per household
BLOB_QUOTA=5GB

Individual blobs are capped at 50 MB regardless of quota.

Backups#

Everything the relay stores lives in PostgreSQL. Back up with:

docker compose exec postgres pg_dump -U micasa micasa > backup.sql

The backup contains encrypted data only — sync operations, blobs, and device registrations. Encryption keys live on each device, not on the relay, so a database dump is not useful without the devices that generated the keys.

Updating#

Pull the latest code and rebuild:

git pull
docker compose up -d --build

The relay runs database migrations automatically on startup.