From 712a82698e25b032c85399905cd7aea03dc3df77 Mon Sep 17 00:00:00 2001 From: NetworkCats <210240595+NetworkCats@users.noreply.github.com> Date: Thu, 22 Oct 2026 21:41:25 +0800 Subject: [PATCH] Fix Docker failing to start on first deploy The firewall role's "Reload systemd" handler shadowed the docker role's handler of the same name, and its flush_handlers ran the pending Docker restart right after base lowered fs.nr_open, without a daemon-reload. Docker then started without its LimitNOFILE override and systemd could not apply the default limit (status=205/LIMITS). Reload systemd inline in the firewall role instead of through a handler, so other roles' handlers keep running at the end of the play, and reload before ensuring Docker is running so a host left in this state recovers on the next deploy. Co-Authored-By: Claude Opus 5.5 --- deploy/ansible/roles/docker/tasks/main.yml | 3 +++ deploy/ansible/roles/firewall/handlers/main.yml | 4 ---- deploy/ansible/roles/firewall/tasks/main.yml | 7 +++---- 3 files changed, 6 insertions(+), 8 deletions(-) delete mode 100644 deploy/ansible/roles/firewall/handlers/main.yml diff --git a/deploy/ansible/roles/docker/tasks/main.yml b/deploy/ansible/roles/docker/tasks/main.yml index 3a07b81..eefdec2 100644 --- a/deploy/ansible/roles/docker/tasks/main.yml +++ b/deploy/ansible/roles/docker/tasks/main.yml @@ -41,11 +41,14 @@ mode: "0644" notify: Restart docker +# daemon_reload picks up the LimitNOFILE override below if it is already on +# disk; without it Docker cannot start once base lowers fs.nr_open. - name: Ensure Docker is enabled and running ansible.builtin.systemd: name: docker enabled: true state: started + daemon_reload: true - name: Configure Docker systemd override for unlimited file descriptors ansible.builtin.file: diff --git a/deploy/ansible/roles/firewall/handlers/main.yml b/deploy/ansible/roles/firewall/handlers/main.yml deleted file mode 100644 index c28484f..0000000 --- a/deploy/ansible/roles/firewall/handlers/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -- name: Reload systemd - ansible.builtin.systemd: - daemon_reload: true diff --git a/deploy/ansible/roles/firewall/tasks/main.yml b/deploy/ansible/roles/firewall/tasks/main.yml index 52176a8..8efbf74 100644 --- a/deploy/ansible/roles/firewall/tasks/main.yml +++ b/deploy/ansible/roles/firewall/tasks/main.yml @@ -39,16 +39,15 @@ loop: - ufw-cloudflare-sync.service - ufw-cloudflare-sync.timer - notify: Reload systemd - -- name: Apply systemd unit changes before enabling the timer - ansible.builtin.meta: flush_handlers +# Reload here rather than via a handler: flushing handlers mid-play would also +# run other roles' pending handlers (e.g. restarting Docker) out of order. - name: Enable daily Cloudflare IP sync ansible.builtin.systemd: name: ufw-cloudflare-sync.timer enabled: true state: started + daemon_reload: true - name: Sync Cloudflare IP ranges now ansible.builtin.command: /usr/local/sbin/ufw-cloudflare-sync