Reputation: 3089
I have an nginx container, with the following Dockerfile:
FROM nginx:1.19.2
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./conf.d /etc/nginx/conf.d
WORKDIR /etc/nginx/conf.d
RUN ln -s /etc/nginx/conf.d/my-site/my-domain.generic.conf \
&& ln -s /etc/nginx/conf.d/my-site/my-domain.conf
COPY ./certs/* /etc/ssl/
and I have the following docker-compose file:
version: '3.5'
services:
my-site_nginx:
container_name: my-site_nginx
build:
context: ./nginx
network: host
image: my-site_nginx
ports:
- '80:80'
- '443:443' # SSL
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
I am looking for a way to have the nginx service inside the container to autoreload (nginx -s reload
) when I change anything inside the conf.d
folder as well as in the nginx.conf
file that's located at the same level with the conf.d
folder.
The closest thing I've found was this tutorial here: https://cyral.com/blog/how-to-auto-reload-nginx/
But I had to adapt the paths a bit, I don't know what openresty
is, I suppose it's a custom image or something? (Docker noob here)... Anyway, I've tried the following from that link:
Created the docker-entrypoint.sh and nginxReloader.sh files:
docker-entrypoint.sh:
#!/bin/bash
###########
sh -c "nginxReloader.sh &"
exec "$@"
nginxReloader.sh:
#!/bin/bash
###########
while true
do
inotifywait --exclude .swp -e create -e modify -e delete -e move /etc/nginx/conf.d
nginx -t
if [ $? -eq 0 ]
then
echo "Detected Nginx Configuration Change"
echo "Executing: nginx -s reload"
nginx -s reload
fi
done
And added this to Dockerfile:
# [...]
COPY ./nginxReloader.sh /usr/local/bin/nginxReloader.sh
COPY ./docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod +x /usr/local/bin/nginxReloader.sh
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
RUN apt-get update && apt-get install -y --no-install-recommends apt-utils
RUN apt-get install inotify-tools -y
ENTRYPOINT [ "/usr/local/bin/docker-entrypoint.sh" ]
# CMD ["/usr/local/openresty/bin/openresty", "-g", "daemon off;"] (don't know what this would do, but I wouldn't know what to replace `openresty` with in my case, so I omitted this line from the tutorial at the link I provided)
But when trying to docker-compose up --build
it either errored with No such file or directory
for line exec "$@"
in the nginxReloader.sh
file OR I got nginx exited with code 0
when doing docker-compose up
(of course, I tried different things between those errors, but can't remember exactly what).
Also, I've tried to point the ENTRYPOINT in the Dockerfile directly to nginxReloader.sh (ENTRYPOINT [ "/usr/local/bin/nginxReloader.sh" ]
) but then when trying docker-compose up I only get 2 lines of output:
Setting up watches.
Watches established.
and nginx never starts (I suppose it's because of that while true
loop).
Also, if I completely remove the ENTRPOINT line in Dockerfile, when running docker-compose up
I still get the following output:
my-site_nginx | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
my-site_nginx | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
my-site_nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
my-site_nginx | 10-listen-on-ipv6-by-default.sh: error: can not modify /etc/nginx/conf.d/default.conf (read-only file system?)
my-site_nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
my-site_nginx | /docker-entrypoint.sh: Configuration complete; ready for start up
like Docker is somehow aware of that file being in the folder, on the same level with the Dockerfile... No errors, but changing a config still doesn't trigger nginx -s reload
Upvotes: 3
Views: 4218
Reputation: 111
I had the same problem and the accepted answer by @TarunLalwani is missing changes to the Dockerfile that are also required.
I wasn't able to edit their answer, so here is the updated solution that is verified to work, including some additional clarifications.
..................
There are 2 issues:
First, you are not running the original entrypoint when you override it with your new entrypoint. Change
#!/bin/bash
###########
sh -c "nginxReloader.sh &"
exec "$@"
to
#!/bin/bash
###########
sh -c "nginxReloader.sh &"
# See changes to Dockerfile next for more details, but
# you aren't including `CMD` in your Dockerfile. So
# forwarding the arguments ("$@") won't include "nginx",
# which is what the default nginx /docker-entrypoint.sh
# will look for before setting up the service.
exec /docker-entrypoint.sh "$@"
Second, as stated above, you also need to include CMD
in your Dockerfile, or you'll still get nginx exited with code 0
. Add:
...
# same as before
ENTRYPOINT [ "/usr/local/bin/docker-entrypoint.sh" ]
# But include this, which is the same command as in the
# default nginx Dockerfile:
CMD [ "nginx", "-g", "daemon off;" ]
The line in the tutorial that you linked to but commented out in your Dockerfile version was:
CMD ["/usr/local/openresty/bin/openresty", "-g", "daemon off;"]
You're not using the openresty version of nginx, so you're just using "nginx". And it's a registered command so you don't need to use the path to the bin file like he's doing for openresty.
Upvotes: 1
Reputation: 146510
Your issue is that you are not running the original entrypoint when you override it with your new entrypoint, so nginx
will not start. Change
#!/bin/bash
###########
sh -c "nginxReloader.sh &"
exec "$@"
to
#!/bin/bash
###########
sh -c "nginxReloader.sh &"
exec /docker-entrypoint.sh "$@"
Upvotes: 1