Run recur in a container with multi-stage build, non-root user, and signal forwarding via tini.

Quick Start

Build and run with default plugins (timer, webhook):

  docker build -t recur .
docker run --rm -it recur
  

Or use Compose from this directory:

  docker compose up --build
  

Plugin Selection

Choose which plugins to include at build time with the RECUR_PLUGINS build arg:

  # Timer and webhook only (default)
docker build -t recur .

# All plugins
docker build --build-arg RECUR_PLUGINS="timer webhook mqtt calendar" -t recur .

# Webhook only
docker build --build-arg RECUR_PLUGINS="webhook" -t recur .
  

Available plugins: timer, webhook, mqtt, calendar, devicemonitor.

Version Injection

Pass a version string at build time:

  docker build --build-arg VERSION="1.0.0" -t recur .
  

This sets the version reported by recur version.

Volumes

PathPurpose
/home/recur/.recur/statePersistent state (JSON flat files). Mount a volume here to survive restarts.
/home/recur/.recur/config.yamlConfig file. Bind-mount your own config (read-only recommended).

Environment Variables

VariableDescription
RECUR_CONFIG_PATHPath to config file inside the container.
RECUR_SOCKETOverride daemon socket address. Set to a TCP address (e.g., 0.0.0.0:8080) to expose the gRPC API over the network instead of a Unix socket. Useful for proxy setups.

Socket and Proxy Use

By default, recurd listens on a Unix socket inside the container. To expose the gRPC API over TCP (e.g., behind an Envoy or nginx proxy), set RECUR_SOCKET:

  docker run --rm -it -e RECUR_SOCKET="0.0.0.0:8080" -p 8080:8080 recur
  

Or in docker-compose.yml:

  environment:
  RECUR_SOCKET: "0.0.0.0:8080"
  

Signal Handling

The container uses tini as PID 1 for proper signal forwarding. docker stop sends SIGTERM, which tini forwards to the daemon for a clean shutdown.

Health Check

The image includes a health check that runs recur status every 30 seconds (with a 10-second start period). Check container health with:

  docker inspect --format='{{.State.Health.Status}}' <container>
  

Compose

The included docker-compose.yml shows:

  • Building with selected plugins and version
  • Exposing port 8080 for the webhook plugin
  • Mounting a config file (read-only)
  • Persisting state with a named volume
  • Optional MQTT broker (commented out)

devicemonitor Caveats

The devicemonitor plugin monitors D-Bus for device events. This requires:

  • Running the container with --privileged or mounting the host D-Bus socket
  • The host must be running a D-Bus daemon

This is generally not practical in a container. Consider running devicemonitor on the host and connecting to a containerized recur instance via TCP socket instead.