Skip to content

Releases: 6RUN0/docker-freeunit-php

v0.0.8

Choose a tag to compare

@github-actions github-actions released this 10 Jul 06:12

Added

  • .trivyignore listing the HIGH/CRITICAL CVEs in the Debian trixie base and the
    sury PHP / image-codec stack that have no upstream fix (none are in FreeUnit's
    own .deb packages, and none are resolvable by the apt full-upgrade the build
    already runs), so make scan and the CI scan surface only new, actionable
    findings instead of a permanent unfixable backlog.

Changed

  • Bumped the bundled FreeUnit .deb release to 1.35.6-build4 and recomputed the
    FREEUNIT_SHA256SUMS_SHA256 trust anchor. Upstream re-published the same
    1.35.6-1 package under a new release tag, so the bundled FreeUnit and PHP
    versions are unchanged — this is a rebuild-only refresh.

v0.0.7

Choose a tag to compare

@github-actions github-actions released this 28 Jun 12:51

Changed

  • Bumped the bundled FreeUnit .deb release to 1.35.6-build3 and recomputed the
    FREEUNIT_SHA256SUMS_SHA256 trust anchor. Upstream re-published the same
    1.35.6-1 package under a new release tag, so the bundled FreeUnit and PHP
    versions are unchanged — this is a rebuild-only refresh.

v0.0.6

Choose a tag to compare

@github-actions github-actions released this 17 Jun 09:34

Changed

  • FreeUnit rebrand (breaking for downstream images). Upstream renamed its
    Debian packages and on-disk identity from unit* to freeunit*, and the image
    follows suit: the daemon is freeunitd/freeunitd-debug, the state dir
    /var/lib/freeunit, the control socket /var/run/control.freeunit.sock, the log
    /var/log/freeunit.log, and the default application user/group freeunit (was
    unit). Downstream images must move any config.json user/group keys and
    any custom launch command from unit/unitd to freeunit/freeunitd; the
    reusable entrypoint library keeps its function names and UNIT_*/APPLICATION_*
    variable identifiers, so hooks that only call the documented API are unaffected.
  • Bumped the bundled FreeUnit .deb release to 1.35.6-build2 (1.35.6-1) and
    recomputed the FREEUNIT_SHA256SUMS_SHA256 trust anchor.
  • The brand identity is single-sourced as Dockerfile ARGs mirroring the upstream
    packaging vocabulary (BRAND, RUNTIME, RUNDIR, BRAND_TITLE, HOMEPAGE,
    DOCS_URL). They default to freeunit//var/run and the build now asserts the
    installed binary's compiled paths match RUNTIME/RUNDIR
    , so a future upstream
    identity change fails the build instead of shipping an image whose entrypoint
    manages paths the daemon does not use.
  • The default launch command moved out of the Dockerfile CMD into the entrypoint,
    and the HEALTHCHECK is now a script (/docker-healthcheck.sh), so the binary
    name and control-socket path stay single-sourced from docker-entrypoint-common.sh
    instead of being duplicated in an exec-form instruction that cannot expand a
    build ARG.

v0.0.5

Choose a tag to compare

@github-actions github-actions released this 09 Jun 17:53

Added

  • examples/ grew into a capability-coverage set: dev (a live-mounted
    development loop writing to a persistent state volume as the unprivileged app
    user), routing (multiple apps behind path routes, static-asset serving, and a
    per-app PHP memory_limit), and web-app (HTTPS from an entrypoint-generated
    self-signed certificate, with an HTTP-to-HTTPS redirect), alongside the existing
    basic and cron-hook. Each example is a self-contained subdirectory with its
    own README.
  • make test-examples: an examples gate that statically lints every example's
    compose file for the capability-hardening block (cap_drop, no-new-privileges,
    SETUID, SETGID), then builds, runs, and asserts each example end to end
    against the just-built image.
  • make help: a self-documenting target list parsed from the ##-prefixed
    comment annotations on the targets themselves.

Changed

  • The cron-hook example fires its task every second using supercronic's
    seven-field (seconds) crontab syntax, so the example and its test no longer wait
    out a full minute for a tick.
  • CI asserts the PHP build matrix is in sync across ci.yml, release.yml,
    security-scan.yml, and check-upstream.yml's completeness gate against the
    Makefile's PHP_VERSIONS, failing the lint job on any drift.
  • release.yml guards each Dockerfile-ARG extraction, failing loudly rather than
    pushing a malformed tag if an ARG line format ever drifts.
  • Repository hygiene: added .gitattributes, tightened .editorconfig, and
    ignored the docs/superpowers/ working notes.

Fixed

  • Documentation: corrected the deb.sury.org pin priority described in CLAUDE.md
    (990, not 1001 — below 1000 so a compromised mirror cannot force a downgrade) and
    the stale crontab field-count comments in the examples test, aligning the docs
    with the shipped Dockerfile and crontab.

v0.0.4

Choose a tag to compare

@github-actions github-actions released this 09 Jun 10:10

Added

  • Extensible entrypoint hook system: a child image adds a launch mode by dropping
    a handle_<command> hook into /docker-entrypoint-hook.d/ (sourced and
    ownership-vetted as root before any privilege drop), and the entrypoint became a
    thin dispatcher over a reusable core library (docker-entrypoint-common.sh) of
    logging, daemon lifecycle, config appliers, privilege drop, and user
    provisioning. Downstream images inherit every base robustness/security fix
    without overwriting /docker-entrypoint.sh.
  • examples/cron-hook/: an example of the hook system — one image runs in two
    roles, the Unit web server and a long-lived supercronic cron runner, selected
    per container by the command (supercronic is pinned and SHA256-verified).
  • test/entrypoint-lib.sh gained checks for the hook dispatch contract
    (dispatch_handler), the exec_as_user privilege drop, setup_user id
    validation and idempotency, the dir_has_content empty/non-empty boundary, and
    newline-less / non-numeric pidfiles. The host-side CLI parser and image build
    shared by both test drivers were extracted into test/lib.sh.

