Skip to content

Install the Mercure hub

The fastest way to get started is Mercure Cloud. Get a managed hub with automatic HTTPS and a custom domain. We operate the infrastructure; you build the real-time features. Choose your Cloud plan.

Need to run Mercure on your own servers? Mercure Enterprise adds clustering, Redis/Valkey, PostgreSQL, Kafka, and Pulsar transports, plus direct support. The Managed On-Premise option lets our team deploy, monitor, and update it on your infrastructure.

To run the open-source hub yourself, choose Docker, Helm, or a prebuilt binary below. All editions speak the same Mercure protocol.

The Mercure.rocks Hub is a custom build of the Caddy web server with the Mercure module. It includes Caddy's standard TLS, HTTP/3, compression, reverse-proxy, and metrics features. Third-party Caddy modules require a custom build.

Generate each key once with openssl rand -base64 32 and export it as MERCURE_PUBLISHER_JWT_KEY / MERCURE_SUBSCRIBER_JWT_KEY: anyone can forge tokens signed with the development key.

docker run \
    -e MERCURE_PUBLISHER_JWT_KEY \
    -e MERCURE_SUBSCRIBER_JWT_KEY \
    -p 80:80 -p 443:443 \
    dunglas/mercure

HTTPS is enabled by default. Set SERVER_NAME to a public hostname for automatic certificates; localhost uses Caddy's local certificate authority. Behind a TLS-terminating proxy, follow the reverse-proxy configuration.

For local development, set MERCURE_EXTRA_DIRECTIVES=playground, which enables anonymous subscriptions and the debug UI:

docker run \
    -e MERCURE_EXTRA_DIRECTIVES=playground \
    -p 80:80 -p 443:443 \
    dunglas/mercure

The hub is then available at https://localhost, with the debug UI at https://localhost/.well-known/mercure/debug/.

The image's HEALTHCHECK queries the transport-aware /mercure/health/ready endpoint on the Caddy admin API.

#Docker Compose

Save this configuration as compose.yaml, then run docker compose up -d:

services:
  mercure:
    image: dunglas/mercure
    restart: unless-stopped
    environment:
      # Uncomment to disable HTTPS (use behind a reverse proxy)
      #SERVER_NAME: ':80'
      MERCURE_PUBLISHER_JWT_KEY: ${MERCURE_PUBLISHER_JWT_KEY}
      MERCURE_SUBSCRIBER_JWT_KEY: ${MERCURE_SUBSCRIBER_JWT_KEY}
      # Uncomment to run in development mode (insecure playground)
      #MERCURE_EXTRA_DIRECTIVES: playground
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - mercure_data:/data
      - mercure_config:/config

volumes:
  mercure_data:
  mercure_config:

The /data volume holds the BoltDB history; /config holds Caddy's autosaved configuration. See Docker deployment for healthchecks and rootless mode.

#Kubernetes (Helm)

helm repo add mercure https://charts.mercure.rocks
helm install my-release mercure/mercure

The chart includes settings for draining SSE connections during rolling updates. Persistent BoltDB deployments need the Recreate strategy; use a shared transport for rolling upgrades. See Kubernetes deployment for values, probes, and rootless setup.

#Mercure hub prebuilt binary

Download an archive for your OS from the release page and extract it.

MERCURE_EXTRA_DIRECTIVES='playground' \
./mercure run --config Caddyfile

The hub listens at https://localhost. For production, remove playground, configure publisher and subscriber verification keys, and set SERVER_NAME and MERCURE_TRUSTED_ISSUERS for your deployment.

macOS users: downloaded binaries may carry a quarantine attribute. If macOS blocks the downloaded binary, remove the quarantine attribute with xattr -d com.apple.quarantine ./mercure.

Windows users: allow inbound connections through Windows Defender Firewall only on the networks where you intend to expose the hub.

If port 80 or 443 is taken (Apache, NGINX, Skype), set SERVER_NAME=:3000 (or any free port) before starting.

#Mercure on Arch Linux

yay -S mercure

Available on the AUR. Or makepkg -sri against the PKGBUILD if you don't use an AUR wrapper.

#Custom Caddy build

If you need other Caddy modules in the same binary (rate limiting, OAuth, custom storage), build with xcaddy:

xcaddy build \
  --with github.com/dunglas/mercure/caddy

Or use the Caddy download page to assemble a build in the browser.

#Embedding the Mercure hub in a Go binary

Mercure is also a Go library. See pkg.go.dev/github.com/dunglas/mercure. You'd typically reach for it when you want to ship a hub as part of a larger Go binary; for everything else the standalone server is simpler.

A hub built without a publisher key leaves the publish endpoint unauthenticated (the protocol's closed-network deployment mode): such a hub must never be reachable from untrusted networks. The Caddy module refuses this configuration unless the embedding application opts in with AllowNoPublish.

#Verify the Mercure hub installation

curl --fail-with-body -i http://localhost:2019/mercure/health/ready

Expect 200 OK with a JSON body containing "status":"ok". Run this inside the container for Docker deployments: the admin API listens on the container's loopback interface.

#Next steps