Files
admin/.wiki/concepts/traefik-file-watch-wsl2-broken.md

69 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Traefik file-watch broken under Docker Desktop Windows (WSL2 9p mount)
type: concept
tags: [traefik, docker-desktop, windows, gotcha, wsl2]
sources: []
updated: 2026-05-21
---
# Traefik file-watch broken под Docker Desktop Windows
Traefik file provider's `watch: true` **не работает** для bind mounts из Windows host через Docker Desktop WSL2 9p (виртуальная файловая система). Изменения на disk **не доходят** до traefik. Config остаётся frozen на startup state до явного `docker restart traefik`.
## Симптомы
1. Rename `.yml → .yml.disabled` — route ОСТАЁТСЯ active в traefik runtime, продолжает отвечать.
2. Edit content of `.yml` — изменения не подхватываются, runtime использует старый snapshot.
3. New `.yml` файл в `/custom/` — игнорируется, route не добавляется.
4. `touch` обновление mtime — нет reload.
5. В logs (`--log.level=DEBUG`) — никаких "Configuration reloaded" сообщений.
## Root cause
Docker Desktop на Windows монтирует bind volumes через WSL2 9p protocol (`/run/desktop/mnt/host/c/...`). 9p **не пропагирует inotify events** — fsnotify watchers внутри контейнера не получают уведомлений об изменениях. Traefik file-watcher использует `fsnotify` → молчит.
Это известная архитектурная проблема Docker Desktop Windows. Linux native Docker, Docker on macOS (через osxfs/virtiofs новый) — работают по-разному.
## Подтверждение
```powershell
# 1. Mount bind path inside traefik
docker inspect traefik --format '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{println}}{{end}}'
# Покажет: /run/desktop/mnt/host/c/... -> /custom/ <-- WSL2 9p
# 2. Rename one yml to .disabled, проверить route ещё активный
docker exec traefik wget --header='Host: <some-host-in-disabled-yml>' --spider https://traefik/
# 200 OK даже после rename (т.к. config не перезагружен)
# 3. После docker restart traefik — то же запрос вернёт 404
docker restart traefik
docker exec traefik wget --header='Host: <some-host-in-disabled-yml>' --spider https://traefik/
# 404 ✅
```
## Последствия
- **Любое изменение в `/custom/*.yml` требует `docker restart traefik`.**
- Atomic revert: backup .yml → restart → rollback означает restore + restart.
- "Hot reload" workflow невозможен под этой config'ом — нужно или native Linux Docker, или migrate на docker provider via labels (отдельные изменения сразу видны через container restart events).
## Workarounds
1. **Always restart traefik after config changes** — single source of truth для team is restart, не file-edit. Документировать.
2. **Periodic auto-restart** — cron внутри traefik container (`docker exec traefik <restart-mechanism>`), e.g. каждый час. Кustомные disruption для уже работающих routes.
3. **Migrate to docker provider** (labels) — labels на сервисах меняются вместе с container restart, traefik догоняет docker events корректно. Big migration работа.
4. **Use traefik file provider's `pollInterval`**НЕ поддерживается в file provider (только в HTTP provider). Не вариант.
5. **Move traefik в WSL native** — запускать traefik внутри WSL2 distro (Ubuntu), mount /etc/traefik внутри WSL native fs, traefik видит inotify нормально. Требует переезд compose stack в WSL.
## Применено
[`traefik-maljarka-502-bug`](../../.tasks/traefik-maljarka-502-bug.md) — обнаружено при debugging. После рестарта traefik 2026-05-21:
- 2 dead routes (sestech, ics-artmaterials) реально 404'нулись (до restart были active despite .disabled rename).
- maljarka 502 не ушло — другая root cause (CMS-side HTTPS-mode crash для maljarka.tandemmebel.ru, см. cms-maljarka-https-mode-bug если создана).
## Ссылки
- Docker Desktop Windows mount perf: https://docs.docker.com/desktop/windows/wsl/
- fsnotify limitations: https://github.com/fsnotify/fsnotify/issues/611 (9p/WSL2)
- Setup на этом стэке: [[traefik-on-windows-docker-desktop]]