CRE Workflows HubCRE Workflows Hub
  • Workflows
  • Chainlink repo
  • Sign in
CRE Workflows Hub
  • Workflows
  • Docs
  • Contribute workflow
  • Chainlink CRE Templates

A registry for Chainlink Runtime Environment workflows. List and share your CRE workflows without waiting for upstream approval.

Back to Docs

Easy CRE: Docker gateway for dev and test

Run CRE workflows continuously in development and testing instead of one-off cre workflow simulate. Use an HTTP gateway in a container so your backend or frontend can trigger workflows on demand or on a schedule before deploying to the official CRE platform.

Guide: Replicating the CRE + Docker System

This guide explains how to put your own Chainlink Runtime Environment (CRE) workflow in a Docker container, expose it via an HTTP gateway, and optionally run it on a schedule with in-container cron. It is based on the pattern used in this project (CRE simulate gateway) and is written so you can replicate the setup for your own workflow.


What You Get

  • HTTP gateway inside the container that accepts JSON payloads and runs cre workflow simulate <workflow> --http-payload @file.
  • Optional in-container cron that triggers a specific action (e.g. a "batch job" action) at a configurable schedule.
  • Same interface as a deployed CRE workflow: any service (e.g. your backend) can POST to the container instead of to the CRE platform, and get the same request/response shape.

You do not need to deploy the workflow to the CRE platform to use it; the container acts as a local/simulate variant.


Prerequisites

  • CRE CLI installed and (for onchain writes) logged in (cre login), or a CRE API key.
  • Docker (and optional: Infisical or another secret manager for env injection).
  • Your workflow project that compiles with CRE (e.g. cre-compile or cre workflow simulate from the workflow directory).

1. Workflow and Config

  • Have a CRE workflow in a directory (e.g. markets/) with:
    • Entry point (e.g. main.ts) that registers HTTP and optionally Cron triggers.
    • A config file (e.g. config.docker.json) read by the workflow for backendUrl, schedule, contracts, etc.
  • Config schedule (if you use cron): CRE uses a 6-field cron format: second minute hour day month day-of-week. Example: "*/30 * * * * *" = every 30 seconds. When running in Docker, the entrypoint can convert this to a 5-field host cron by dropping the first field (see below).

2. Gateway Server

Create a small HTTP server that:

  1. Accepts POST requests (e.g. to / or /trigger) with a JSON body.
  2. Writes the body to a temporary file.
  3. Runs:
    cre workflow simulate <workflowDir> --non-interactive --trigger-index 1 --http-payload @<tmpFile> --target <CRE_TARGET> [--broadcast]
  4. Reads stdout/stderr, parses the workflow result (e.g. JSON after a known prefix), and returns it as the HTTP response.

Important details:

  • Working directory: run cre from the project root so the workflow can resolve config and relative paths.
  • Secrets: the CRE CLI (and your workflow) need env vars (e.g. API keys, private keys). Either:
    • Inject them at container runtime (e.g. --env-file, -e, or Infisical in the entrypoint), and optionally write a .env in the working directory before calling cre so the workflow can load them.
    • Or mount a volume (e.g. ~/.cre) for CRE CLI auth and pass other secrets via env.
  • Broadcast: for actions that must write onchain, pass --broadcast to cre workflow simulate. You can derive this from the request body (e.g. body.broadcast === true) or from an env var (e.g. CRE_GATEWAY_BROADCAST=true) so every trigger in Docker is onchain.

Example flow (pseudocode):

POST /  body = { action: "createMarketsFromBackend", broadcast: true }
  -> write body to /tmp/cre-payload-<id>.json
  -> cre workflow simulate markets --non-interactive --trigger-index 1 --http-payload @/tmp/cre-payload-<id>.json --target docker-settings --broadcast
  -> parse stdout for "Workflow Simulation Result: {...}"
  -> return 200 + JSON or 502 on non-zero exit

3. Cron Trigger (Optional)

If you want the same "batch" action to run on a schedule inside the container:

  1. Cron script (e.g. gateway/cron-trigger.sh): a script that POSTs a fixed payload to the gateway. Example:

    #!/usr/bin/env bash
    PORT="${GATEWAY_PORT:-8080}"
    HOST="${GATEWAY_HOST:-localhost}"
    curl -sS -X POST "http://${HOST}:${PORT}" -H "Content-Type: application/json" -d '{"action":"createMarketsFromBackend","broadcast":true}'
    
  2. Entrypoint installs a crontab that runs this script at the desired schedule. The schedule can come from:

    • Env: e.g. CRE_CRON_SCHEDULE="*/10 * * * *" (5-field: minute hour day month dow).
    • Config file: read schedule from your workflow config (e.g. config.docker.json). If it is 6-field (CRE style), convert to 5-field by dropping the first (seconds) field, then install that as the crontab. Example: "*/30 * * * * *" → * * * * * (every minute).
  3. Start cron in the background in the entrypoint (e.g. cron or crond) so the cron daemon runs inside the container.


4. Entrypoint

