2

I have the following piece of definition in a Dockerfile:

# This aims to be the default value if -e is not present on the run command
ENV HOST_IP=127.0.0.1
...
COPY /container-files/etc/php.d/zz-php.ini /etc/php5/mods-available/zz-php.ini
RUN ln -s /etc/php5/mods-available/zz-php.ini /etc/php5/apache2/conf.d/zz-php.ini
COPY /container-files/init-scripts/setup_xdebug_ip.sh /usr/local/bin/setup_xdebug_ip.sh
RUN chmod +x /usr/local/bin/setup_xdebug_ip.sh
CMD ["/usr/local/bin/setup_xdebug_ip.sh", "/usr/local/bin/setup_php_settings.sh"]

This is the relevant piece of definition at zz-php.ini:

; Xdebug
[Xdebug]
xdebug.remote_enable=true
xdebug.remote_host="192.168.3.1"  => this should be overwrited by HOST_IP
xdebug.remote_port="9001"
xdebug.idekey="XDEBUG_PHPSTORM"

This is the content of the script setup_xdebug_ip.sh:

#!/usr/bin/bash

sed -i -E "s/xdebug.remote_host.*/xdebug.remote_host=$HOST_IP/" /etc/php5/apache2/conf.d/zz-php.ini

Updated the script

I have updated the script to see it that's the reason why the value isn't changed and still not working. See the code below:

#!/usr/bin/bash

sed -ri "s/^xdebug.remote_host\s*=.*$//g" /etc/php5/apache2/conf.d/zz-php.ini
echo "xdebug.remote_host = $HOST_IP" >> /etc/php5/apache2/conf.d/zz-php.ini

In order to build the image and run the container I follow this steps:

  • Build the image:

    docker build -t reynierpm/dev-php55 .
    
  • Run the container:

    docker run -e HOST_IP=$(hostname -I | cut -d' ' -f1) 
               --name dev-php5 
               -it /bin/bash reynierpm/dev-php55
    

After the image gets built and the container is running I open a browser and point to: http://container_address/index.php (which contains phpinfo()) and I can see the value of xdebug.remote_host as 192.168.3.1 ...

why? What is not running when the container start? Why the value doesn't get overwritten using the provided value by -e on the run command?

UPDATE:

I've notice that I am only copying the file and setting up the permissions but I am not running it at all:

# Copy the script for change the xdebug.remote_host value based on HOST_IP    
COPY /container-files/init-scripts/setup_xdebug_ip.sh /usr/local/bin/setup_xdebug_ip.sh

# Execute the script
RUN chmod +x /usr/local/bin/setup_xdebug_ip.sh

Could this be the issue? Everything that I put under /usr/local/bin is executed at container start? If not that's definitively the issue or at least I think.

UPDATE #2:

After the suggestions from @charles-dufly I've fixed a few things but still not working.

Now the Dockerfile looks like:

# This aims to be the default value if -e is not present on the run command
ENV HOST_IP=127.0.0.1
...
ADD container-files /
RUN chmod +x /usr/local/bin/setup_xdebug_ip && \
/usr/local/bin/setup_xdebug_ip && \
chmod +x /usr/local/bin/setup_php_settings && \
ln -s /etc/php5/mods-available/zz-php.ini /etc/php5/apache2/conf.d/zz-php.ini && \
ln -s /etc/php5/mods-available/zz-php-directories.ini /etc/php5/apache2/conf.d/zz-php-directories.ini && \
a2enmod rewrite

EXPOSE 80 9001

CMD ["/usr/local/bin/setup_php_settings"]

After build the image I am running the following command:

$ docker run -e HOST_IP=192.168.3.120 -p 80:80 --name php55-img-6 -it reynierpm/php5-dev-4 /bin/bash

I can see the value of xdebug.remote_host being set as 127.0.0.1 but is not taking the value passed as -e on the run command, why?

