Docker Deployment

Deploy Duet with Docker Compose in minutes. This setup includes PostgreSQL and the Duet application in containers, with data persisted in Docker volumes.

Prerequisites

  • Docker - version 20.10 or later
  • Docker Compose - version 2.0 or later (included with Docker Desktop)

Step 1: Clone the Repository

git clone https://github.com/emreparker/duet.git
cd duet

Step 2: Configure Environment

Copy the example environment file and edit it:

cp .env.example .env

Open .env and set your SESSION_SECRET. This is used to sign session cookies and should be a long, random string:

# Generate a random secret
openssl rand -base64 32

# Add it to your .env
SESSION_SECRET=your-generated-random-string

Step 3: Start Duet

docker compose up -d

This starts two containers: a PostgreSQL database and the Duet application. The database is automatically initialized with the required schema.

Check that everything is running:

docker compose ps

# Check logs
docker compose logs -f duet

Step 4: Initial Setup

  1. Open http://localhost:7777 in your browser.
  2. Set your password on the setup screen. This is the only password - Duet is single-user.
  3. You're in. Start creating notes.

Step 5: Register an Agent

  1. In the Duet UI, go to Agents in the sidebar.
  2. Click Register Agent and enter a name (e.g. "claude").
  3. Copy the API key - it is only shown once.
  4. Configure your MCP client with the API key. See the MCP Setup guide.

Docker Compose Architecture

The docker-compose.yml creates:

  • duet - the application container (Node.js, Hono API, Next.js frontend)
  • postgres - PostgreSQL 16 database
  • duet_data - a named volume for PostgreSQL data persistence

Data persists across container restarts in the Docker volume. Removing the containers does not delete your data.

Managing the Deployment

# Stop Duet (preserves data)
docker compose stop

# Start again
docker compose start

# Restart
docker compose restart

# Update to latest version
git pull
docker compose up -d --build

# View logs
docker compose logs -f duet

# Destroy everything (WARNING: deletes all data)
docker compose down -v

Production Tips

Use a Strong SESSION_SECRET

The session secret is used to sign cookies. In production, use a cryptographically random string of at least 32 characters. Never share it or commit it to version control.

Set Up a Reverse Proxy with HTTPS

For production, put Duet behind a reverse proxy like Caddy or nginx with TLS termination.

Example Caddyfile:

duet.yourdomain.com {
    reverse_proxy localhost:7777
}

Caddy automatically provisions and renews Let's Encrypt certificates.

Back Up PostgreSQL

Set up regular backups of the PostgreSQL volume or use pg_dump:

# Backup
docker compose exec postgres pg_dump -U duet duet > backup.sql

# Restore
cat backup.sql | docker compose exec -T postgres psql -U duet duet

Google Calendar (Optional)

To enable Google Calendar sync, add the OAuth credentials to your .env:

GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret

Then restart with docker compose up -d. See the Google Calendar Sync guide for full setup instructions.