Add healthchecks to download-stack, deploy playbook, and mealie resource limits

nzbget and rutorrent share gluetun's network namespace via
network_mode: service:gluetun. When autoheal restarts gluetun,
the dependent containers lose their network and fail silently.

Added healthchecks so autoheal detects and restarts them too:
- nzbget: curl localhost:6789
- rutorrent: curl localhost:80
- depends_on changed to condition: service_healthy

New deploy-download-stack.yml playbook stages startup (gluetun
first, wait for healthy, then dependents) since the LXC host
lacks Python requests for community.docker modules.

Also added resource limits to mealie (512M memory, 1 CPU).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Maddox 2026-01-27 23:47:40 +00:00
parent 77b153a054
commit 394a973d6c
3 changed files with 92 additions and 2 deletions

View file

@ -52,6 +52,11 @@ services:
labels: labels:
- "com.centurylinklabs.watchtower.enable=true" - "com.centurylinklabs.watchtower.enable=true"
- "autoheal=true" - "autoheal=true"
deploy:
resources:
limits:
memory: 512M
cpus: '1.0'
networks: networks:
proxy: proxy:

View file

@ -64,6 +64,12 @@ services:
- /mnt/nas/downloads/nzbget:/downloads - /mnt/nas/downloads/nzbget:/downloads
- /mnt/nas/media:/media - /mnt/nas/media:/media
network_mode: service:gluetun network_mode: service:gluetun
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:6789 || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
deploy: deploy:
resources: resources:
limits: limits:
@ -72,7 +78,8 @@ services:
reservations: reservations:
memory: 256M memory: 256M
depends_on: depends_on:
- gluetun gluetun:
condition: service_healthy
restart: unless-stopped restart: unless-stopped
labels: labels:
- "autoheal=true" - "autoheal=true"
@ -96,8 +103,15 @@ services:
- /mnt/nas/downloads/rutorrent:/downloads - /mnt/nas/downloads/rutorrent:/downloads
- /mnt/nas/media:/media - /mnt/nas/media:/media
network_mode: service:gluetun network_mode: service:gluetun
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:80 || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
depends_on: depends_on:
- gluetun gluetun:
condition: service_healthy
restart: unless-stopped restart: unless-stopped
deploy: deploy:
resources: resources:

View file

@ -0,0 +1,71 @@
---
- name: Deploy Download Stack (gluetun + nzbget + rutorrent)
hosts: download-stack
become: true
vars:
service_dir: /home/docker/appdata/download-stack
compose_src: "{{ playbook_dir }}/../compose-files/download-stack/download-stack"
tasks:
- name: Create download-stack directory
file:
path: "{{ service_dir }}"
state: directory
mode: '0755'
- name: Ensure download network exists
shell: docker network inspect download >/dev/null 2>&1 || docker network create download
changed_when: false
- name: Copy docker-compose.yml
copy:
src: "{{ compose_src }}/docker-compose.yml"
dest: "{{ service_dir }}/docker-compose.yml"
mode: '0644'
backup: yes
- name: Check if local .env exists
delegate_to: localhost
become: no
stat:
path: "{{ compose_src }}/.env"
register: local_env
- name: Copy .env file (if local copy exists)
copy:
src: "{{ compose_src }}/.env"
dest: "{{ service_dir }}/.env"
mode: '0600'
when: local_env.stat.exists
- name: Pull images
shell: docker compose pull
args:
chdir: "{{ service_dir }}"
- name: Start gluetun first
shell: docker compose up -d --force-recreate gluetun
args:
chdir: "{{ service_dir }}"
- name: Wait for gluetun to become healthy
shell: docker inspect --format '{{ '{{' }}.State.Health.Status{{ '}}' }}' gluetun
register: gluetun_health
until: gluetun_health.stdout == "healthy"
retries: 30
delay: 5
changed_when: false
- name: Start nzbget and rutorrent
shell: docker compose up -d --force-recreate nzbget rutorrent
args:
chdir: "{{ service_dir }}"
- name: Check container status
shell: docker ps --filter name=gluetun --filter name=nzbget --filter name=rutorrent --format "table {{ '{{' }}.Names{{ '}}' }}\t{{ '{{' }}.Status{{ '}}' }}" | head -10
register: container_status
changed_when: false
- name: Show status
debug:
msg: "{{ container_status.stdout_lines }}"