Skip to content

Features

Health-gated Docker updates, by default.

freshdock runs the full update cycle (check, pull, recreate, verify, clean up) and treats “did the new container actually come up healthy?” as the gate for every update. Here’s how each part works. For exact flags and tables, the reference docs ↗ are the source of truth.

The recreate lifecycle

A container is “updated” only once it proves healthy.

Whether triggered manually or by the scheduler, every update runs the same gated cycle, and reverts on failure.

  1. 01

    inspect

    Capture the running container’s full config.

  2. 02

    pull

    Fetch the new image.

  3. 03

    stop

    Gracefully stop the old container.

  4. 04

    rename

    Archive it as <name>-old-<ts>, the rollback source.

  5. 05

    create

    Recreate from the same config + new image.

  6. 06

    start

    Bring the new container up.

  7. 07

    health-gate

    Wait for healthy, or the grace period.

healthy

The archive is removed; the update stands. Opt in to also delete the superseded image with freshdock.cleanup=true.

timeout / crashed → roll back

The failed container is removed and the archive is renamed back and restarted. You’re left running exactly what you had, and a failed notification is sent.

timings (currently hardcoded): health timeout 120s · grace period 10s · poll 1s

Verdicts, grace periods, and image cleanup in full → health & rollback docs ↗.

Per-container modes

Mix update strategies on one daemon.

Each opted-in container picks a freshdock.mode. The scheduler polls live/watch on an interval and fires calendar modes on cron, overridable per container with freshdock.schedule. The default, watch, never restarts anything.

Cron fields, DST handling, and missed-window behaviour → scheduling docs ↗.

freshdock update modes and what each one does
modewhen it actswhat it does
liveevery --interval (default 300s)Pull and recreate on every new digest.
nightlycron 0 4 * * * (04:00 daily)Recreate if a newer image exists.
weeklycron 0 4 * * 0 (04:00 Sunday)Recreate if a newer image exists.
monthlycron 0 4 1 * * (04:00 on the 1st)Recreate if a newer image exists.
watchevery --intervalReport only: notify, never pull or restart. The default.
offneverIgnored by the scheduler entirely.

Five registries

Digest checks use rate-friendly HEAD requests (not full pulls), anonymous or authenticated.

  • Docker Hubanonymous + authenticated
  • GHCRghcr.io · PAT or public
  • Quay.ioquay.io
  • lscr.ioLinuxServer
  • Any OCI registrybearer-token auth

PAT scopes & credentials → registry auth ↗.

Four notifiers

Each target subscribes to just the events it wants: available, succeeded, failed.

  • Webhookgeneric JSON POST
  • Discordcoloured embed
  • TelegramBot API message
  • SMTPemail, STARTTLS or implicit TLS

Payloads & the event matrix → notifications ↗.

Optional, best-effort cleanup

A healthy update always removes the replaced container archive. Opt in to also delete the superseded image (freshdock.cleanup or [settings] cleanup), and (separately) enable a daemon-wide dangling-image prune ([settings] prune_dangling). A shared base image still in use is kept. Cleanup never fails an update, and freshdock never removes volumes.

One static binary

Built in Rust as a single static-musl binary, ≤ 10 MB, no runtime dependencies. The multi-arch image (amd64, arm64, armv7) is a thin wrapper, not a 100 MB runtime sitting beside the containers it manages.

Compatibility

Where it runs, and where it doesn’t.

Plain Docker (24.x to 29+)Primary target
Docker Desktop (Linux/macOS/Win)Supported
Portainer (CE & Business)Same Docker socket
Podman 4+Docker-compatible socket
Dockge / Komodo & compose UIsPer-container; compose files untouched
Kubernetes / SwarmOut of scope; use platform-native

Three commands

check · recreate · run

$freshdock check

Read-only status table. Lists opted-in containers, resolves the latest digest per unique image, reports what has updates. Never mutates.

$freshdock recreate <name>

Manually update one container: inspect → pull → stop → rename → create → start, health-gated with rollback. Refuses containers you’ve opted out.

$freshdock run

The scheduler daemon. Each tick it acts on due containers per their mode; watch is report-only. Graceful SIGINT/SIGTERM drain.

Every flag and example → CLI reference ↗.

Try it read-only first.

freshdock check changes nothing. It just shows you what would update. Install it and run that before you trust it with a thing.

Install freshdock