Как сохранить загруженные пользователем файлы на подключенный том, используя PHP, docker -compose? - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть стек LAMP, настроенный с docker -compose, и возникают проблемы с сохранением выгруженных пользователем файлов на подключенный том для постоянного хранения. Вот мой файл композиции:

    version: '3.7'
services:

  php-apache:
    build: './php-apache'
    restart: always
    ports:
      - 5000:80
    volumes:
      - ./public_html:/var/www/html
      - ./composer/vendor:/var/www/html/vendor
      - ./tmp:/usr/local/tmp
      - ./cert/:/usr/local/apache2/cert
      - covers:/var/lib/app-data/covers:rw
      - ebooks:/var/lib/app-data/ebooks:rw
    depends_on: 
      - mysql
      - composer

  mysql:
    build: './mysql'
    restart: always
    ports:
      - '33061:3306'
    volumes:
      - ./database:/var/lib/mysql
      - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    environment: 
      MYSQL_ROOT_PASSWORD: secretpw
      MYSQL_USER: myuser
      MYSQL_PASSWORD: mypw 
      MYSQL_DATABASE: mydb

  composer:
    build: './composer'
    working_dir: /composer
    volumes:
      - ./composer:/composer
    command: install

volumes:
  covers: {}
  ebooks: {}

В моем коде PHP я пытаюсь сохранить файлы на томах:

    if (!move_uploaded_file($_FILES[$file]['tmp_name'], $path . $filename)) {
        throw new RuntimeException("Failed to move uploaded file.");
    }

И получаю следующую ошибку:

Предупреждение: move_uploaded_file (/var/lib/app-data/covers/useruploadedfile.jpg): не удалось открыть поток: разрешение отклонено

Я пытался изменить разрешения для громкость безрезультатна. Есть ли способ дать PHP разрешения на запись для подключенных томов?

Ответы [ 2 ]

1 голос
/ 05 февраля 2020

Я нашел решение под руководством @Nguyen, хотя в моей ситуации было немного больше, поэтому я подумал, что напишу свой подробный ответ на случай, если он кому-нибудь поможет.

Если вы используете Docker в MacOS, Docker фактически работает на виртуальной машине Linux, а не на машине. Это сбило меня с толку при попытке изменить разрешения на хост-машине (хост-машина с точки зрения docker - это ВМ).

Я обнаружил, какой идентификатор пользователя и группы выполнял мой сценарий PHP, используя следующие функции:

echo posix_getuid();
echo posix_getgid();

Я узнал место подключения моего тома с помощью следующей команды:

docker volume inspect nameofyourvolume

Когда я пытался сократить каталог, в который был смонтирован том (/ var / lib / docker / volume), я получал сообщение «нет такого файла или каталога». Проведя некоторые исследования, я понял, что путь к месту монтирования был относительно виртуальной машины, работающей docker. Я нашел способ попасть в эту виртуальную машину с помощью следующей команды (см. https://www.bretfisher.com/docker-for-mac-commands-for-getting-into-local-docker-vm/):

docker run -it --rm --privileged --pid=host justincormack/nsenter1

Это приведет вас к контейнеру с полными разрешениями для виртуальной машины. Затем вы можете изменить разрешения для каталога, содержащего ваши тома, как обычно.

1 голос
/ 05 февраля 2020

Я пытался изменить разрешения для тома, но безрезультатно. Есть ли способ дать PHP разрешения на запись для подключенных томов?

Короче говоря, в контексте вашего сценария невозможно изменить разрешение подключенного тома из docker контейнер. Это необходимо сделать на уровне хост-машины.

Эта проблема обычно возникает, когда хост-компьютер основан на Linux (например, RedHat, Ubuntu), в то время как он отлично работает для MacOS. Вам необходимо:

  • Узнать, какой идентификатор пользователя в контейнере docker выполняет команду.
  • Убедитесь, что тот же идентификатор пользователя на хост-компьютере имеет достаточные разрешения создать файл внутри смонтированной папки.
...