Mercure.rocksSponsored by Les-Tilleuls.coop
Contribute!

Install the Mercure.rocks Hub

Cloud and Enterprise Versions

The easiest way to get started with Mercure is to subscribe to the Cloud version. Give it a try!

Prebuilt Binary

The Mercure.rocks Community hub (free and open-source) is available as a custom build of the Caddy web server including the Mercure.rocks module.

First, download the archive corresponding to your operating system and architecture from the release page, extract the archive and open a shell in the resulting directory.

Note: macOS users must download the Darwin binary, then run xattr -d com.apple.quarantine ./mercure to release the hub from quarantine.

To start the Mercure.rocks Hub in development mode on Linux and macOS, run:

MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \
MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \
./mercure run --config dev.Caddyfile

On Windows, start PowerShell, go into the extracted directory and run:

$env:MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!'; $env:MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!'; .\mercure.exe run --config dev.Caddyfile

Note: The Windows Defender Firewall will ask you if you want to allow mercure.exe to communicate through it. Allow it for both public and private networks. If you use an antivirus, or another firewall software, be sure to whitelist mercure.exe.

The server is now available on https://localhost (TLS is automatically enabled; learn how to disable it). In development mode, anonymous subscribers are allowed and the debug UI is available at https://localhost/.well-known/mercure/ui/.

Note: If you get an error similar to bind: address already in use, it means that port 80 or 443 is already used by another service (the usual suspects are Apache and NGINX). Before starting Mercure, stop the service using the port(s) first, or set the SERVER_NAME environment variable to use a free port (e.g., SERVER_NAME=:3000).

To run the server in production mode, run this command:

MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \
MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \
./mercure run

In production mode, the debugger UI is disabled and anonymous subscribers aren't allowed. To change these default settings, learn how to configure the Mercure.rocks Hub.

When the server is up and running, the following endpoints are available:

  • POST https://localhost/.well-known/mercure: to publish updates

  • GET https://localhost/.well-known/mercure: to subscribe to updates

See the protocol for more details about these endpoints.

To compile the development version, see https://github.com/dunglas/mercure/blob/master/CONTRIBUTING.md.

Docker Image

A Docker image is available on Docker Hub. The following command is enough to get a working server in development mode:

docker run \
    -e MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \
    -e MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \
    -p 80:80 \
    -p 443:443 \
    dunglas/mercure caddy run --config /etc/caddy/dev.Caddyfile

Note: Docker images before tag v0.16.2 use Caddyfile.dev instead of dev.Caddyfile

The server is then available on https://localhost. Anonymous subscribers are allowed and the debugger UI is available on https://localhost/.well-known/mercure/ui/.

In production, simply run:

docker run \
    -e MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \
    -e MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \
    -p 80:80 \
    -p 443:443 \
    dunglas/mercure

HTTPS support is automatically enabled. If you run the Mercure hub behind a reverse proxy such as NGINX, you usually want to use unencrypted HTTP. This can be done as follows:

docker run \
    -e SERVER_NAME=':80' \
    -e MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \
    -e MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \
    -p 80:80 \
    dunglas/mercure

The Docker image is based on the Caddy Server Docker image. See the configuration section and the documentation for the Caddy Docker image to learn how to configure it to fit your needs.

Kubernetes

Use the Helm package manager to install Mercure on a Kubernetes cluster:

To install the chart with the release name my-release, run the following commands:

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

See the list of available values for this chart.

Rootless Deployment (Kubernetes)

Run the hub as a non-root user with every capability dropped. Modern container runtimes (containerd 1.5+, cri-o) set net.ipv4.ip_unprivileged_port_start=0 inside the container, so an unprivileged process can bind any port directly, including 80 and 443. The chart mounts /data, /config, and /tmp as writable volumes so readOnlyRootFilesystem: true works out of the box:

# values.yaml
podSecurityContext:
  runAsNonRoot: true
  runAsUser: 1000
  runAsGroup: 1000
  fsGroup: 1000
  seccompProfile:
    type: RuntimeDefault
securityContext:
  allowPrivilegeEscalation: false
  capabilities:
    drop: [ALL]
  readOnlyRootFilesystem: true
  runAsNonRoot: true
  runAsUser: 1000

If your runtime is older (or you've explicitly raised ip_unprivileged_port_start above 80), set service.targetPort to an unprivileged port (e.g. 8080); the Service still exposes :80 to the cluster.

When persistence is enabled, fsGroup ensures the volume is writable by the chosen UID.

Docker Compose

If you prefer to use docker compose to run the Mercure.rocks Hub, here's a sample service definition:

# compose.yaml
services:
  mercure:
    image: dunglas/mercure
    restart: unless-stopped
    environment:
      # Uncomment the following line to disable HTTPS
      #SERVER_NAME: ':80'
      MERCURE_PUBLISHER_JWT_KEY: "!ChangeThisMercureHubJWTSecretKey!"
      MERCURE_SUBSCRIBER_JWT_KEY: "!ChangeThisMercureHubJWTSecretKey!"
    # Uncomment the following line to enable the development mode
    #command: /usr/bin/caddy run --config /etc/caddy/dev.Caddyfile
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - mercure_data:/data
      - mercure_config:/config

volumes:
  mercure_data:
  mercure_config:

The image ships a HEALTHCHECK that queries the transport-aware /mercure/health/ready endpoint on the Caddy admin API.

Rootless Deployment

The image runs as root by default, but Docker (since 20.10) sets net.ipv4.ip_unprivileged_port_start=0 inside the container, so an unprivileged process can bind any port directly, including 80 and 443. To run rootless, set the user key:

# compose.yaml
services:
  mercure:
    image: dunglas/mercure
    user: "1000:1000"
    read_only: true
    tmpfs:
      - /tmp
    restart: unless-stopped
    environment:
      MERCURE_PUBLISHER_JWT_KEY: "!ChangeThisMercureHubJWTSecretKey!"
      MERCURE_SUBSCRIBER_JWT_KEY: "!ChangeThisMercureHubJWTSecretKey!"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - mercure_data:/data
      - mercure_config:/config

volumes:
  mercure_data:
  mercure_config:

The /data and /config volumes must be writable by the chosen UID. For fresh named volumes, pre-set ownership once:

docker run --rm -v mercure_data:/data -v mercure_config:/config alpine chown 1000:1000 /data /config

For bind mounts, run chown 1000:1000 on the host directory.

Alternatively, you may want to run the Mercure.rocks hub behind Traefik Proxy.

Arch Linux

Mercure.rocks is available on the AUR. You can install it with your favorite AUR wrapper:

yay -S mercure

Or download the PKGBUILD and compile and install it: makepkg -sri.

Custom Caddy Build

It's also possible to download Caddy with Mercure and other modules included, or to build your own binaries using xcaddy:

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

Mercure.rocks is shipped by several popular services and frameworks, including Symfony and API Platform. Refer to their documentation to get started.