I try to run httpd:2.4-alpine docker image not as a root user.
Default behavior :
> docker run -p 80:80 -d --rm --name httpd httpd:2.4-alpine
3c271ae8abfc3f54c0e63d62a2ce26fcbeeef29064da66f4b3f6bd00480ad4fb
> docker exec httpd --name httpd whoami
root
After looking inside the Dockerfile definition of this image, one can see a www-data
is created with an id 82
:
...
RUN set -x
&& adduser -u 82 -D -S -G www-data www-data
# 82 is the standard uid/gid for "www-data" in Alpine
...
Let’s try to run this image using this user then :
> docker stop httpd # cleaning previous instance
> docker run -p 80:80 --rm --name httpd -u www-data httpd:2.4-alpine
This failed with this error :
AH00558: httpd: Could not reliably determine the server’s fully
qualified domain name, using 172.17.0.3. Set the ‘ServerName’
directive globally to suppress this message AH00558: httpd: Could not
reliably determine the server’s fully qualified domain name, using
172.17.0.3. Set the ‘ServerName’ directive globally to suppress this message [Tue Aug 30 15:57:25.958695 2022] [core:error] [pid 1:tid
140459379268424] (13)Permission denied: AH00099: could not create
/usr/local/apache2/logs/httpd.pid.XXXXXX [Tue Aug 30 15:57:25.959029
2022] [core:error] [pid 1:tid 140459379268424] AH00100: httpd: could
not log pid to file /usr/local/apache2/logs/httpd.pid
I’ve found this answer that seems to fix the problem, but because I’m in a docker context I don’t know how/if I can apply this solution.
Does someone out there know how I could run this image NOT as a root ?
2
Answers
The reason for this is that by default the user
www-data
lacks the capability to bind a privileged port, in fact, any other regular will have the same issue.As you can see, only the parent process runs as the
root
user, and child processes run as thewww-data
user.By setting
setcap 'cap_net_bind_service=+ep'
to thehttpd
binary, you’ll be able to run it as thewww-data
user.In order to fix this, you need to create a new image, this is a Dockerfile example:
Once you have created the new image, you’ll be able to run the image as non-root.
Logs:
Running as:
While @javierlga’s answer is correct, you don’t need to build a new image to remediate this issue. There are three things we need to do:
www-data
userwww-data
user the ability to bind to privileged ports, and/usr/local/apache2/logs
.We can accomplish (1) using the
-u
argument todocker run
:We can solve (2) using with the
--cap-add
argument todocker run
:That leaves us with (3). We can see the problem in the logs you posted in your question:
Apache is trying to write a file into
/usr/local/apache2/logs
, butthe
www-data
user does not have permission to create files in thisdirectory.
There are a number of ways of solving this problem. The simplest is probably moving the pidfile to
/tmp
, which we can do by passing the necessary configuration directive tohttpd
using the-C
command line option:Putting it all together, we get:
Or in a
docker-compose.yaml
file:That runs without errors and does not require maintaining our own image.