Open damienfern opened 1 month ago
Hi, @damienfern
I'm also interested in this question!
For now I'm using the following edits to run FrankenPHP as the built-in user www-data
.
@@ -53,8 +53,9 @@
fi
fi
- setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var
- setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var
+ chgrp -R www-data var /data /config
+ setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var /data /config
+ setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var /data /config
fi
-exec docker-php-entrypoint "$@"
+su -c "docker-php-entrypoint $*" -s '/bin/sh' 'www-data'
With this edit the container still runs as root
, but FrankenPHP runs as www-data
.
I'm not sure if this is the correct way, but in my case it works so far.
I would also be glad if this template contained information about a more correct way to run the container not as an privileged user.
Modifying the Dockerfile
like this should help: https://frankenphp.dev/docs/docker/#running-as-a-non-root-user
A doc PR explaining how to change this template to run as a non-root user is very welcome, however, we'll not do that by default, because this causes many issues.
Found a problem when using the method I described above (using su ...
instead of exec ...
): when using su ...
a chain of subprocesses is created (entrypoint→su→sh→frankenphp), while when using exec ...
there is no chain (frankenphp).
Due to the chain, signals sent by Docker do not reach the target process. This primarily negatively affects the Symfony Messenger consumer.
Processes when using exec ... : |
PID | USER | Command |
---|---|---|---|
1 | root | frankenphp run --config /etc/caddy/Caddyfile |
Processes when using su ... : |
PID | USER | Command |
---|---|---|---|
1 | root | /bin/sh /usr/local/bin/docker-entrypoint frankenphp run --config /etc/caddy/Caddyfile |
|
33 | root | `- su -c docker-php-entrypoint frankenphp run --config /etc/caddy/Caddyfile -s /usr/bin/sh www-data |
|
34 | www‑data | `- sh -c frankenphp run --config /etc/caddy/Caddyfile |
|
35 | www‑data | `- frankenphp run --config /etc/caddy/Caddyfile |
Hi @7-zete-7,
You should give a try to https://github.com/tianon/gosu as it uses the same methods to "impersonate" user as Docker, but it uses an exec instead of a subprocess (which, as you pointed, handles the signal better).
Thanks for such a quick response, @damienfern!
I'll try using gosu
for this task.
gosu
actually changes the user and does not create any subprocesses. Thanks, @damienfern!
Some update of https://github.com/dunglas/symfony-docker/issues/679#issuecomment-2434587889 to work via gosu
.
@@ -27,8 +27,9 @@
RUN set -eux; \
install-php-extensions \
@composer \
apcu \
+ gosu \
intl \
opcache \
zip \
;
@@ -53,8 +53,9 @@
fi
fi
- setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var
- setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var
+ chgrp -R www-data var /data /config
+ setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var /data /config
+ setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var /data /config
fi
-exec docker-php-entrypoint "$@"
+exec /usr/sbin/gosu www-data "$@"
Still not sure if this is the correct way, but it works for now.
Have you tried to use gosu directly ? Based on the gosu's README, it already does an exec.
-exec /usr/sbin/gosu www-data "$@"
+/usr/sbin/gosu www-data "$@"
@damienfern, yes, I did this first. I was surprised that there was a chain of processes and tried with exec
. With exec
the chain was gone.
PID | USER | Command |
---|---|---|
1 | www-data | frankenphp run --config /etc/caddy/Caddyfile
|
PID | USER | Command |
---|---|---|
1 | root | /bin/sh /usr/local/bin/docker-entrypoint frankenphp run --config /etc/caddy/Caddyfile
|
20 | www-data | `- frankenphp run --config /etc/caddy/Caddyfile
|
Hi,
Thx for this template, very useful ! :pray:
Many resources suggest using an unprivileged user in container in order to prevent privilege escalation attacks(e.g. OWASP https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-2-set-a-user or Docker docs https://docs.docker.com/build/building/best-practices/#user).
It seems it's not the case on this template with FrankenPHP and based on its doc, FrankenPHP can be used with an unprivileged user. Is it on purpose, or is it a feature that can be added to this template ?