Sign inSign up

ricariel/localkit

By ricariel

•Updated 3 days ago

Image
0

3.7K

ricariel/localkit repository overview

⁠Localkit

This project aims to provide local control of Petkit devices. It communicates directly with your devices on your local network and creates entities in Home Assistant over MQTT for seamless integration.

⁠About this fork

This is the pyrox fork of dwyschka/localkit⁠. It carries its own image (see "Image layout") and code changes on top of upstream main. The main one, offered upstream as a pull request: CLOUD_STORAGE recordings are encoded to MP4 once per event instead of on every ~4 s segment (see fix/cloud-storage-encode). Re-encoding the whole event on every segment made the upload request grow quadratically with the event length, and device retries ran two encodes at once; the container was OOM-killed on longer events.

Smaller fixes: dev_multi_config answers without a device implementation instead of HTTP 500 (W7H), the device edit form no longer resets times to 00:01 (cherry-picked from upstream beta), and the Services page copes without s6.

The fork releases with the shared Forgejo workflows from pyrox/actions, copied unchanged from its templates. Forgejo runs only .forgejo/workflows, so the upstream GitHub workflow stays inactive here.

WorkflowTriggerResult
semver-bump.yamlpush to mainraises .bumpversion.toml and tags vX.Y.Z, only if files that end up in the image changed
docker.yamltag v*, Mondays 05:15, manualbuilds the latest tag as X.Y.Z, X.Y, X and latest

Repository variables: IMAGE_NAME=localkit, and SEMVER_RELEASE_PATHS with the same exclusion list as the build's relevant-paths (the image copies the whole repository, so everything except CI files counts).

Deployments pin the version tag without a digest. The weekly rebuild pushes the same version tag again, and the Forgejo registry deletes the previous manifest of an overwritten tag: a pinned digest of an older build returns 404. The version tag itself always resolves.

The fork's versions continue from upstream 1.2.0, the last upstream tag in its history, and are independent of later upstream versions.

New settings:

VariableDefaultMeaning
LOCALKIT_CLOUD_STORAGE_ENCODE_DELAY60Seconds without a new segment before an event is encoded
LOCALKIT_FFMPEG_THREADS2libx264 threads for that encode; memory grows with it
LOCALKIT_FFMPEG_TIMEOUT900Time limit of one encode in seconds

The encode runs from the Laravel scheduler (localkit:encode-cloud-storage every minute), so a scheduler must run. A queue worker is not required: with QUEUE_CONNECTION=sync the job runs inside the scheduler.

⁠Image layout

The fork does not build on upstream's base image ghcr.io/dwyschka/localkit-docker (serversideup/php with nginx and s6), which was last rebuilt in August 2026 and stayed on PHP 8.4.24. The Dockerfile here starts from the official php:<version>-fpm-trixie image with an exact PHP version that Renovate updates; renovate.json keeps it on PHP 8.4. Extensions come from install-php-extensions (gd, intl, opcache, pcntl, pdo_mysql, pdo_pgsql, zip; no redis, which Localkit does not use), Composer installs without dev packages, and Debian's ffmpeg handles recordings and thumbnails. The go2rtc binary of the old base image is gone: every camera runs its own go2rtc, and Localkit only talks to that over HTTP (config/go2rtc.php).

The image runs php-fpm only, as www-data, with tini as PID 1. Each Localkit process is a container of its own in the same pod, started from the same image:

ContainerCommandReplaces
init containerlocalkit-init /exportserversideup's AUTORUN (migrations)
php-fpmdefault command, 127.0.0.1:9000php-fpm under s6
nginxnginxinc/nginx-unprivileged with docker/nginx/localkit.confnginx under s6
listenerphp artisan localkit:listens6 service localkit-listen
Home Assistant bridgephp artisan localkit:homeassistants6 service localkit-homeassistant
schedulerphp artisan schedule:works6 service localkit-scheduler

localkit-init (docker/localkit-init) copies public/ and the nginx configuration into a volume shared with the nginx container, so nginx always serves the files of the running image, and then runs php artisan migrate --force. nginx listens on 8080 (HTTP) and 8443 (HTTPS) and expects the device certificate as /etc/nginx/tls/tls.crt and tls.key. docker/php/ holds the PHP and php-fpm settings, with the same limits as the old base image (256M memory, 100M uploads).

Without s6 the System, Services page of the web UI is hidden. A process that exits restarts its container; sh -c 'kill 1' inside a container restarts it on purpose, for example the Home Assistant bridge after adding a device, as it publishes the discovery messages only on start.

The deployment in pyrox/k3s-prod (apps/localkit) shows the complete pod.

Back to upstream: once upstream contains the change and its image ships a current PHP, point deployments back to ghcr.io/dwyschka/localkit (one container with nginx and s6) and archive this repository. Until then, sync with git fetch upstream && git merge upstream/main on a branch and open a pull request here. Upstream changes to Dockerfile, s6/ or entrypoint.d/ do not apply to this image and show up as conflicts; keep this layout and carry over only what the app needs (a new service becomes a container in the deployment). Do not push upstream's tags (1.2.0 and older, without v) here: scheduled builds check out the latest tag, and would then publish upstream code without the fork's changes.

⁠Requirements

As an internal MQTT broker, localkit-broker⁠ is required for the system to function correctly.

⁠Supported Devices

Litter boxes

  • Petkit Pura Max (t4)
  • Petkit Purobot Crystal (t7)

Feeders

  • Petkit Fresh Element 3 (d3)
  • Petkit Fresh Element Solo (d4)
  • Petkit Yumshare Solo (d4h)
  • Petkit Yumshare Dual (d4sh)

Water fountains

  • Petkit Eversweet Ultra (w7h)

Bluetooth accessories

  • K3 Spray (k3)
  • Eversweet Fountain (w5)

⁠Home Assistant

Localkit integrates with Home Assistant over MQTT, automatically exposing your Petkit devices as entities via MQTT discovery. See the Home Assistant integration guide⁠ for setup details.

⁠Documentation

For full setup instructions, the complete list of exposed entities, and detailed documentation, visit localkit.io⁠.

Tag summary

Content type

Image

Digest

sha256:825e5bf67…

Size

369.3 MB

Last updated

3 days ago

docker pull ricariel/localkit