Docker Apache httpd не может отобразить изображения на смонтированном ресурсе

Я пытаюсь настроить простой веб-сервер для отображения некоторых изображений, загруженных из моего NAS. Моя проблема в том, что я могу заставить веб-сервер отображать изображения, только если они хранятся в папке на хосте Ubuntu. При попытке загрузить их с моего NAS они отображаются на веб-странице в виде битых файлов, но доступны при прямом доступе к ним путем ввода полного пути к файлу в браузере.

Веб-сервер работает внутри Docker на хосте Ubuntu 20.04. Я использую httpd Docker-image. Мой compose-файл выглядит так:

version: '3'
services:
  httpd:
    container_name: webserver-test
    image: httpd:2.4.38-alpine
    restart: always
#    environment:
#      - PUID=1000
#      - PGID=1000
    ports:
      - "80:80"
    volumes:
      - /mnt/744fa3d8-4c42-44fb-90a4-1cec0422ab15/data/containers/webserver-test/public-html/:/usr/local/apache2/htdocs
      - /mnt/744fa3d8-4c42-44fb-90a4-1cec0422ab15/data/containers/webserver-test/configuration/:/usr/local/apache2/conf
      - /mnt/nas-intern-delt-data/webtest/data/:/usr/local/apache2/htdocs/img
    networks:
      macvlan0:
        ipv4_address: 192.168.10.210
networks:
  macvlan0:
    external: true

Точка монтирования /mnt/nas-intern-delt-data смонтирована в fstab так, и просматривается в Ubuntu без проблем:

//192.168.10.100/intern\040delt\040data /mnt/nas-intern-delt-data cifs username=user-here,password=password-here,vers=3.0,dir_mode=0777,file_mode=0777,uid=1000,gid=1000,iocharset=utf8 0 0

Мой index. html выглядит так

<!DOCTYPE html>
<html>
    <head>
        <title>Example</title>
    </head>
    <body>
        <p>Hello world!</p>
        <img src="/data/1.jpg">
        <img src="/img/1.jpg">
    </body>
</html>

При просмотре разрешений в папках data и img внутри контейнера я вижу следующее:

bash-4.4# cd /usr/local/apache2/htdocs
bash-4.4# ls -l
total 16
drwxrwxr-x    2 1000     1000          4096 Feb 10 16:53 data
drwxrwxrwx    2 1000     1000             0 Feb 10 19:29 img
-rwxr-xr-x    1 1000     1000           267 Feb 10 17:17 index.html
drwxrwxr-x    8 1000     1000          4096 Feb  9 20:33 pages
drwxr-xr-x    3 root     1000          4096 Feb 10 17:30 public-html
bash-4.4# cd data
bash-4.4# ls -l
total 100
-rwxr-xr-x    1 1000     1000         98588 Dec 14 16:20 1.jpg
bash-4.4# cd ..
bash-4.4# cd img
bash-4.4# ls -l
total 112
-rwxrwxrwx    1 1000     1000         98588 Dec 14 16:20 1.jpg
-rwxrwxrwx    1 1000     1000             4 Feb 10 19:32 test2.txt
bash-4.4# 

В логах Apache-контейнера при просмотре веб-страницы видно следующее:

192.168.2.124 - - [21/Feb/2021:15:40:07 +0000] "GET / HTTP/1.1" 304 -
192.168.2.124 - - [21/Feb/2021:15:40:07 +0000] "GET /img/1.jpg HTTP/1.1" 200 98588

Сама веб-страница выглядит так: imgur-link

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

Спасибо заранее

0
задан 22 February 2021 в 14:51
1 ответ

Вот решение, которое я придумал.

В моем примере используется образ wordpress:5.8, но его можно применить к любому образу php 7.4 apache debian (и других дистрибутивов). Использование docker-compose.

Сначала смонтируйте хранилище CIFS за пределами целевого каталога:

volumes:
  repo:
    driver_opts:
      type: cifs
      o: "addr=WINDOWS-SHARE.local,uid=1000,gid=1000,vers=3,username=WindowsUser,password=YourPassword,iocharset=utf8,file_mode=0644,dir_mode=0777"
      device: "//WINDOWS-SHARE.local/Repositories/TheFolder"

Затем в томах контейнера смонтируйте его в папку /var/www/html, но не в окончательный путь.

volumes:
  - repo:/var/www/html/repo

И это то, что я использовал для своей точки входа и команды:

entrypoint: [ "/bin/sh", "-c" ]
command: >
  '
    rm -rf /var/www/html/wp-content/themes/theme-name
    apt update && apt-get install -y bindfs
    mkdir -p /var/www/html/wp-content/themes/theme-name
    bindfs -u www-data -g www-data /var/www/html/repo/theme-name /var/www/html/wp-content/themes/theme-name
    usermod -u 1000 www-data
    groupmod -g 1000 www-data
    docker-entrypoint.sh apache2-foreground
  '

Идея заключалась в том, чтобы удалить из папки докера все, что может иметь такое же имя. Затем установите биндфс. Затем создайте пустой каталог, используя только что удаленное имя папки. Затем привяжите каталог в репозитории к папке, которую вы создали. Обычно я модифицирую пользователя и группу www-data для своего пользователя только для того, чтобы смонтированные разрешения работали лучше, но, вероятно, это не нужно. Наконец, последняя запись — это CMD исходного изображения.

Проблема заключается в том, как работают символические ссылки в сочетании с apache. При использовании bindfs эта проблема маскируется, и apache видит привязку папки как обычную папку.

РЕДАКТИРОВАТЬ: забыл добавить, контейнер должен быть установлен в привилегированный ( привилегированный: true) для монтирования с помощью bindfs.

0
ответ дан 23 August 2021 в 15:30

Теги

Похожие вопросы