-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
entrypoint: Monitor config dir for changes #791
base: master
Are you sure you want to change the base?
Conversation
4427d51
to
ff48fcb
Compare
Hi @oliv3r ! I think it only makes sense with an init-like system (see e.g. https://github.com/docker-library/official-images/#init) and that is too big of a change. |
@thresheek it would be nicer, if nginx would monitor this via inotify library internally, for sure. The problem I'm trying to solve, is that, nginx is running in a (compose) container, doing happily its thing. Through external means (the only way anyway?) the configuration files OR the certificate files get updated (e.g. certbot ran and renewed) so now nginx needs to be sigusr-ed. The problem is of course, if certbot also runs in a container, it can't really do that (easily). Instead, it's much easier and nicer, to have inotifywait (or nginx itself) watch for differences in these files, and (after nginx -t) restart itself, which is what the script is for (not activated by default). So nginx works exactly the same as before, but if you set the correct environment variables, nginx will restart itself if a configuration file is detected through inotifywait. So not sure why you refer to an init system, the nginx container doesn't have it right now, and doesn't need it imo after this change either, or rather, because of this change (using tini would still probably be wise, and would be a trivial change, as only the shebang of the entrypoint script would need to change, and tini is like 34k). |
I'm referring to an init system because we now have two types of processes running inside a container, with no proper management for those. Imagine if inotifywait exits during the lifetime of a container - we have no way to restart it, or to know if it's stil running as it should. And we still explicitely rely on the services it provides since we enabled it in the first place. |
ff48fcb
to
ae86545
Compare
You are very correct, and nginx is currently doing it wrong to begin with (hence my last sentence in my previous comment). Unless nginx becomes a process monitor (which as you said it doesn't) it 'violates' all the init reasoning mentioned by these init systems. Signal handling, process reaping etc, is all left to nginx. And as there's commands being executed (grep, sed just to name something) these also can cause problems. So in that sense, adding dumb-init is a good idea generally anyway. As for why dumb-init and not the built-in tini-init. For one, docker has added, removed, re-added it so it becomes unpredictable. Secondly, the initial entrypoint depends on it, yet it requires the user to run the container with the |
Even single process containers (which this one is actually not) should have an init system. However most init systems are too big and complex for containerization purposes. [Dumb-init][0] (and tini init) address this problem _specifically_ for Docker containers. See the [dumb-init][0] documentation for more details. [0]: https://github.com/Yelp/dumb-init Signed-off-by: Olliver Schinagl <[email protected]>
We see a lot of crudges and hacks to notify nginx or the nginx container informing it it needs to restart. While there certainly cases that require manual control, for the most, this could be easily automated. With inotify, we can recursively monitor /etc/nginx (or any directory per config) for changes (currently, not monitoring for for access time changes, e.g. reads or `touch` (not creating new files) events). On an event, we sleep first for (configurable) seconds, the default is 10, so that multiple updates don't cause multiple restarts. E.g. copying 10 certificates into /etc/nginx/certs, won't trigger 10 reloads. The monitor will run indefinably, but to ensure there is 'some' way to exit it, is to remove the pid file (configurable location) and triggering a `/etc/nginx` change (`touch '/etc/nginx/exit'` for example to create a file. It's not perfect, but probably will never be used anyway. The current configuration won't change existing behavior, it needs to be explicitly enabled. Signed-off-by: Olliver Schinagl <[email protected]>
ae86545
to
506fd0f
Compare
I don't see how nginx is currently doing it wrong, to be honest. It will manage the processes it spawns (workers, cache processes, etc.). It does not execute grep or sed. Are you referring to entrypoints? If those fail on a startup, there is no need to invoke nginx or init, since they are not managed by those in any case. |
So nginx fails, in that it is trying to 'be' an init system, handling signals etc (the dumb init describes it quite well). What happens to zombie processes? Will nginx reap those? As for grep/sed, nginx container does very much so, doesn't it? I mean The dockerfile defines an entrypoint https://github.com/nginxinc/docker-nginx/blob/master/Dockerfile-debian.template#L103 which means the container always runs https://github.com/nginxinc/docker-nginx/blob/master/entrypoint/docker-entrypoint.sh which is a) a shell script, so now your shell script is responsible for initially handling signals and reaping processes. Anyway, this change shouldn't affect the container on nginx in a negative way, but will improve nginx container and make it adhere to the 'official docker guidelines' which would be a pro :) |
See also #509 |
Yes,
For the small amount of time during startup, the shell (and script) will be responsible for signals and reaping (which Any real (systemd, SysVinit, etc) or pretend (like a bash script that stays resident as PID 1) init system that isn't the main software of the image (i.e., |
We see a lot of crudges and hacks to notify nginx or the nginx container informing it it needs to restart. While there certainly cases that require manual control, for the most, this could be easily automated.
With inotify, we can recursively monitor /etc/nginx (or any directory per config) for changes (currently, not monitoring for for access time changes, e.g. reads or
touch
events). On an event, we sleep first for (configurable) seconds, the default is 10, so that multiple updates don't cause multiple restarts. E.g. copying 10 certificates into /etc/nginx/certs, won't trigger 10 reloads.The monitor will run indefinably, and can't be easily killed. This isn't a problem however, as this is specifically a docker entry point and it is fair to assume this will only ever be run under docker.
The current configuration won't change existing behavior, it needs to be explicitly enabled.