Sometimes I use a command like the following to initialize a mysql new database volume from a backup.
docker run --rm ... --volume /path/to/backup.sql:/docker-entrypoint-initdb.d/backup.sql mysql
It would be handy if I could (through a environment variable, alternative entrypoint, etc.) cause the docker container to stop running after the init process is complete, instead of listening for connections.
My current workaround (hack) is to build a new image based on the mysql image, that contains a shell script that waits for the init process to finish - and then kill the mysql service. This seems to work fine, but it would be nice if there was a baked in way to accomplish this behavior.
#!/bin/bash
set -e
# wait until init process is finished
until /docker-entrypoint.sh mysqld 2>&1 | \
tee /dev/tty | \
grep --silent --extended-regexp --max-count=1 "init process done|error";
do
sleep 1;
done
# shutdown container
kill -s TERM $$
Why not just make your script alphabetically after your backup file in docker-entrypoint-initdb.d and then you can do something like the following:
#!/bin/bash
set -e
# you should have access to any vars from the entrypoint since scripts are sourced
kill -s TERM "$pid"
wait "$pid"
# or
killall -s TERM mysqld
sleep 10
# prevent entrypoint from continuing
exit 1
The solution documented in this issue no longer works ($pid is no longer an accessible variable). The solution mentioned in https://github.com/docker-library/mysql/pull/423#issuecomment-562355462 works but will have to be manually updated every time the implementation changes.
Are there plans to support this now that https://github.com/docker-library/mysql/pull/471 is merged?
You should be able to invoke docker_temp_server_stop to stop the temporary server, followed by exit in order to stop the execution of any further instructions (as above).
Also, with #471 you could more easily write your own script which just does the initialization followed by exiting (and thus be much less error-prone).
A script that copies _main from docker-entrypoint.sh becomes error-prone the moment a name used within _main changes, or a new (and necessary) command is added. What I'd like to do is just run _main without the last line.
Maybe I'm confused and there's an easier way to go about this?
I'm not sure if this works for everyone else interested - but I have since found a clean solution for my needs:
I simply append the SQL SHUTDOWN statement at the end of my bootstrap script!
https://dev.mysql.com/doc/refman/5.7/en/shutdown.html
As far as I'm concerned, this is a good solution. If there are no objections, I think it's safe to close this issue?
I try this one out today, thanks!
Works as intended for my use case; this should be the recommended solution
This is the command I run at the end of my bootstrap script:
mysql -u root -A -e "SHUTDOWN;"
But, the container does not shut down and I see this error in the logs:
```2020-03-18 19:48:31+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/initdb.sh
mysql: [Warning] Using a password on the command line interface can be insecure.
2020-03-18T19:48:31.974925Z 10 [System] [MY-013172] [Server] Received SHUTDOWN from user root. Shutting down mysqld (Version: 8.0.19).
2020-03-18 19:48:31+00:00 [Note] [Entrypoint]: Stopping temporary server
mysqladmin: connect to server at 'localhost' failed
error: 'Lost connection to MySQL server at 'reading initial communication packet', system error: 104'
2020-03-18 19:48:32+00:00 [ERROR] [Entrypoint]: Unable to shut down server.
```
What am I doing wrong?
@marzigolbaz, you probably just need an exit 0 on the next line. The error comes because the entrypoint continues its regular shutdown after your shutdown. Be warned that if you exit during initdb, then you will not get anything from _main that happens later (which right now is just expiring the root password if you set MYSQL_ONETIME_PASSWORD).
Since the init scripts are sourced: https://github.com/docker-library/mysql/blob/d284e15821ac64b6eda1b146775bf4b6f4844077/.template.Debian/docker-entrypoint.sh#L61
You can just use the provided function to shut it down:
#!/bin/bash
# all your initialization steps...
docker_temp_server_stop
exit 0
@yosifkit thank you so much for your detailed clarification. Adding exit 0 fixed the issue. Thanks again.
Most helpful comment
@marzigolbaz, you probably just need an
exit 0on the next line. The error comes because the entrypoint continues its regular shutdown after your shutdown. Be warned that if you exit during initdb, then you will not get anything from_mainthat happens later (which right now is just expiring the root password if you setMYSQL_ONETIME_PASSWORD).https://github.com/docker-library/mysql/blob/d284e15821ac64b6eda1b146775bf4b6f4844077/.template.Debian/docker-entrypoint.sh#L355-L365
https://github.com/docker-library/mysql/blob/d284e15821ac64b6eda1b146775bf4b6f4844077/.template.Debian/docker-entrypoint.sh#L119-L123
Since the init scripts are sourced: https://github.com/docker-library/mysql/blob/d284e15821ac64b6eda1b146775bf4b6f4844077/.template.Debian/docker-entrypoint.sh#L61
You can just use the provided function to shut it down: