docker-library / httpd

Docker Official Image packaging for Apache HTTP Server
https://httpd.apache.org
Apache License 2.0
310 stars 345 forks source link

http-foreground is bypassing apachectl #197

Closed Saaha closed 2 years ago

Saaha commented 3 years ago

Hello !

Sorry if I get wrong, but the script http-foreground is bypassing the standard script for running httpd. The main issue is that /usr/local/apache2/bin/envvars is not loaded by httpd which is normaly done by apachectl.

From man page :

In general, apache2 should not be invoked directly, but rather should be invoked via /etc/init.d/apache2 or apache2ctl. The default Debian configuration requires environment variables that are defined in /etc/apache2/envvars and are not available if apache2 is started directly. However, apache2ctl can be used to pass arbitrary arguments to apache2.

Currently I bypassed the official CMD entry point with CMD ["/usr/local/apache2/bin/apachectl", "-DFOREGROUND"]. I am probably missing something, is it done on purpose ?

I should recommend to update http-foreground script with apachectl binary.

yosifkit commented 3 years ago

apachectl is meant for controlling a service under a regular init system; There is no init system running in the container, so it is better to just run httpd directly. Plus apachectl doesn't exec the httpd process so if httpd stays in the foreground, then the shell running the script stays resident rather than letting httpd be pid 1 of the container thus interfering with signals. (On the other hand, if we don't use -DFOREGROUND and let httpd start in the background, the shell script would exit (pid 1) and docker would consider the container done and kill any other pids to clean up the container.)

We could add a sourcing of envvars, but the default doesn't provide anything (just an LD_LIBRARY_PATH to a non-existent directory) and users can more flexibly set variables through docker run (or via the orchestration platform of choice).

Saaha commented 3 years ago

Ok I got it. It's all about making httpd having pid of 1. What's the consequences of having httpd with a pid other than 1 ?

But, in my case, PassEnv or SetEnv directives are not enough (from my knowledge).

I need to extend PATH environment variable of www-data user, I don't see how to make this without using envvars file. Passing env variables from -e option on runtime is not enough in this case because of environment variables scope.

Edit : I used a workaround by inserting a line in the httpd-foreground script (same as apachectl) from Dockerfile to export variables, so I can still run httpd-foreground and stay with pid 1. That corresponds to the solution you mentioned. It could be great to source it for use cases such as mine.

tianon commented 3 years ago

I'm confused about your PATH-related use case -- if you need something added to path, something like the following in a Dockerfile should do the trick?

ENV PATH $PATH:/foo/bar/baz
# or
ENV PATH /foo/bar/baz:$PATH
# (depending on your desired precedence)
Saaha commented 3 years ago

In my Dockerfile recipe, I indeed set ENV variables like this (and more with docker-compose on runtime).

But, from official documentation, I red that environement variables are not pass through apache directly that's why I use PassEnv apache directive to do this (some are passed through on runtime with docker-compose since to apache with PassEnv). Withtout PassEnv, I cannot access to some variables I need. In a word, the environment variables from root shell are not passed through to apache directly.

But this directive does not work for PATH variable, that's why I used envvars.

Saaha commented 3 years ago

Some news about this ?

yosifkit commented 3 years ago

I am a little unsure of the exact problem; could you provide your Dockerfile, shell script, etc?

Doing export variable in a shell script will produce an identical result for the running process as ENV in a Dockerfile or environment in docker-compose yaml. If you are adding something like su or sudo in between, then it does explicit cleaning/resetting of sensitive things like PATH or LD_LIBRARY_PATH.