2

I am trying to create an nginx docker container (to provide file upload/download). Under the html root I'm looking to create some additional subfolders (upload and download).

I took the nginx docker image as my base and added some additional lines to create/initialise the subfolders.

FROM nginx

MAINTAINER Carl Wainwright <[email protected]>

ENV HTML_PATH /var/www/html
COPY nginx.conf /etc/nginx/nginx.conf

RUN mkdir -p $HTML_PATH/upload && mkdir -p $HTML_PATH/download
RUN chmod 755 $HTML_PATH/upload && mkdir chmod 755 $HTML_PATH/download
RUN chown nginx:nginx $HTML_PATH/upload && chown nginx:nginx $HTML_PATH/download

In my docker-compose file I am creating my container as follows:

  wbh-device-asset-server:
    restart: always
    image: wbh-device-asset-server/nginx:test
    container_name: wbh-device-asset-server
    volumes:
     - /www-data:/var/www/html
    ports:
     - "8081:8081"
    networks:
     - mynetwork

My nginx configuration has the following server configuration.

server {
    error_log  /var/log/nginx/error.log debug;
    access_log  /var/log/nginx/access.log  main;

    # Running port
    listen 8081;

    # Proxy requests to get SDP's
    location ~ \.sdp {
      root /var/www/html;

      try_files $uri =404;

      limit_except GET           { deny all; }
    }

    # Proxy requests to put APD's.
    location ~ \.(apd) {

      dav_methods  PUT;
      limit_except PUT           { deny all; }

      client_body_temp_path      /tmp/files/;
      client_body_in_file_only   on;
      client_body_buffer_size    128K;
      client_max_body_size       30M;

    }

On my local machine /www-data exists and has write permissions. Each time I bring the container up the contents of /www-data are empty.

Why is it I cannot create folders under /var/www/html/ ? What is stopping me from doing this.

NOTE: As part of my troubleshooting I created a docker image based on centos and installed nginx from packages and I faced the same issue.

2
  • When you mount a folder from host to container, the host folder content prevails and you won't see container folders that were created before the mounting. Commented Sep 16, 2016 at 18:15
  • Makes perfect sense now.. Commented Sep 18, 2016 at 14:34

1 Answer 1

4

The Dockerfile creates an image, this is the definition used to run containers, not the container itself, and is only run once per image creation. So all the RUN commands happen in there and update your image with the directories you expect.

In your docker-compose.yml, which creates containers, you have a host volume mount. Volumes are performed on the container, not the image build, so this directory is mounted after your Dockerfile's RUN commands have already updated the image. With a host volume, the contents of that directory on the host completely overlay the contents of the image, they aren't deleted, but you won't be able to see them in any container with that volume mount. If you used a named volume, and that named volume happened to be empty, e.g. after you created it for the first time, then Docker includes a feature to copy the contents of the image's directory into the volume before mounting it into your container.

So your 3 options are:

  1. Don't use a volume at all and your files will be visible. Not recommended if you want to preserve this data between containers.

  2. Use a named volume. That can be as easy as changing the volume source from a fully qualified directory, /www-data, to a name, www-data. If you do this, you won't be able to manage the contents of that folder easily from your host, Docker will manage it via it's internal directory structure and you'll want to manage it via containers.

  3. Simply add your desired files to the directory on your host. This is the easiest solution when you're starting out, but be aware that users on the host may not match users in the container, so you may see permission and uid errors that you'll need to fix with chmod or chown commands.

Sign up to request clarification or add additional context in comments.

7 Comments

I now understand the issue of host volume mounts overlaying the image folder. For my setup I don't need to modify the contents of my html root once the container is running. I just need to expose the contents of the html root. From your explanation it seems that option 2) is what I need. When you say named volume do you mean using the VOLUME in the Dockerfile?
I forgot to mention that I need the ability to read/write to the mount volume once the container is up and running.
If you declare the volume inside the Dockerfile, it won't have a name by default, but you'll get an anonymous guid volume created every time you run the container. I don't recommend this. As mentioned above, change the volume source from /www-data to www-data in your docker-compose.yml and it will create a named volume for you. You can specify :ro at the end of the volume mount if you don't want that specific container to have rw access to the volume.
ERROR: Named volume "www-data:/var/wwwi/html:rw" is used in service "wbh-device-asset-server" but no declaration was found in the volumes section.
I added a volumes: section to my Dockerfile to resolve the error. I assume if I want to backup the mount contents I archive the contents of the _data folder from the source path (found in docker inspect output).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.