Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

README.md

Clapshot with Docker Compose

Each compose recipe is one directory you deploy as-is — the only file you edit is .env.

Upgrades are git pull + redeploy.

This guide starts with a local test deployment and works up to a public, TLS-terminated production deployment.

Quick start — HTWicket auth on 127.0.0.1, no HTTPS

The following runs full stack with a built-in login form, on your machine, over plain HTTP. No DNS, no certs yet — the shipped defaults already point at http://127.0.0.1:8080/.

cd deploy/compose/htwicket
cp .env.example .env        # defaults = local HTTP eval; no edits needed for the demo
docker compose up -d

Then:

  1. Get the auto-generated admin password (printed once, on first run):

    docker compose logs htwicket-init
  2. OPTIONAL: Log into http://127.0.0.1:8080/htwicket/admin as admin and create a regular user. Alternatively, you can use docker compose exec htwicket /usr/bin/htwicket user add <name>.

  3. Browse http://127.0.0.1:8080/ → you're sent to the login page.

  4. Log in.

To stop: docker compose down (add -v to also wipe the demo data volumes).

Everything below takes you from this demo toward a real deployment.

Pick a recipe (= your auth choice)

The quick start used HTWicket. There are three recipes, differing only in how users authenticate:

Recipe Auth Use for
no-auth/ none — anonymous; inbound X-Remote-User-* stripped local dev / evaluation
htwicket/ built-in login form + user manager simple deployments
custom-proxy/ trusts X-Remote-User-* from your reverse proxy production with a real IdP

For Authentik, Okta, Keycloak, Kerberos/AD, etc.: run that in front and use the custom-proxy/ recipe. See Advanced Authentication.

Suggested Production Topology

        ┌──────── Caddy ─────────┐    ← TLS termination: Let's Encrypt or your certs
        │  the only container    │      (public entry point)
        │  that publishes ports  │
        └───────────┬────────────┘
                    │ ← http/ws to Docker network
                    |
              [clapshot-web]       ← nginx: serves the web client, proxies /api,
                    |                auth_request → the auth layer
          ┌─────────┴──────────┐
          |                    |
  [clapshot-server]         [ auth ]  ← HTWicket, or nothing, or your own IdP
   + organizer

Only Caddy publishes host ports; the rest talk over the internal Compose network on fixed ports. (Exception: the custom-proxy recipe ships no Caddy — your own proxy is the front and TLS terminator, so there clapshot-web publishes the port instead.)

Deploy from the repo

The quick start ran docker compose by hand from a checkout. For an unattended server, deploy the same directory through your stack manager — still from the git repo, because the recipes mount files by relative path (./site.conf, ./htwicket.toml), so a single file pasted into a web editor won't work.

Plain Docker Compose

cd deploy/compose/htwicket   # or another recipe
cp .env.example .env         # then edit it
docker compose up -d

Portainer

StacksAdd stackRepository:

  • Repository URL: this repository
  • Compose path: deploy/compose/htwicket/compose.yml (or another recipe)
  • Set the variables from .env.example in the Environment variables panel
  • Turn on Automatic updates (or add a webhook) to redeploy when the repo changes

Komodo

Create a Stack from this git repo with compose path deploy/compose/<recipe>/compose.yml; set the variables in the UI.

Upgrading (any method): pull the repo and redeploy. The nginx config and htwicket.toml are versioned in the repo and mounted read-only, so they update with the pull; your data and users live in volumes and persist. Pin CLAPSHOT_VERSION / HTWICKET_VERSION if you want upgrades to be deliberate.

Configuration (.env)

Your edits go here — see each recipe's .env.example for the full, commented set. The essentials:

Variable Meaning
CLAPSHOT_URL_BASE the public URL — the source of truth (its scheme drives http/https everywhere)
CADDY_CERT_DOMAIN set → Caddy gets Let's Encrypt certs this hostname; unset → plain HTTP
CADDY_BIND / CADDY_HTTP_PORT / CADDY_HTTPS_PORT where Caddy publishes on the Docker host
CLAPSHOT_DATA_DIR (and HTWICKET_DATA_DIR, CADDY_DATA_DIR) unset → managed volume; set → bind to a host path

The CADDY_* rows apply to no-auth and HTWicket. custom-proxy has no Caddy: it uses WEB_BIND / WEB_PORT for the published port, and TLS is your front proxy's job.

A config-check step runs on every up and stops startup if the settings are inconsistent.

HTTPS

The demo ran plain HTTP. For secure authentication and operation, you need TLS. In the HTWicket and no-auth recipes, Caddy terminates it — three modes, selected by .env. (The custom-proxy recipe has no Caddy; TLS is handled by your own front proxy, so this section doesn't apply to it.)

  1. Automatic Let's Encrypt (most common). Set CADDY_CERT_DOMAIN=clapshot.example.com, point that name's DNS at the host, and open ports 80 and 443. Caddy obtains and renews the certificate.
  2. Your own certificates. Set CADDY_TLS_CERT / CADDY_TLS_KEY to mounted PEM files; ACME is skipped.
  3. Plain HTTP (local testing, or behind your own TLS proxy). Leave CADDY_CERT_DOMAIN unset — this is what the quick start uses.

How LE validation works: Caddy uses the HTTP-01 (:80) or TLS-ALPN-01 (:443) challenge, so both ports must be publicly reachable. Keep the CADDY_DATA_DIR volume — it stores the certs and the ACME account; losing it on every restart will hit Let's Encrypt rate limits.

Going to production

Take the quick-start .env and replace the local-eval values with public, HTTPS ones:

CLAPSHOT_URL_BASE=https://clapshot.example.com/
CADDY_CERT_DOMAIN=clapshot.example.com      # LE cert; host must equal the URL's host
CADDY_BIND=0.0.0.0
CADDY_HTTP_PORT=80
CADDY_HTTPS_PORT=443
HTWICKET_INSECURE_COOKIES=false             # HTWicket on https (omit if not using HTWicket)
CLAPSHOT_VERSION=<pin a released version>

Users (HTWicket recipe)

First start seeds a single admin user — create everyone else yourself in the admin UI at /htwicket/admin (HTWicket's whole job), or with docker compose exec htwicket /usr/bin/htwicket user add <name>.

There is no default admin password. You can either:

  • set the admin password with CLAPSHOT_INITIAL_ADMIN_PASSWORD (or …_FILE for a Docker/Swarm secret); or
  • leave it unset to get a random one printed in the logs (as in the quick start). It's applied only on first run (or, when missing) — change it later in the GUI, or by running (this prompts for new password):
docker compose exec htwicket /usr/bin/htwicket user passwd admin

Data & backups

By default each store is a managed Docker volume. To put data on a host path (e.g. on a NAS for easy backups), set the matching *_DIR variable to an absolute path. Each service runs as a different user, so the host path must be writable by that service's uid (a fresh named volume is chowned automatically; a host bind is not):

Variable Holds Host path writable by Back up?
CLAPSHOT_DATA_DIR videos + SQLite database uid 33 (www-data) yes — the important one
HTWICKET_DATA_DIR users (.htpasswd), per-user flags, session key uid 65532 (nonroot) yes
CADDY_DATA_DIR TLS certs + ACME account uid 0 (root) optional (re-fetchable, but avoids rate limits)

Tests

tests/ holds end-to-end smoke tests for these recipes: each brings a recipe's stack up and drives the real web client in a headless browser (tests/run.sh <recipe>). See tests/README.md.