EDIT: 20181007
I have found the way you mentioned in question--initialize DB while building docker image. But with a little difference, the way I found seems like initializing DB while running a container from image, although the initializing script was specified while building the image.
According to the official information about mysql:5.7, there is paragraph named "Initializing a fresh instance". We could just add a initializing script into the directory /docker-entrypoint-initdb.d, the default ENTRYPOINT and CMD of image mysql:5.7 would execute it after database start-up.
For example:
FROM mysql:5.7
COPY init-database.sql /docker-entrypoint-initdb.d/
content of init-database.sql:
create database light;
create user 'light'@'%' identified by 'abc123';
grant all privileges on light.* to 'light'@'%' identified by 'abc123';
grant all privileges on light.* to 'light'@'localhost' identified by 'abc123';
Build new image:
docker build -t light/mysql:5.7 .
Run a container:
docker run -tid --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD='abc123' light/mysql:5.7
Examine initialization:
docker run -ti mysql /bin/bash
root@25e73d40c4ff:/# mysql -uroot -p
Enter password: (abc123)
Welcome to the MySQL monitor.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
All work well.
Former answer below.
How to start mysql damon in container?
First of all, you are right on "trying to run before mysql is started" part. But still, there is a missing on "how MySQL starts exactly". If you execute docker history mysql:5.7 --no-trunc, you could see three important records among output like below:
/bin/sh -c #(nop) CMD ["mysqld"]
/bin/sh -c #(nop) ENTRYPOINT ["docker-entrypoint.sh"]
/bin/sh -c ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh
So far we should know when we start a mysql container with command below, the exact initial command in container is docker-entrypoint.sh mysqld.
docker run -tid -e MYSQL_ROOT_PASSWORD='abc123' mysql:5.7
How to initiate mysql in container?
Secondly, let's now have a check on docker-entrypoint.sh script.
There is a specific line like below, just at roughly middle position of this script, which means to start mysql daemon.
mysql=( mysql --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" )
After starting mysql, we could see lots of initiating statements in docker-entrypoint.sh script. Such as creating root user with password or not, granting privileges to root, creating database declared by users with MYSQL_DATABASE env and so on.
Now here are solutions offered for you.
Self-defining the docker-entrypoint.sh script.
In this way, you could whatever you want which is legal in mysql.
- Get the whole entrypoint.sh script on your host.
- Add your self-definition of mysql in the script, make your
self-defining content at the bottom of this script. I assume you
don't want to mess it with original content.
Build a new mysql image for your own with command and Dockerfile below.
command: docker build -t mysql:self .
Dockerfile:
FROM mysql:5.7
COPY /path/to/your-entrypoint.sh /
ENTRYPOINT ["/your-entrypoint.sh"]
CMD ["mysqld"]
If your don't want a new image, there is another way to change
ENTRYPOINT when you run a container. But still, you should make your own script available in container.
docker run -tid -v /path/to/your-entrypoint.sh:/entrypoint.sh -p 3306:3306 -e MYSQL_ROOT_PASSWORD='abc123' mysql:5.7
Using default ENVs provided by mysql:5.7
In this way, there is a limit, especially on "specified permmissions" you mentioned.
The ENVs you need are: MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD.
The command should like this:
docker run -tid -e MYSQL_ROOT_PASSWORD='abc123' -e MYSQL_DATABASE='apps' -e MYSQL_USER='light' -e MYSQL_PASSWORD='abc123' mysql:5.7
This means that the database apps and user light will be created automatically, and the user light will be granted superuser permissions for the database apps.
More reference here on hub.docker.com.