Changed

  • apply_config now warns when more than one *.json is present in
    /docker-entrypoint.d, since PUT /config replaces the whole configuration and
    only the lexically-last file survives.
  • wait_for_control_socket bounds each probe with curl --max-time, and
    run_entrypoint_scripts now reports which user script failed.
  • examples/ reorganised so each example is a self-contained subdirectory
    (examples/basic/, examples/cron-hook/) with an index README.md.
  • CI pins ShellCheck to the version used locally — the runner's bundled one
    flagged false positives on the library's optional-argument and
    trap/dispatch-invoked functions — and now lints each example's README.md.

Fixed

  • A child-hook handle_<cmd> that exits non-zero no longer aborts the entrypoint
    silently under set -e before its diagnostic. Dispatch moved into
    dispatch_handler, which reports both a non-zero exit and a return-without-exec
    with an actionable message.
  • stop_unit no longer skips kill -TERM when the pidfile has no trailing
    newline (read returns non-zero at EOF even after assigning the value). The new
    read_pid helper decouples the value from read's exit status and ignores a
    non-numeric pid, so a corrupt pidfile cannot become a broad kill.
  • dir_has_content treats an existing-but-unreadable directory as an error rather
    than "empty", so a transient EACCES on the state dir cannot trigger a
    re-initialisation over a populated state.

Security

  • exec_as_user now passes setpriv --no-new-privs, so a child-image hook's
    privilege drop is irreversible inside the image even if the operator omits
    --security-opt=no-new-privileges.
  • The first-run failure wipe (find … -delete) gained -xdev, so it stops at
    filesystem boundaries and never deletes through a host volume bind-mounted
    inside /var/lib/unit.
  • apply_certificates validates the bundle name to [A-Za-z0-9._-], so a crafted
    *.pem filename cannot retarget the control-API PUT at another endpoint.

v0.0.3

Choose a tag to compare

@github-actions github-actions released this 09 Jun 05:05

Added

  • Supply-chain attestations on release: release.yml now generates an SPDX SBOM
    for each pushed image and records keyless (OIDC) build-provenance and SBOM
    attestations, pushed to GHCR as OCI referrers of the image manifest. Verify a
    pulled image with
    gh attestation verify oci://ghcr.io/6run0/freeunit-php@<digest> --owner 6RUN0.
  • .github/workflows/check-upstream.yml: a weekly (and manually dispatchable)
    job that watches the FreeUnit package repo for a new release and opens a bump
    PR — it recomputes the pinned FREEUNIT_SHA256SUMS_SHA256 trust anchor and
    refuses to bump unless every matrixed PHP line ships a module .deb in the new
    SHA256SUMS.
  • .github/dependabot.yml: weekly grouped bump PRs for the SHA-pinned GitHub
    Actions.
  • CI lint job gained workflow and markdown gates: actionlint, zizmor (workflow
    security audit), and rumdl.
  • The CI trivy scan now emits SARIF and uploads it to GitHub code scanning, so
    CVEs surface in the Security tab and are tracked over time.
  • .github/workflows/security-scan.yml: a weekly (and manually dispatchable)
    trivy re-scan of the published GHCR images per PHP line, so CVEs disclosed
    after a release surface without a new push.
  • examples/: a self-contained, security-hardened deployment — a small
    Dockerfile bakes the app and its Unit config onto the published base image
    (config copied into /docker-entrypoint.d, no bind mounts), run with cap-drop
    and no-new-privileges hardening, with a worker that drops to the unit user.

Changed

  • CI build+smoke matrix now runs through Buildx with a per-PHP GitHub Actions
    layer cache (type=gha), so repeat runs reuse the apt/download layers instead
    of rebuilding from scratch; the trivy scan reuses the 8.4 image rather than its
    own build.
  • The smoke test now runs the container under the documented hardening
    (--cap-drop=ALL …), so a regression that breaks cap-dropped startup (such as
    a non-root-owned state directory) is caught in CI; the *.pem upload it already
    asserts exercises the affected certs store.

Fixed

  • The container aborted on startup under the README's own hardening recipe
    (--cap-drop=ALL …): /var/lib/unit was owned by unit:unit, so the root
    unitd master — stripped of CAP_DAC_OVERRIDE by the dropped capabilities —
    could not create its certs/ and scripts/ stores (mkdir … EACCES) and
    failed to store the configuration. The state directory is now kept root-owned
    (the master is root by design), so cap-dropped startup works; the per-app
    worker still drops to unit via the Unit config.

v0.0.2

Choose a tag to compare

@github-actions github-actions released this 08 Jun 15:14

Added

  • test/smoke.sh gained a --build flag (with --php X.Y) so a single
    invocation covers the whole build -> run -> assert pipeline; the PHP line is
    taken from --php, else parsed from the image ref's phpX.Y tag, else the
    Dockerfile ARG default. Without --build the script still tests a prebuilt
    image, so make test and the CI build+smoke step are unchanged.

Fixed

  • rootfs/docker-entrypoint.sh: stop the post-configuration daemon with an
    explicit if instead of the [ -f pid ] && kill … || true one-liner, fixing
    a ShellCheck SC2015 failure on the CI runner's shellcheck and stating the
    intent more clearly.
  • test/smoke.sh: poll the Unit control socket when verifying the uploaded
    certificate, fixing an intermittent CI failure where the controller had not
    finished restarting after initial configuration before the single probe ran.