Причина: compose монтировал ../../media/media:/srv/publisher/media, а краулер с 2026-09-12 качает файлы в media/<file> (новая раскладка). В контейнере Path(media/<file>).exists() = False → медиа молча пропускалось, уходил только текст (пост #1017). Фикс: монтировать весь ../../media + _resolve_media() в publisher (пробует media/<file>, media/media/<basename>). GoToSocial тоже. Change fix-media-mount (skip_specs: багфикс), e2e: media_message_id задан, тестовые сообщения удалены.
4.3 KiB
Why
Пост #1017 (linux) опубликован без картинки: в Telegram ушёл только текст, хотя
у поста есть медиа (media_path='media/linux_education_2772.jpg', файл на хосте
/opt/vesti/media/linux_education_2772.jpg, 151 КБ).
Причина: Docker-контейнер vesti-publisher монтирует
../../media/media:/srv/publisher/media — внутренний каталог media/media/.
С 2026-09-12 краулер качает медиа в media/<file> (внешний каталог), а не в
media/media/<file>. В контейнере (CWD /srv/publisher) путь media/<file>
резолвится в /srv/publisher/media/<file> = /opt/vesti/media/media/<file>,
которого для новых постов не существует.
В publisher (services/publisher/app/main.py):
if req.card.media and Path(req.card.media).exists():
проверка проваливается → медиа молча пропускается, публикуется только текст. Ошибки нет — файл «просто не найден».
Проверено в контейнере:
docker exec vesti-publisher python -c "import os; print(os.path.exists('media/linux_education_2772.jpg'))" # False
Затронуты все посты с медиа, скачанные с 2026-09-12 (новая раскладка). Старых
файлов в media/media/ на диске нет (545 постов со старым путём вообще без
файлов — отдельная проблема, не этого change).
What Changes
-
services/publisher/docker-compose.yml: монтировать весь каталог медиа../../media:/srv/publisher/media:roвместо../../media/media. Тогда в контейнере видны ОБЕ раскладки:- новые файлы:
/srv/publisher/media/<file>=media/<file>✓ - старые (если появятся/восстановятся):
/srv/publisher/media/media/<file>=media/media/<file>✓
- новые файлы:
-
services/publisher/app/main.py: устойчивый резолвинг медиа-файла в контейнере. Вместо единственной проверкиPath(card.media).exists()— пробовать кандидатов в порядке приоритета (под контейнерный CWD):card.mediaкак есть (заданный путь, напр.media/<file>, резолвится от/srv/publisher),media/<basename>(если путь в БД содержал подкаталог),media/media/<basename>(старая раскладка). Первый существующий путь идёт вsend_media.
Это чинит и будущие случаи, когда веб пришлёт нормализованный путь, и старые посты, файлы которых восстановят.
-
publisher/card.py— не меняем (нормализация путей на стороне веба уже работает, publisher получаетmedia='media/<file>').
Why Not
- Не переносить файлы из
media/вmedia/media/и не править 12 строк БД: новая раскладка правильная, старую не размножаем. - Не отключать проверку существования файла: у 545 старых постов файла нет, publisher должен молча пропускать отсутствующее медиа, а не падать.
- Не менять
media_pathв БД: веб (route/media/{filename}, MEDIA_DIRS) и читает оба каталога, и publisher после фикса тоже.
Impact
- Файлы:
services/publisher/docker-compose.yml,services/publisher/app/main.py. - Сервис: пересоздать контейнер publisher (
docker compose up -d— volume меняется), проверить healthz. - Данные: без миграций БД.
- Rollback: вернуть монтирование
../../media/mediaи старый код, пересоздать контейнер.