ReynierPM
  • 17,594
  • 53
  • 193
  • 363
  • Well, I'm not a Docker expert, but if you're expecting the `RUN chmod ...` line to execute the script, I'm pretty sure it's not going to do that. That looks like it will only set the permissions. Trying adding another line, `RUN /usr/local/bin/setup_xdebug_ip.sh` at the end. – ccarton Sep 26 '16 at 15:19
  • 1
    Things in `/usr/local/bin` *never were* automatically executed. Not on any Linux distribution ever, since [according to the Filesystem Hierarchy Standard](https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard), `/usr/local/bin` is a place for local additions equivalent to `/usr/bin`, and nobody would ever automatically execute everything under `/usr/bin`. – Charles Duffy Sep 26 '16 at 15:30
  • @CharlesDuffy that makes sense and it's what I was concerned about, I will try to add a `CMD` or `RUN` command and will come back when I have something to say it works or it doesn't – ReynierPM Sep 26 '16 at 15:33

2 Answers2

2

You're correct in that items under /usr/local/bin are not automatically executed.

The Filesystem Hierarchy Standard specifies /usr/local as a "tertiary hierarchy" with its own bin, lib, &c. subdirectories, equivalent in their intent and use to the like-named directories under / or /usr but for content installed local to the machine (in practice, this means software installed without the benefit of the local distro's packaging system).

If you want a command to be executed, you need a RUN that directly or indirectly invokes it.


As for the other matters discussed as this question has morphed, consider the following:

FROM alpine
ENV foo=bar
RUN echo $foo >/tmp/foo-value
CMD cat /tmp/foo-value; echo $foo

When invoked with:

docker run -e foo=qux

...this emits as output:

bar
qux

...because bar is the environment variable laid down by the RUN command, whereas qux is the environment variable as it exists at the CMD command's execution.

Thus, to ensure that an environment variable is honored in configuration, it must be read and applied during the CMD's execution, not during a prior RUN stage.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Ok, take a look to the update I've made to the OP (the last lines at first code sample where is the `CMD`), it's suppose that the command will run the files, right? well the result is the same as in the OP, the value is not being set properly – ReynierPM Sep 26 '16 at 15:36
  • Your current command doesn't make sense. Passing `"/usr/local/bin/setup_php_settings.sh"` as an argument to `"/usr/local/bin/setup_xdebug_ip.sh"` isn't going to execute the former, since the latter doesn't ever look at its argument, much less try to execute that argument as a command. – Charles Duffy Sep 26 '16 at 15:38
  • Use a `RUN`, not a `CMD` array entry, for additional scripts to run as prerequisites. And consider using `set -x` (as via making your shebang `#!/usr/bin/env bash -x`) to log what your scripts are actually doing. – Charles Duffy Sep 26 '16 at 15:39
  • Can you add an example of this latest comment on your answer? Sorry I am new to Docker and I am still learning – ReynierPM Sep 26 '16 at 15:40
  • Not a Docker suggestion, a bash suggestion. Edit your `setup_php_settings.sh` to change the first line from `#!/usr/bin/bash` to `#!/usr/bin/env bash -x`, and the commands run will be logged to stderr, so you can read those logs and see what's actually being run in practice, and (1) ensure that the script really is run, and (2) compare it to what you expect. – Charles Duffy Sep 26 '16 at 15:41
  • @ReynierPM, ...and the other part, which *is* a Docker suggestion, is to have a `RUN /usr/local/bin/setup_xdebug_ip.sh` followed by a `CMD /usr/local/bin/setup_php_settings.sh` (assuming that your `setup_php_settings.sh` actually exec's the service process at the end; if it doesn't, you need to fix it to actually do that). – Charles Duffy Sep 26 '16 at 15:43
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/124229/discussion-between-reynierpm-and-charles-duffy). – ReynierPM Sep 26 '16 at 15:44
  • Can you take a look at the **UPDATE #2** on OP? I am still doing something wrong and I can't find what is it – ReynierPM Sep 26 '16 at 20:42
  • 1
    Move the update you want to be impacted by the environment variable set at runtime into your `setup_php_settings` script. Your `RUN`s aren't re-executed every invocation, whereas `CMD` contents are. – Charles Duffy Sep 26 '16 at 20:46
  • 3
    By the way -- having a bounty gets folks a significant bit of leeway around normal site rules, but under usual circumstances "chameleon questions" (that change from the original question asked into new problems encountered after that first issue is fixed) are rather heavily frowned on. – Charles Duffy Sep 26 '16 at 20:46
  • Still not working, even if I pass the ENV var as `-e HOST_IP=xxx.yyy.zzz.ttt` I am still seing the `xdebug.remote_host` being set as localhost and I already moved the code to the script on the CMD, what else could be wrong here? Thanks for the advise around the "topic change" won't happen again – ReynierPM Sep 26 '16 at 21:14
  • Interesting. I'd want to repro -- if you run `env` in the CMD-launched script to dump environment variables, which value does it show? – Charles Duffy Sep 26 '16 at 21:19
  • I took the time to reproduce, and the behavior I'm getting is in line with what I stated earlier: Your CMD or ENTRYPOINT gets environment updates passed on the `docker run` command line, whereas prior RUN stages using ENV values set from the Dockerfile are not reexecuted. If the behavior you're seeing is contrary to that, please post a reproducer complete enough that someone else can run it and validate identical behavior. – Charles Duffy Sep 26 '16 at 23:09
  • Maybe will be better if you take a look to the repo [here](https://github.com/reypm/php55-dev) if you want we can cleanup the post and start from the original issue but take a look to the repo, those are the latest files – ReynierPM Sep 27 '16 at 03:34
1

Multiple problems with your repo:

First of all when using CMD in docker file, the command added after the image name in the docker run : /bin/bash will override the CMD ["/usr/local/bin/setup_php_settings"] from your Dockerfile.

Thus your setup_php_settings is never executed! You should use ENTRYPOINT i.s.o. CMD in your Dockerfile. I found good explanation here and here.

In conclusion for the Dockerfile change the CMD [...] line in:

ENTRYPOINT bash -C '/usr/local/bin/setup_php_settings';'bash'

then you can run your container with:

docker run -it -e HOST_IP=<your_ip_address> -e PHP_ERROR_REPORTING='E_ALL & ~E_STRICT' -p 80:80 --name dev-php5 mmi/dev-php55

No need to add /bin/bash at the end. Check-out test-repo for test-setup.

Secondly, in your /usr/local/bin/setup_php_settings, you should add

a2enmod rewrite
service apache2 restart

at the end, just before

source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND`

this in order for your new settings to be applied in your web app.

Danny
  • 1,603
  • 1
  • 15
  • 25
  • This works like a charm, many thanks for taking the time and check those errors and make suggestions – ReynierPM Sep 27 '16 at 13:14
  • One question, be inside the container and exit from there cause the container to end, how do I keep it running even if I exit from the bash? – ReynierPM Sep 27 '16 at 13:18
  • Then you would have to start it with -d, rest can be same, and connect to container, check out my readme.md on my test-repo – Danny Sep 27 '16 at 13:21
  • I've started using `-d` and yes it goes to background and it keeps running, then I can attach to the container but again as soon as I type `exit` inside the container it stops the execution, how do I keep it running even after? – ReynierPM Sep 27 '16 at 13:50
  • See http://stackoverflow.com/questions/19688314/how-do-you-attach-and-detach-from-dockers-process – Danny Sep 27 '16 at 14:41
  • I have upvoted :) and that works: `docker exec -it ` does the job, that's what I was looking for – ReynierPM Sep 27 '16 at 14:45
  • as this answer is the answer to your question "This works like a charm", why is another answer that did not solve the question is being accepted and rewarded with a bonus? – Danny Sep 28 '16 at 08:04
  • you're right, I accepted yours but I can not give you the bounty since it was assigned to the other user, that was my bad, apologies – ReynierPM Sep 28 '16 at 12:22