I’ve been wondering how it’s supposed to behave. We can likely make it work any way we want it to!
What’s the correct way this should work for our users you think?
I’ve been wondering how it’s supposed to behave. We can likely make it work any way we want it to!
What’s the correct way this should work for our users you think?
I’d like to find a way to get nginx to run as a non-root user and have its logs be visible via fly logs
or the monitoring tab on the dashboard. Here’s a Dockerfile that doesn’t quite work today:
# syntax = docker/dockerfile:1
FROM debian:bullseye-slim
# Install nginx
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y nginx && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
# configure nginx
RUN chown www-data:www-data /var/lib/nginx && \
sed -i 's/80/8080/' /etc/nginx/sites-available/default && \
sed -i 's/^user/#user/' /etc/nginx/nginx.conf && \
sed -i 's/access_log\s.*;/access_log \/dev\/stdout;/' /etc/nginx/nginx.conf && \
sed -i 's/error_log\s.*;/error_log \/dev\/stderr info;/' /etc/nginx/nginx.conf
# run without root privs
USER www-data:www-data
# Start nginx
EXPOSE 8080
CMD ["nginx", "-g", "daemon off;"]
The error produced is:
[info]nginx: [emerg] open() "/dev/stdout" failed (13: Permission denied)
Hi Jerome,
My expectation (and I believe I’m speaking for everyone) is that the anonymous pipes should be owned by the app’s user (same user as the container’s main process).
This allows the app to log by writing to /dev/stdout (which is a symlink to /proc/self/fd/1, which is a pseudo-symlink to the anonymous pipe). It is very useful, and some standard images rely on it (see the original post).
The code in the public init-snapshot repo already tries to do this, so I am curious why it’s not currently the case (code change? bug?). The ownership of the anonymous pipe can be verified by running stat -L /proc/self/fd/1
.
The workaround I posted above should work, just add this to the Dockerfile:
ENTRYPOINT ["/bin/sh", "-c", "\"$@\" 2>&1 | cat", "/bin/sh"]
Or change CMD to
CMD nginx -g "daemon off;" 2>&1 | cat
Ok, I think I have a fix for this. Here’s the output I get for my process:
$ ls -lah /proc/233/fd
total 0
dr-x------ 2 appuser appuser 0 Feb 20 17:09 .
dr-xr-xr-x 9 appuser appuser 0 Feb 20 17:08 ..
lr-x------ 1 appuser appuser 64 Feb 20 17:09 0 -> /dev/null
l-wx------ 1 appuser appuser 64 Feb 20 17:09 1 -> pipe:[4328]
lrwx------ 1 appuser appuser 64 Feb 20 17:09 10 -> socket:[4404]
l-wx------ 1 appuser appuser 64 Feb 20 17:09 2 -> pipe:[4329]
# ...
Which looks right!
I su - appuser
and then echoed into /proc/233/fd/1
and there were no errors and it did appear in my app logs.
I’ve pushed this change to all hosts now. You’ll have to restart your app instances to get the new init
version (08b4c2b
). If you’re using machines, you’ll need to update your machine to purge the rootfs cache for it.
Hurray, it’s working for me now – my humble nobody
can log errors now. Thank you very much, this has been a pain for a loooooooooooooooooooooong time. Much appreciated.
Thanks @tom93 and Jerome (that was quick!)
Publish the new snapshot…