You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Docker: hiddify apply and the panel's "Apply Changes" never run after container start, because daemons inherit the 0-install.lock file descriptor #5655
Description: Docker: hiddify apply and the panel's "Apply Changes" cannot run after the container has started, because every daemon inherits the 0-install.lock file descriptor and keeps the lock held.
Details:
Hiddify Version: 14.1.0b2 Python Version: 3.13.18 (main, Oct 26 2026, 14:08:20) [Clang 23.1.3 ] OS: Linux-6.8.0-117-generic-x86_64-with-glibc2.39 User Agent: Unknown
Setup
Docker, docker-compose.yml from dev (network_mode: host), image ghcr.io/hiddify/hiddify-manager:beta (rev 29036f70b7). The relevant code (set_lock and the systemctl shim) is identical in dev and main.
Problem
After the container has started, hiddify apply always fails, although no install/apply is running:
$ docker exec hiddify-manager-hiddifymanager-1 hiddify apply --no-gui
Another installation is running.... Please wait until it finishes.
The panel is affected too. Its Apply API (start_action in apply_api.py) calls check_can_start, which aborts with 409 "Another action is still running", because _lock_held("0-install") is true while the daemons hold the descriptor. In the admin UI (Apply & Status) the card keeps showing the previous "Reinstall finished, 100%, 0:00" and nothing is applied (I did not trace why the UI shows that instead of the error).
The only way to apply settings is to restart the container, which re-runs the apply at boot.
Cause
set_lock (scripts/common/utils.sh) does exec {HIDDIFY_LOCK_FD}>"$(lock_file "$1")" and flock -n on it. The descriptor is inheritable and nothing closes it for child processes. Services are started through the bundled systemctl shim (services/docker/systemctl), which uses os.fork() + os.setsid() + os.execve() in execve_from() and never closes inherited descriptors, so every daemon keeps the lock open after the apply has finished (an flock is released only when all copies of the open file are closed).
Holders of the lock file in a running container (fd 10):
@hiddify-com Thanks for the detailed analysis. Flagging this: in Docker (14.1.0b2), daemons inherit the 0-install.lock descriptor from set_lock, so hiddify apply and the panel's Apply Changes are blocked until the container restarts. Workaround for now: docker compose restart hiddifymanager.
Activity
hiddify-com commentedon Oct 29, 2026
@hiddify-com Thanks for the detailed analysis. Flagging this: in Docker (14.1.0b2), daemons inherit the
0-install.lockdescriptor fromset_lock, sohiddify applyand the panel's Apply Changes are blocked until the container restarts. Workaround for now:docker compose restart hiddifymanager.