Python DockerLinux

Python: PermissionError при создании файла внутри контейнера

  • Обновлено
  • Чтение ≈ 3 минуты

Краткий ответ

PermissionError при записи Python в контейнер Docker: проверьте пользователя процесса, владельца смонтированного каталога, режим read-only и права на путь без chmod 777.

В этой статье
  1. Что происходит и как распознать неисправность
  2. Как отличить причины
  3. Пошаговая диагностика и исправление
  4. Команды и примеры для проверки
  5. Как проверить результат и что делать дальше

#Что происходит и как распознать неисправность

Python внутри контейнера может успешно читать данные и получать PermissionError при создании файла. Внутри образа и на хосте действуют разные пространства имён, пользователи UID/GID, права и настройки монтирования.

#Как отличить причины

Возможная причинаКак узнатьЧто делать
Папка смонтирована только на чтениеbind mount или volume используется с :ro либо контейнер запущен с read_only.Ошибка возникает и у процессов с корректными правами.Измените режим только для специально выделенного рабочего каталога.
UID/GID процесса не имеет правВладельцем bind mount является другой UID, чем у процесса в контейнере.id и stat показывают разные значения.Согласуйте права и пользователя без глобальных chmod.
Папка отсутствует или невернаОжидаемый абсолютный путь создан на хосте, но в контейнере он другой.ls внутри контейнера показывает другой каталог.Проверьте фактические mounts и переменные приложения.

#Пошаговая диагностика и исправление

  1. Запишите точный путь, в который пишет программаОткройте журнал контейнера через docker compose logs --tail 100 ИМЯ_СЛУЖБЫ, заменив имя названием службы в compose.yaml; в терминале перейдите в каталог с этим файлом. Найдите PermissionError: [Errno 13] и абсолютный путь. Не меняйте права наугад по корню контейнера.
  2. Проверьте пользователя процесса и путь внутри контейнераВ терминале Docker-хоста выполните docker compose exec ИМЯ_СЛУЖБЫ id и docker compose exec ИМЯ_СЛУЖБЫ ls -ld /путь/для/записи, предварительно подставив реальные имя и путь. В выводе запишите UID/GID и разрешения. Если служба не запущена, используйте её диагностику через docker compose ps и логи, не удаляя контейнеры.
  3. Сравните настройки монтирования в ComposeОткройте compose.yaml в редакторе, найдите разделы volumes, read_only и user у проблемной службы. При записи ./data:/app/data:ro суффикс :ro означает запрет записи. Если файл должен быть только читаемым, измените путь вывода Python, а не защиту контейнера.
  4. Убедитесь, что на хосте существует назначенный каталогВ файловом менеджере или терминале хоста проверьте соответствующий исходный каталог bind mount, например ./data. Поскольку относительный путь зависит от Compose-проекта, сначала определите его реальное расположение командой docker compose config. Не создавайте неизвестные каталоги в системных папках; для вывода выделите отдельный путь приложения.
  5. Исправьте права точечно после резервной копииЕсли диагностика доказала конфликт UID/GID, согласуйте владельца конкретной папки данных с администратором. Не применяйте chmod -R 777 или изменение владельца к общему разделу. При необходимости можно настроить отдельный именованный volume либо user сервиса, предварительно проверив права на существующие файлы и влияние на другие задачи.
  6. Проверьте запись без риска для данныхВнутри запущенного контейнера через Python создайте НОВЫЙ диагностический файл в нужном каталоге с уникальным именем, убедитесь, что он появился, затем удалите только этот собственный тестовый файл после проверки. Если контейнер read-only по политике безопасности, используйте разрешённый каталог /tmp либо отдельный volume, не отключая защиту всей системы.
  7. Примените изменения контролируемо и откатите при проблемеЕсли правили compose.yaml, сохраните его копию, проверьте синтаксис docker compose config и только по согласованию пересоздайте нужную службу командой docker compose up -d ИМЯ_СЛУЖБЫ. После запуска повторите запись. Если пропал доступ к старым данным, остановитесь, восстановите исходный compose.yaml и проверьте, не был ли смонтирован пустой новый том.

#Команды и примеры для проверки

Linux · Терминал (Bash)Команда
Запускайте в терминале на Docker-хосте из папки с compose.yaml. Эти команды выводят состояние и итоговую конфигурацию, но могут раскрыть значения переменных — не публикуйте полный вывод.
docker compose ps
docker compose config
Python
Запускайте только в тестовой папке контейнера, заменив путь. Режим x отказывается перезаписывать существующий файл; удаляйте только созданный тестовый файл.
from pathlib import Path

target = Path("/app/data/probe-write.txt")  # замените путём к разрешённой папке
with target.open("x", encoding="utf-8") as f:
    f.write("проверка записи\n")
print(target)

#Как проверить результат и что делать дальше

Рабочий признак — новый файл появляется именно в ожидаемой папке, приложение не сообщает PermissionError, а контейнер не получил ненужные привилегии. Если запись невозможна даже при согласованном UID/GID, проверьте ACL, SELinux/AppArmor и ограничения файловой системы совместно с администратором.

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.