Stack256 · 004

Scheduling and bookings on your own server.

Share a booking link, set your availability, and let invitees pick a time — no back-and-forth email. Runs on your own server, on your own database, with nothing phoning home.

What makes it different

Most of these follow from one decision: it is a real application you run on your own server, not a service someone else hosts.

  • No account to make

    Invitees pick a time with a name and an email — no password, no registration wall. The link takes them back to read confirmations and updates.

  • Email that keeps trying

    Outgoing mail is queued and retried rather than quietly dropped when your provider has a bad day. No-show reminders and confirmations are durable, not best-effort.

  • Health checks that mean something

    GET /api/health runs a real query against your database — not just whether the process is alive. The container’s own Docker HEALTHCHECK uses it, so a load balancer or uptime monitor sees the same truth your orchestrator does.

  • Admin screens where you work

    User management, queue state, and platform settings live under /settings/* inside the dashboard, gated by role. No separate admin panel, no second login.

  • Config that refuses to start broken

    Every variable is validated at boot. A missing or invalid required value makes the app refuse to start and print exactly which one failed — rather than breaking halfway through a request.

  • Your storage, your way

    Local disk in development; S3 or Cloudflare R2 in production, one setting. Your data stays where you put it.

Installing it

You need Docker, and nothing else. No separate Node.js or PostgreSQL install — the images are prebuilt and PostgreSQL comes with them.

  1. Get the two files

    A compose file and an environment file. That is the whole setup.

    curl -O https://raw.githubusercontent.com/stack256org/scheduled/main/docker-compose.yml
    curl -o .env https://raw.githubusercontent.com/stack256org/scheduled/main/.env.docker.example
  2. Set three values

    APP_SECRET (32+ random characters, from openssl rand -hex 32), APP_URL, and DATABASE_URL. Everything else has a working default.

  3. Start it

    This pulls both images, starts PostgreSQL, migrates the database, and leaves the app and worker running.

    docker compose up -d
  4. Open it

    First run walks you through creating the admin account. No separate terminal step needed.

    http://<this host’s address>/

You need two images. The app (ghcr.io/stack256org/schduled) serves traffic, and the worker (ghcr.io/stack256org/schduled-worker) sends email and runs background jobs — nothing sends without it. The compose file starts both for you.

What it needs

Host Anything that runs containers — Compose, Coolify, Dokploy, Portainer, Kubernetes, Swarm, ECS
Images ghcr.io/stack256org/schduled and ghcr.io/stack256org/schduled-worker
Architectures amd64 and arm64, in every tag
Processes The app, a worker (email and background jobs), and a one-off migrate step
Database PostgreSQL 16+ — bundled, or point it at your own (Neon, Supabase, RDS)
File storage Local disk, S3, or Cloudflare R2 — one setting
Health check GET /api/health, unauthenticated, reports database reachability
Licence MIT

Have a look at the code

Schduled is the fourth of 256. The README covers full production setup, HTTPS, backups, and everything else in detail.