The entrypoint script should:

  1. Optional – config file: if CRE_CONFIG_FILE is set and points to a file (e.g. mounted from the host), copy it to the workflow's config path (e.g. markets/config.docker.json) so the workflow uses your chosen backend URL, contracts, and schedule.
  2. Optional – cron:
    • If CRE_CRON_SCHEDULE is set, use it as the 5-field crontab.
    • Else, if the workflow config has a schedule field, read it, convert 6→5 if needed, and install the crontab.
    • Install the cron job that runs gateway/cron-trigger.sh and start the cron daemon.
  3. Optional – secrets: if you use Infisical (or similar), run the main process under infisical run ... -- "$@" so secrets are injected; otherwise rely on Docker env (exec "$@").
  4. Main process: start the HTTP gateway (e.g. bun run gateway/server.ts or node gateway/server.js).

Use a Debian-based image if you rely on the CRE CLI; Alpine (musl) can cause "cannot execute" for the CLI binary.


5. Dockerfile

  • Base: use a Debian-based runtime that matches how you run the gateway (e.g. Node/Bun).
  • Install:
    • CRE CLI (e.g. from https://cre.chain.link/install.sh into /opt/cre and add to PATH).
    • Dependencies for the entrypoint: curl, bash, cron, jq (for parsing config schedule).
    • Optional: Infisical CLI if you inject secrets in the entrypoint.
  • Copy: workflow directory, gateway (server + entrypoint + cron script), config, and any payload examples.
  • Precompile (optional): run cre-compile or a dry-run of cre workflow simulate so the first HTTP request doesn't pay compile time.
  • Env: set PORT, CRE_TARGET, and optionally CRE_GATEWAY_BROADCAST=true.
  • Entrypoint: the script that sets up config, cron, and then runs the gateway.

Example structure:

FROM oven/bun:1
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates bash cron jq && rm -rf /var/lib/apt/lists/*
ENV CRE_INSTALL=/opt/cre
ENV PATH="/opt/cre/bin:${PATH}"
RUN curl -sSL https://cre.chain.link/install.sh | bash
WORKDIR /app
COPY markets ./markets
COPY gateway ./gateway
RUN chmod +x /app/gateway/entrypoint.sh /app/gateway/cron-trigger.sh
RUN bun install --cwd ./markets
ENV PORT=8080
ENV CRE_TARGET=docker-settings
EXPOSE 8080
ENTRYPOINT ["/app/gateway/entrypoint.sh"]
CMD ["bun", "run", "gateway/server.ts"]

6. Running the Container

  • Port: map the gateway port (e.g. -p 8080:8080).
  • Backend reachable from container: if the workflow calls a backend on the host, use backendUrl: "http://host.docker.internal:4000" (or similar) and on Linux run Docker with --add-host=host.docker.internal:host-gateway.
  • Secrets: pass via -e, --env-file, or Infisical in the entrypoint. For CRE CLI auth you can use -v "$HOME/.cre:/root/.cre" after cre login on the host, or set CRE_API_KEY.
  • Config override: mount your config and set CRE_CONFIG_FILE=/config/cre.json (and copy it in the entrypoint to the workflow's config path).
  • Cron schedule: set CRE_CRON_SCHEDULE="*/10 * * * *" to override the config's schedule; otherwise the entrypoint can derive the schedule from the config's schedule field (6→5 conversion).

Example:

docker build -t my-cre-gateway .
docker run --rm -p 8080:8080 \
  --add-host=host.docker.internal:host-gateway \
  -e CRE_TARGET=docker-settings \
  -e CRE_CRON_SCHEDULE="*/10 * * * *" \
  -v "$(pwd)/markets/config.docker.json:/config/cre.json" \
  -e CRE_CONFIG_FILE=/config/cre.json \
  --env-file .env \
  my-cre-gateway

7. Using the Gateway from Your Backend

Point your backend at the container instead of at the CRE platform:

  • Set CRE_HTTP_URL=http://<host>:8080 (or the URL of the gateway).
  • For a cron-triggered action (e.g. createMarketsFromBackend), you can either:
    • Rely on the in-container cron to POST to the gateway at the schedule, or
    • Have the backend call the gateway on its own schedule (e.g. backend cron POSTs to CRE_HTTP_URL).

The request body must include the action (and any other fields your workflow expects); the gateway forwards the full body as the HTTP payload to cre workflow simulate.


Summary Checklist

StepDescription
1CRE workflow with HTTP (and optional Cron) trigger; config file for backend URL, schedule, etc.
2Gateway server: POST → write body to temp file → cre workflow simulate ... --http-payload @file → return parsed result.
3Optional: cron script that POSTs to the gateway; entrypoint installs crontab (from env or from config schedule 6→5) and starts cron.
4Entrypoint: optional config copy, optional cron setup, optional Infisical, then run gateway.
5Dockerfile: install CRE CLI, cron, jq; copy workflow + gateway; set PORT and CRE_TARGET; entrypoint + CMD.
6Run container with port map, host alias for backend, secrets, and optional CRE_CONFIG_FILE / CRE_CRON_SCHEDULE.
7Backend uses CRE_HTTP_URL to POST to the container as if it were the CRE platform.

This gives you a replicable CRE + Docker system: your workflow runs in a container, triggered by HTTP and optionally by in-container cron, with the same contract as a deployed CRE workflow.