I have a docker-compose.yml
with the following service:
services:
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
environment:
- MYSQL_USER=cct1
- MYSQL_DATABASE=cct1
- MYSQL_PORT=3306
- MYSQL_PASSWORD_FILE=/run/secrets/mysql-password
- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql-password
healthcheck:
test:
[
"CMD-SHELL",
# "sh",
# "-c",
"mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$(cat /run/secrets/mysql-password)"
]
start_period: 5s
interval: 3s
timeout: 5s
retries: 6
secrets:
- mysql-password
secrets:
mysql-password:
file: ./mysql_pwd.secret
When I run docker stack deploy stack-name
, the db
service fails (Received SHUTDOWN from user root
) and the reason is in the healthcheck. I have already found a working solution, but I am missing the logic: it seems that the mysqladmin ping ...
command must be run inside a shell using sh -c
:
[
"CMD-SHELL",
"sh",
"-c",
"mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$(cat /run/secrets/mysql-password)"
]
And it works.
What I have tried
The documentation is pretty clear on what CMD-SHELL
does:
Using
CMD-SHELL
runs the command configured as a string using the container’s default shell (/bin/sh
for Linux)
So why do I need an additional shell? Several other alternatives make the deployment fail, for example this one:
[
"CMD",
"sh",
"-c",
"mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$(cat /run/secrets/mysql-password)"
]
Why? The second shell seems mandatory, but I cannot understand the reason. I have also inspected the MySQL Docker image but the SHELL
is not overwritten.