Version 5.2.1
[5.2.1] — 2026-09-09
Recovery commands: re-sync GitHub/GitLab deploy keys and webhooks, and restore an app home to the permission model Cipi created it with.
Added
cipi git refresh [app]. Walks every app with a GitHub or GitLab repository (or one named app) and re-registers the local SSH deploy key plus the deploy webhook. Stale IDs inapps.jsonare replaced. Remote leftovers titledcipi:<app>or pointing at this app's webhook URL are removed first so duplicates are not left behind. Custom/SFTP apps get the key only. A missing or rejected PAT is reported per app (cipi git github-token/gitlab-tokenfirst).--rotate-keysmints a new ed25519 key and swaps it inauthorized_keys(Deployer still SSHs to localhost with it).--rotate-secretmints a newCIPI_WEBHOOK_TOKENinapps.jsonandshared/.env. Both ask before touching every app unless--force. If GitHub refuses the existing pubkey because it is already a deploy key on another repo, refresh generates a new key for that app and continues.cipi app fix-permissions [app]. The panel already hadcipi api fix-permissionsandcipi gui fix-permissions; apps did not. A bluntchown -R app:app /home/<app>is wrong: nginx writes vhost logs aswww-dataintologs/(2775 setgid), the home must stay 750 sowww-data(in the app group) can read the docroot,.sshmust be 700 or OpenSSH StrictModes refuses the deploy key, andshared/.envis 640. This command reapplies that layout — ownership of the tree exceptlogs/, then the log/ACL helper, storage dirs 775, Composerauth.json640,cipi-databases.env600. One named app, or every app. No migration:self-updatecopies the libs and refreshes shell completion. The panel sudoers file lists the new command so a future GUI can call it; existing servers pick that line up the next time sudoers is rewritten (the CLI runs as root and does not need it).
Fixed
self_updatemail on a same-version refresh. The nightly cron always copies the libs even whenversion.mdhas not moved. Theself_updateemail is now decided from a snapshot taken before/etc/cipi/versionis rewritten, and is sent only when that snapshot differs from the downloaded version. A refresh that stays on the same release is silent.
Notes
- Deploy keys and webhooks on GitHub/GitLab do not vanish when a PAT expires — they only become unmanageable via API. Refresh is for the case where they were deleted, the stored IDs drifted, or you just installed a new token and want every app re-attached.
cipi deployalready runs the log-ACL helper before Deployer.fix-permissionsis the full home, on demand, after someone unpacked a zip as root or chmod'd.sshto 775.