Я пытаюсь настроить простой веб-сервер для отображения некоторых изображений, загруженных из моего 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.
Спасибо заранее
Вот решение, которое я придумал.
В моем примере используется образ 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.