1

I am building a docker machine using the image "mysql". I have some setup script to run for the first time the machine is built. This setup script will create some database and dabase users with specified permmissions.

Following are the minimized version of my files..

pcdb1.entrypoint.sh

#!/bin/sh

mysql -uroot -p'pass123' -e 'show databases MYENTRYDB;'

Dockerfile

FROM mysql:5.7

COPY ./pcdb1.entrypoint.sh /
ENTRYPOINT ["/pcdb1.entrypoint.sh"];

I am getting the following error in the log

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

pcdb1 exited with code 1

What I understood is, my script is trying to run before mysql is started. But I am not sure how to do it properly. Can I get a suggestion?

1 Answer 1

4

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.

  1. Get the whole entrypoint.sh script on your host.
  2. 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.
  3. 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"]

  4. 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.

Sign up to request clarification or add additional context in comments.

5 Comments

The mysql:5.7 image already has it's own Docker file and entrypoint script with which it will build the image, start mysql and initialize it. Isn't there any way that I can add my own initialization script on top of it while I am building a new docker machine? For your information I am using docker-compose to create my machines. Becuase this has some customer script, I am pointing to my own dockerfile from the docker-compose.yml
@BlueBird As you said, there is already a n entrypoint for mysql:5.7. You want custom init script, so you modify it or you replace it. As I know, it seems no other way. Maybe there is or maybe not.
@BlueBird I've updated answer, is that what you want?
Note that if: 1.) you place a sql script into /docker-entrypoint-initdb.d/ and 2.) you have a volume mounted for db persistence, then the volume must be deleted as well.
I am just mounting the sql as volume (in docker-compose.yml) as suggested in 1.) and it works fine. It also works with mysql 5.6

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.