Skip to content

ianuriegas/cinnamon

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cinnamon

A job orchestration framework powered by BullMQ, Postgres, and Hono. Define jobs in a config file, trigger them via CLI, HTTP API, or cron, and monitor everything through a built-in dashboard.

  • Language-agnostic -- run Python, Bash, Node, or any command. If it runs in a shell, cinnamon can orchestrate it.
  • Multi-tenant -- teams and API keys isolate workloads. Each job run is scoped to the team that triggered it. The dashboard is team-scoped for regular users; super admins see all.
  • Durable -- every run is logged to Postgres with status, stdout, stderr, timing, and structured results.
  • Observable -- query job history, inspect runs, check schedules, and stream live logs through the REST API or dashboard.
  • Notifiable -- get Slack, Discord, or generic webhook notifications on job success or failure.

Architecture

flowchart LR
  CLI["CLI"] --> Queue["BullMQ (Redis)"]
  API["API server (Hono)"] -->|"POST /v1/jobs/:name/trigger"| Queue
  Dashboard["Dashboard (React)"] -->|"/api/dashboard/*"| API
  Queue --> Worker[worker]
  Worker --> Handler[job handler]
  Worker --> JobsLog["cinnamon.jobs_log (Postgres)"]
Loading

Getting started

Requires Bun and Docker Compose.

New project

The fastest way to start is bun create cinnamon:

bun create cinnamon my-app
cd my-app

The scaffolding wizard sets up a working Cinnamon instance with Postgres, Redis, the dashboard, and an example job. Start infrastructure, then run:

docker compose up -d postgres redis
bun run db:migrate
bun run seed:team              # creates a team + API key (save the cin_... key)

Open two terminals:

bun run worker   # terminal 1
bun run dev      # terminal 2

Open http://localhost:5173/dashboard to view the dashboard.

cinnamon init                   # paste your API key when prompted
cinnamon trigger hello-world    # trigger a job
cinnamon status hello-world     # check the result

Development (clone the repo)

If you want to contribute or work on the framework itself:

git clone https://github.com/ianuriegas/cinnamon.git
cd cinnamon
bun install
cp .env.example .env
docker compose up -d postgres redis
bun run db:migrate
bun run seed:team

Then start the worker and dev server as above.

How to add a job

Three steps: config, script, trigger.

1. Define the job in cinnamon.config.ts:

export default defineConfig({
  jobs: {
    "my-job": {
      command: "python3",
      script: "./jobs/my-job/my-script.py",
      timeout: "30s",
      description: "My custom job",
    },
  },
});

Any command that can run in a shell works -- python3, bash, bun, node, curl, etc.

2. Create the script at the path you specified:

# jobs/my-job/my-script.py
import json

result = {"processed": 42, "status": "ok"}
print(json.dumps(result))  # last line of JSON stdout → stored in jobs_log.result

3. Trigger it:

cinnamon trigger my-job              # via CLI
# or
curl -X POST http://localhost:3000/v1/jobs/my-job/trigger \
  -H "Authorization: Bearer cin_<your_key>"

Add a schedule field (cron syntax) to run it automatically:

"my-job": {
  command: "python3",
  script: "./jobs/my-job/my-script.py",
  timeout: "30s",
  schedule: "0 * * * *",  // every hour
},

See Jobs and config and Writing scripts for the full spec.

Notifications

Jobs can send webhooks on success or failure. Cinnamon auto-detects Discord and Slack URLs and formats messages accordingly; any other URL receives a generic JSON payload.

"my-job": {
  command: "python3",
  script: "./jobs/my-job/my-script.py",
  timeout: "30s",
  notifications: {
    on_failure: [{ url: "${DISCORD_WEBHOOK_URL}" }],
    on_success: [{ url: "${SLACK_WEBHOOK_URL}" }],
  },
},

${VAR} references are resolved from environment variables at runtime.

Using as a submodule

Cinnamon is designed to be added as a git submodule inside your project. This keeps your jobs and config in your repo while pulling in the framework.

git submodule add https://github.com/ianuriegas/cinnamon.git cinnamon

Docker Compose merge

Use Docker Compose's merge feature to layer your app on top of cinnamon's base services:

docker compose -f cinnamon/docker-compose.yml -f docker-compose.override.yml up -d

Your override file adds project-specific config (env vars, volumes, extra services) while inheriting Postgres, Redis, worker, scheduler, and API from cinnamon.

See examples/deploy/docker/ for a working override example.

Migrations

Cinnamon tables live in a dedicated cinnamon Postgres schema, so they never collide with your app's tables. Run cinnamon's migrations separately from your own:

cd cinnamon && bun run cinnamon:migrate && cd ..

See Migrations for the full dual-migration setup.

Dashboard auth (optional)

The dashboard is open by default for local dev. To require Google sign-in:

  1. Place your GCP OAuth client_secret.json in the project root (or set GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET in .env).
  2. Generate a session secret and add it to .env:
bun run generate:secret

Paste the output as SESSION_SECRET in .env.

  1. For local dev with bun run dev (Vite on port 5173), create .env.local with BASE_URL=http://localhost:5173 so the OAuth callback and session cookie use the same origin. Keep BASE_URL=http://localhost:3000 in .env for Docker/production. .env.local overrides .env when running locally and is gitignored.

  2. Set super-admin emails (these users get full dashboard access on first login):

SUPER_ADMINS=you@gmail.com,teammate@gmail.com
  1. Optionally enable access requests so non-admin users can request dashboard access:
ACCESS_REQUESTS_ENABLED=true

When SESSION_SECRET is unset, auth is disabled and the dashboard remains open.

See Access requests for the full operator guide and .env.example for all options.

Docs

About

Self-hosted job orchestration: BullMQ, Postgres, Hono. Config-driven jobs, CLI/API/cron triggers, React dashboard, multi-tenant.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors