How to combine CMD and ENTRYPOINT

Hi All,
i have a docker-compose script that, at the end of docker-image, exec ENTRYPOINT and CMD
Why, this? Because i have necessity to launch, when container start, a custom script and start apache2 in foreground, like this:

...
...
ENTRYPOINT ["bash", "/var/www/config/bootstrap.sh"]
CMD ["apache2-foreground"]

after “docker-compose build” and “docker-compose up” i have, in console, this result:

Attaching to formazionephp7-web-1
project-web-1  | total 16
project-web-1  | -rwxrwxrwx 1 www-data www-data 1815 Dec  2 14:51 .htaccess
project-web-1  | -rwxrwxrwx 1 www-data www-data  687 Dec  2 14:51 .gitignore
project-web-1  | drwxrwxrwx 1 www-data www-data 4096 Dec  2 14:51 FixedPages
project-web-1  | drwxrwxrwx 1 www-data www-data 4096 Dec  2 14:51 Extensions
project-web-1  | drwxrwxrwx 1 www-data www-data 4096 Dec  2 14:51 Messages
project-web-1  | drwxrwxrwx 1 www-data www-data 4096 Dec  2 14:51 TemplatesUSR
project-web-1  | -rwxrwxrwx 1 www-data www-data  318 Dec  2 14:51 favicon.ico
project-web-1  | drwxrwxrwx 1 www-data www-data 4096 Dec  2 14:51 .git
project-web-1  | drwxrwxr-x 1 www-data www-data 4096 Dec  5 05:15 Logs
project-web-1  | drwxrwxr-x 1 www-data www-data 4096 Dec  5 05:16 tmp
project-web-1  | lrwxrwxrwx 1 www-data www-data   35 Dec  5 14:10 AppData -> /var/www/SMBFormazionePHP7/AppData/
project-web-1  | lrwxrwxrwx 1 www-data www-data   33 Dec  5 14:10 embed -> /var/www/SMBFormazionePHP7/embed/
project-web-1  | lrwxrwxrwx 1 www-data www-data   33 Dec  5 14:10 files -> /var/www/SMBFormazionePHP7/files/
project-web-1  | lrwxrwxrwx 1 www-data www-data   34 Dec  5 14:10 images -> /var/www/SMBFormazionePHP7/images/
project-web-1  | lrwxrwxrwx 1 www-data www-data   23 Dec  5 14:10 cm -> /var/www/ContentManager
project-web-1  | lrwxrwxrwx 1 www-data www-data    8 Dec  5 14:10 admin -> cm/admin
project-web-1  | lrwxrwxrwx 1 www-data www-data   12 Dec  5 14:10 index.php -> cm/index.php
project-web-1  | drwxr-xr-x 1 root     root     4096 Dec  5 15:36 ..
project-web-1  | drwxrwxrwx 1 www-data www-data 4096 Dec  5 15:36 .
project-web-1  | -rwxr-xr-x 1 www-data www-data  606 Dec  5 15:36 site.conf.php
project-web-1 exited with code 0

“exited with code 0” it’s seems that command in CMD [“apache2-foreground”] is not execute because if comment code in ENTRYPOINT, output change:

it’s seems that apache2 is running in foreground mode.

Where am i wrong?
Thank you all.

When ENTRYPOINT and CMD are declared, CMD will become the argument of ENTRYPOINT.
Basically, your container starts bash /var/www/config/bootstrap.sh apache2-foreground.

Note: if you use container arguments (`docker run … repo:tag arg1 … argN) they will override the CMD command and will be used instead.

I have two suggestions:

  • instead of ENTRYPOINT ["bash", "/var/www/config/bootstrap.sh"], just use ENTRYPOINT ["/var/www/config/bootstrap.sh"]. Though make sure the bootstrap.sh script start with bash shebang #!/bin/bash). As a result execution of bootstrap.sh will have pid1, instead of bash that calls the scrip.
  • use exec "${@} at the last line of the bootstrap.sh script to exec the CMD arguments and effectively hand over pid1 to it.

Both changes are required for proper SIGTERM handling, when shutting down the container without risking to have orphaned processes .

2 Likes

As @meyay already mentioned, the CMD will be the argument of the entrypoint script. It means the will not run independently of the command as if it were a bootstrap phase executed by the same executor as the command. This is why you have to use the exec line as meyay suggested.

The execution can be more complicated and conditional, but it will not run automatically. Without it bash will have PID 1 and it would be responsible for forwarding signals, but it will not do that and the Apache HTTPD server will be killed forcefully every time after 10 seconds instead of shutting down gracefully.

In both cases bash would have PID 1. The difference is that in the first case docker ps would show

bash /var/www/config/bootstrap.sh apache2-foreground

and in the second it would only show

/var/www/config/bootstrap.sh apache2-foreground

It would not change the behavior that in the container the process would look like this:

bash /var/www/config/bootstrap.sh apache2-foreground

So exec is required in both cases.

Thanks a lot. It’s working.