3

I want to mount the /etc/nginx folder to a custom folder on my host. However, whenever I try this the container doesn't run at all. Mounting anything else doesnt seem to be problem, though the folder I want it to mount to is always empty.

I tried using /usr/local/nginx/conf or /usr/local/etc/nginx instead of /etc/nginx but the folder is always empty. Though here the container runs at least. Which is what lead me to believe it is this specific mounting that is causing problems.

This is what I want to do.

docker run -p 80:80 -p 443:443 -v /home/pi/nginx_files/config:/etc/nginx -v /home/pi/nginx_files/certs:/etc/ssl/private -d nginx

The container seems to run with any other folder, as ive tried

docker run -p 80:80 -p 443:443 -v /home/pi/nginx_files/config:/etc/nginx/b -v /home/pi/nginx_files/certs:/etc/ssl/private -d nginx

Just to see if any non existent folder doesn't have that problem.

Before that I tried using docker composer and the docker-compose.yaml

version: '3'

services:
  reverse:
    container_name: reverse
    hostname: reverse
    image: nginx
    ports:
      - 80:80
      - 443:443
    volumes:
      - <path/to/your/config>:/etc/nginx
      - <path/to/your/certs>:/etc/ssl/private

and

tried docker-compose up

However it suffered from the same problem, where it doesn't even start the container. Error Message:

Creating network "nginx_files_default" with the default driver
Creating reverse ... done
Attaching to reverse
reverse    | 2019/08/31 00:41:07 [emerg] 1#1: open() "/etc/nginx/nginx.conf" failed (2: No such file or directory)
reverse    | nginx: [emerg] open() "/etc/nginx/nginx.conf" failed (2: No such file or directory)
reverse exited with code 1

If I use nonexistent folders it just gets stuck in "Attaching to reverse" indefinitely. But I dont get a message "no such file or directory" although the folders have completely made up names and definitely dont exist.

Did I missunderstand the point of mounting? I thought I'd get to look at the default.conf file by having the container save it on the host, but does it not create one? Do I have to create one myself and then mount it to the container? Does mounting create a folder to read from for the container and not a folder to write to? I'm fairly new to docker and linux so forgive me if this is a rather stupid question.

Raphael
  • 65
  • 1
  • 7
  • The [official nginx](https://hub.docker.com/_/nginx) image's documentation provides information on how to use the image. i.e. mount the `/path/to/nginx.conf:/etc/nginx/nginx.conf` (you don't want to override important `nginx` config in the `/etc/nginx/` directory by bind mounting a directory to it). – masseyb Aug 31 '19 at 01:08
  • You can pull a copy of the default config files from an instance of the container i.e.: `docker run --rm -d --name nginx` then `docker cp nginx:/etc/nginx/nginx.conf /path/to/nginx.conf` and `/etc/nginx/conf.d/default.conf /path/to/default.conf` - can modify them to your liking's and bind mount them / build your custom image with them. Can stop the container afterward with `docker stop nginx`. – masseyb Aug 31 '19 at 01:15
  • 1
    Thanks masseyb thats exactly what I needed. Guess I really did missunderstand what t meant to mount in this case. – Raphael Aug 31 '19 at 09:47
  • No problem, added an [answer](https://stackoverflow.com/a/57737841/1423507) with more details and an example. – masseyb Aug 31 '19 at 15:18

3 Answers3

4

You should not mount the whole /etc/nginx directly, it will defiantly break you container because it will override the following files and directories.

conf.d fastcgi_params koi-utf koi-win, mime.types modules nginx.conf scgi_params uwsgi_params and win-utf

Without going into details of each directory, just take mime.types it will be overridden as a result, your Nginx will never be able to run without /etc/nginx/mime.types

If you want to update configuration then you should only mount

/etc/nginx/conf.d

For example

docker run -p 80:80 -p 443:443 -v /home/pi/nginx_files/config:/etc/nginx/conf.d -v /home/pi/nginx_files/certs:/etc/ssl/private -d nginx

If really want to update nginx.conf then you should mount exact file, not the whole directory

docker run -p 80:80 -p 443:443 -v /home/pi/nginx_files/config/nginx.conf:/etc/nginx/nginx.conf  -v /home/pi/nginx_files/certs:/etc/ssl/private -d nginx
Adiii
  • 54,482
  • 7
  • 145
  • 148
3

As pointed out in the comments and @Adiii's answer, you should avoid bind-mounting a directory to /etc/nginx/ as you're "overriding" the containers configuration (think of it as mounting a USB device to a folder that already contains files, a ls -alF will display the contents of the USB device and the files that exist in the mount point will only be available once the USB device is unmounted).

You can pull the nginx.conf and default.conf from an instance of a running container for example:

  1. run a nginx container: docker run --rm -d --name nginx nginx:1.17.3
  2. use docker cp to copy out the files: docker cp nginx:/etc/nginx/nginx.conf /path/to/nginx.conf and docker cp nginx:/etc/nginx/conf.d/default.conf /path/to/default.conf
  3. stop the container: docker stop nginx (the container will be removed given the --rm from the docker run)

You can then modify the configuration files and bind mount them in the container i.e.: docker run --rm -d --name nginx -v /path/to/nginx.conf:/etc/nginx/nginx.conf nginx:1.17.3

Otherwise you can build your own image using your custom configuration, for example:

├── default.conf
├── Dockerfile
└── nginx.conf
FROM nginx:1.17.3

COPY nginx.conf /etc/nginx/nginx.conf
COPY default.conf /etc/nginx/conf.d/default.conf

You can build your image: docker build --rm -t so:57734446 . and run it: docker run --rm -d --name my-nginx so:57734446. For a little more advanced use-case of the image this is my nginx-modsecurity build that extends the official nginx image.

masseyb
  • 3,745
  • 1
  • 17
  • 29
0

Something that might make it easier is just leave nginx structure the way it is. Don't mount folders over it until you understand the unique style it uses.

You really have 2 major folders. Your blahblah.conf files and your web pages.

So create 2 folders that will be mounted inside your docker. Say 'mounted_conf' and 'mounted_web'.

We mount the 'mounted_conf' below the the conf.d folder.

So mount it /etc/nginx/conf.d/mounted_conf.

Now add in your directories to scan for conf files which normally is only the conf.d folder, by adding it to the nginx configuration file /etc/nginx/nginx.conf. You'll see normally at the end of that file where it scans for blahblah.conf files. Add that location to the one that is already there. Example is "the conf.d/*.conf" will already be there so add your mounted one below that.... don't forget the ; at the end. :)

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/conf.d/mounted_conf/*.conf;

Now do the same for your mounted_web folder.

Not the ideal way to go but it'll get you in the game and going! Good luck.