2

There are many questions on this site abut it but none of them give me a solution.

My dockerfile:

from php:7.2-apache

copy php.ini "$PHP_INI_DIR/php.ini"

copy symfony/ /var/www/html/
run chmod -R o+w /var/www/html/var/cache /var/www/html/var/logs /var/www/html/var/sessions

run docker-php-ext-install pdo_mysql opcache

copy exec.php /var/www/html/

my docker-compose.yml file:

version: '3'
services:
    web:
        build: .
        ports:
            - "8082:80"
        depends_on:
            - mysql
        command: ["php", "/var/www/html/exec.php"]
        #command: ["echo", "hello"]
    mysql:
        image: "mysql:5"
        environment:
            MYSQL_ROOT_PASSWORD: my-secret-pw

The problem comes from the command key. When I comment the commands the php-apache/web runs. from docker ps I can see the container. But when I add a command php-apache/web container died on php-apache_web_1 exited with code 0 and it is not shown from docker ps while the mysql container exists and I can interact with it.

From that answer someone says the container exit because the command is completed his task and exited. But I don't want my server to exit or die/kill. How to prevent the command from returning an exit status without running the command forever?

If you're curious about why I am running a command, my command do almost exactly how explained there.

Edited: What I want is a solution on how to keep my php apache server running and create a database in the mysql server once the php apache image has built.

I edited my codes according to a suggested answer but exec "$@" still exited with code 0:

The dockerfile:

from php:7.2-apache
copy php.ini "$PHP_INI_DIR/php.ini"

copy symfony/ /var/www/html/
run chmod -R o+w /var/www/html/var/cache /var/www/html/var/logs /var/www/html/var/sessions

run docker-php-ext-install pdo_mysql opcache

copy exec.php /var/www/html/

#using an sh script
copy run.sh /var/www/html/
run chmod u+x,g+x /var/www/html/run.sh

The docker-compose.yml file:

version: '3'
services:
    web:
        build: .
        ports:
            - "8082:80"
        depends_on:
            - mysql
        command: ["/var/www/html/run.sh"]
    mysql:
        image: "mysql:5"
        environment:
            MYSQL_ROOT_PASSWORD: my-secret-pw

The run.sh script:

#!/bin/sh
set -e

# Execute your custom scripts
php -f /var/www/html/exec.php

#End with running the original command
exec "$@"

Then to run the script I execute in the terminal:

docker-compose down
docker-compose build
docker-compose up
user3502626
  • 838
  • 11
  • 34
  • Do you use a certain web framework? – MEDZ Jan 05 '20 at 08:50
  • I use Symfony. But this is not the problem. And to be sure. The php script I called from the command line is pure PHP write by me (No framework). – user3502626 Jan 05 '20 at 08:56
  • If you specify a `command:` it runs _instead of_ the default `CMD` in the Dockerfile. In the example you've shown here there is no PHP Apache server to keep running, you're running your database migration script instead. – David Maze Jan 05 '20 at 12:34
  • @DavidMaze I totally forgot about that and also Apache runs in the foreground. Thanks for remind me that. And Pat just give me the answer I wanted. – user3502626 Jan 05 '20 at 19:04
  • @DavidMaze The Pat answer did not work. How can I run the apache command after running my command? – user3502626 Jan 05 '20 at 19:38

3 Answers3

2

In order to run commands before the container starts executing its command you can use a custom entrypoint.

#!/bin/sh
set -e

# Execute your custom scripts
php -f /var/www/html/exec.php

#End with running the original command
exec "$@"

For more information check out the official documentation for entrypoint

pat
  • 1,765
  • 8
  • 22
  • I run the exact script you provide and It still `php-apache_web_1 exited with code 0`. Please check out my edited question. – user3502626 Jan 05 '20 at 19:36
  • I also added `echo "$@"` at the end of the script and the output is blank. – user3502626 Jan 05 '20 at 19:46
  • You need to explicitly specify your run.sh script with the ENTRYPOINT command in the Dockerfile. You can then remove the command definition completely from the docker-compose file to fall back to the original command from the base image. – pat Jan 05 '20 at 20:29
  • I still have to start the apache service myself because I have already seen the `exec "$@"` code in the docker documentation but, I never understood why did they put that code in the script `exec "$@"`. `"$@"` return all the parameters passed to the script ([refrence](https://stackoverflow.com/questions/9994295/what-does-mean-in-a-shell-script)) from $1-$9. I just add `entrypoint ["/var/www/html/run.sh"]` in the dockerfile and commented `command` in the docker-compose file and the echo `"$@"` is a blank character. – user3502626 Jan 05 '20 at 21:09
  • Docker by default passes the specified command to the entrypoint script. To allow for the command to change images tend to not hard code the command in there. To know why your entrypoint isn't getting any parameters I would need a full example. However it is fine in your use case to just statically define it anyway. – pat Jan 05 '20 at 21:32
2

Thanks to pat answer I was able to make apache run.

The line exec "$@" did not work for me. "$@" was a blank string. But thanks to the link he provided, I found the script needed to run the apache service which is /usr/sbin/apache2ctl -D FOREGROUND. So instead of exec "$@" I wrote exec /usr/sbin/apache2ctl -D FOREGROUND at the end of the script.

The script is now:

#run.sh
#!/bin/sh
set -e

# Execute your custom scripts
php -f /var/www/html/exec.php

#End with running the original command
exec /usr/sbin/apache2ctl -D FOREGROUND

After taking a look at the image dockerfile or running docker inspect php:7.2-apache I found ENTRYPOINT ["docker-php-entrypoint"] and CMD ["apache2-foreground"].

So edit my script to exec docker-php-entrypoint apache2-foreground to make sure the image script executes properly.

user3502626
  • 838
  • 11
  • 34
0

You need to run a server and listen to a certain port in order keep the app running (listening to incoming requests). That's the idea behind keeping the server alive, because it receives requests. If your php file has a small task and it's done, It has no need to stay up.

So what you need is to have a web server and since you are using pure php, you may find this article useful about building web servers.

There is a quick hack for what you want to do which is to run php in interactive mode using -a flag. Try to include the following in your docker-compose file:

command: ["php", "-a", "/var/www/html/exec.php"]
MEDZ
  • 2,227
  • 2
  • 14
  • 18
  • Well, your answer is not very useful in this case because apache is going to listen for incoming requests even if no PHP script is running. As I mentioned, if I don't run any command the server still running. It just exited with code 0 only when I run a command. And the command does not necessarily to be a php script. If you take a look a the docker-compose file you will see another command commented: `command: "echo hello"` exits with a 0 code. – user3502626 Jan 05 '20 at 09:13
  • What I want is a solution on how to keep my php apache server running and create a database in the mysql server once the php apache image has built. – user3502626 Jan 05 '20 at 09:19
  • @user3502626 I've updated my answer to have a workaround that may satisfy your need. Let me know if it works. – MEDZ Jan 05 '20 at 09:24
  • I changed it to `command: ["php","-a", "/var/www/html/exec.php"]` and still having `exited with code 0` and the container does not show in `docker ps`. – user3502626 Jan 05 '20 at 09:42
  • Did you consider using `sleep(60 * 60)` to keep the file running in the background for an hour? – MEDZ Jan 05 '20 at 09:46
  • No. I don't want to let the script running to avoid overloading the container because having PHP running in the background all day long may impact incoming requests. But let the script running would be a temporary fix like append `tail -f /dev/null` to the command. But I prefer avoid the script running for ever. – user3502626 Jan 05 '20 at 10:01