0

I'm trying to set up a simple webserver to display some images loaded from my NAS. My problem is that I can only get the webserver to display images when they're stored in a folder on the Ubuntu-host. When trying to load them from my NAS, they appear as broken files on the webpage, but are accessible when accessing them directly by entering the complete file path in my browser.

The webserver is running inside Docker on a Ubuntu 20.04 host. I am using the httpd Docker-image. My compose-file looks like this:

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

The mount-point /mnt/nas-intern-delt-data is mounted in fstab like so, and is browsable in Ubuntu without any problems:

//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

My index.html looks like this

<!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>

When looking at the permissions at the data and img folders from inside the container I see this:

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# 

The Apache-container logs shows the following when browsing the webpage:

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

The webpage itself looks like this: imgur-link

I hope that someone can shed some light on where this goes wrong. My guess is that it's a permissions problem, I just can't find it... As stated it shows the internally saved image fine, but not the one stored at my NAS.

Thanks in advance

Andrew Schulman
  • 8,811
  • 21
  • 32
  • 47
Joent
  • 1
  • My **httpd.conf** file looks like this, just a standard I found somwhere... Haven't paid much attention to it: https://pastebin.com/Jft37nxc – Joent Feb 21 '21 at 15:56
  • I have the same issue. MY GUESS is a bug in docker itself. This even happens with cifs volume mounts: https://pastebin.com/kuRxq3dc. It happens with raw, file access (navigating to a .lock file) but NOT .js or .css files. My containers also usermod and groupmod the www-data user to 1000 to be more compatible with shares. This has been the only other mention of the issue I've found online. – JonShipman Aug 19 '21 at 15:03
  • I actually got it working! If I'm not mistaken I documented the solution, I'll look for it and let you know! – Joent Aug 21 '21 at 07:50
  • Funny story, I found a solution this morning. I mounted the folder outside the directory, then used bindfs to point it to the correct spot. I'll add it as an answer. – JonShipman Aug 23 '21 at 15:17

1 Answers1

0

Here's the solution I came up with.

My example is using the image wordpress:5.8 but can apply to any php 7.4 apache debian (and other distro) images. Using docker-compose.

First, mount the CIFS storage in a mount outside of the target directory:

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"

Then in the container volumes, mount it in the /var/www/html folder, but not the final path.

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

And this is what I used for my entrypoint and command:

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
  '

The idea being, remove anything in your docker folder that might have the same name. Then install bindfs. Then make an empty directory using the folder name you just deleted. Next, bindfs the directory in the repo with the folder that you created. I typically mod the www-data user and group to my user just to make mounted permissions work better, but it's probably not needed. Finally, the last entry is the original image's CMD.

The issue is with the way symlinks work in conjunction with apache. By using bindfs, that issue is being masked and apache sees the folder bind as being a normal folder.

EDIT: Forgot to add, the container needs to be set to privileged (privileged: true) in order to mount with bindfs.

JonShipman
  • 101
  • 1