Allow non-root users to write to stdout/stderr

Hi, could you please allow non-root users to write to /dev/stdout and /dev/stderr in your default image?

The most common PHP/nginx docker base image (trafex/php-nginx) works fine in Docker but can’t deploy to Fly because of permission issues.

1 Like

Hi @md1, I could be missing something, but isn’t this explicit in the permissions setup on docker-php-nginx/Dockerfile at master · TrafeX/docker-php-nginx · GitHub ? From what I know it seems like permission needs to be added in there for nobody to write to /dev/stdout and /dev/stderr. Will check if I’m missing something, but it might be easier to raise an issue or ask on the base image repo.

We create a pipe for the main process’s stdout and another one for stderr. Those are owned by the same user and group we use to start the process.

@md1 Can you share your Dockerfile and your nginx config?

As far as I can tell, your app logged a few lines, the error seems to be elsewhere?

2021-10-31 01:39:01,449 INFO supervisord started with pid 510
2021-10-31 01:39:02,451 INFO spawned: 'nginx' with pid 516
2021-10-31 01:39:02,453 INFO spawnerr: can't find command 'php-fpm8'
2021-10-31 01:39:02,590 INFO gave up: php-fpm entered FATAL state, too many start retries too quickly
2021-10-31 01:39:03,592 INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

It wouldn’t have been able to log these lines if it couldn’t write to /dev/stdout or /dev/stderr.

You can repo the error with FROM trafex/php-nginx:latest

I’m not sure which app you are looking at, but yes I broke tons of unrelated stuff trying to get it working.

As you mentioned in your other post, you create the pipes as the user running the main process. If you set the permissions properly it should also allow other processes spawned as lower privilege users to also write to stdout/stderr.

Everything works fine in Docker, so it does appear to be an issue specific to the fly runtime.

@md1 I’ve managed to replicate the problem as you’ve suggested with just the latest image, but we still don’t know the exact cause.

All the other images that are running on Fly are writing to stdout/stderr, even the ones spawned as nobody. Even in this case the EACCES error itself is being written there correctly, which is why we’re able to see it at all.

Will try to figure out what’s going on, I’m basically trying to adjust the permissions on every directory used one at a time to see what’s special about this, but no luck so far.

Thanks for confirming I am not crazy!

I’ll continue to try and debug on my end, but I would appreciate any assistance in figuring out what is unique to Fly that breaks the universe.

2 Likes

Any idea what might be going on here? @sudhir.j

Not yet. I wasn’t able to figure it out with the default Dockerfile. If you’re ok with modifying the Dockerfile I’d suggest removing the switch to the nobody user, that should help a bit, but all the surrounding files will need to be checked as well.

@sudhir.j I’m curious if you ever found a solution, or a better alternative Dockerfile to use? I’m running into the same permissions issues with trafex/docker-php-nginx, even after mucking around with permissions on different files.

I don’t quite see Sudhir around anymore.

Anyways, see: Permissions Error Attempting To Read From stdout - #2 by greg

It could be supervisord (which docker-php-nginx uses as a process supervisor) that’s mucking with your log output?

1 Like

Yeah, building on that from @ignoramous my answer was in turn based on Fly’s own example for how to run multiple processes. This one:

As I recall … it only worked when the user was root. As per the Fly example. But in the docker-php-nginx Dockerfile they don’t use root. And hence that could explain the permission issue.

1 Like

Ahh, that makes sense. I modified the Dockerfile to use hivemind instead (as suggested in the docs you linked) and that seems to have done the trick!

The end result looks something like this, and works just fine as the nobody user from trafex/php-nginx:

FROM trafex/php-nginx:2.6.0

# ...

RUN curl -fsSL https://github.com/DarthSim/hivemind/releases/download/v1.1.0/hivemind-v1.1.0-linux-amd64.gz | gunzip -c > /usr/local/bin/hivemind && chmod +x /usr/local/bin/hivemind

# ...

ENTRYPOINT [ "hivemind", "/path/to/Procfile" ]
1 Like

I ran into this issue as well, and wrote up the specifics with what I’m encountering in Container (non-root) user can't write to /dev/stdout or /dev/stderr. What’s weird there is:

echo "hi"

works, but:

echo "hi" >> /dev/stdout

fails with a permission denied, which contradicts the comment in Allow non-root users to write to stdout/stderr - #5 by jerome.

Actual files backing stdin/out/err for entrypoint (main / server) process are pipes (code) owned by run-as user.

# from fly ssh console; where 520 is the entrypoint-pid (server process)
# fd/1 is stdout
ls -lhtr /proc/520/fd/1
l-wx------    1 <run-as>     <run-as>          64 Jan 26 21:58 /proc/520/fd/1 -> pipe:[4403]
...

I not am really sure, but I believe the reason why writing to /dev/stdout from fly ssh (interactive shell) doesn’t work is because the char device /dev/pts/1 is owned by root with no world permissions even if the link /proc/<entrypoint-pid>/fd/1 is owned by USER (shell-user) one is running the interactive shell as.

# from fly ssh console; su <shell-user>
ls -lhtr /dev/pts/0 
...
crw--w----    1 root     tty       136,   0 Jan 26 22:15 /dev/pts/0
...
ls -lhtr /proc/self/fd/1
lrwx------    1 <shell-user>     <shell-user>          64 Jan 26 22:15 /proc/self/fd/1 -> /dev/pts/0
1 Like