Automation of container creation and creating image with DB packed

I want to create an image that will have mysql with the database included.

I created mysql container and imported DB with the steps:

  1. docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.9

  2. created catalog mysql db inside of the container

  3. docker exec -i mysql-container mysql -uroot -proot catalog < sample.sql

Then I pushed the image into the DockerHub:

  1. docker tag <image-id> tenzan/mysql-container:20151210

  2. docker push tenzan/mysql-container

But it seems, the pushed tenzan/mysql-container won’t include the database created in step #3.

Questions:

  1. I want to automate the steps 1-3. Dockerfile or docker-compose.yml? And what’s the commands?

  2. How to create image with the database included? Let me know if I’m on the wrong way.

The official mysql image stores its data in a volume.

If you do want a database to populate on first run, then the mysql image does have a mechanism to make that happen:

FROM mysql:5.7.9
ADD sample.sql /docker-entrypoint-initdb.d/sample.sql

And then build it with: docker build -t tenzan/mysql:20151210

When the mysql image starts up, its entrypoint script will load anything it sees in the /docker-entrypoint-initdb.d/ directory.

Additionally, when you docker tag <image-id> tenzan/mysql-container:20151210, that creates another name for the exact same image id that you specify. Images are immutable, and you have to create new image layers (using a Dockerfile and docker build, or using docker commit).

Cheers!

1 Like

Is there any general thoughts if this is a good practice or not?

ADD sample.sql /docker-entrypoint-initdb.d/sample.sql

This wasn’t populating a database, later I found out that I had to add the following commands in the sample.sql and it was ok.

DROP DATABASE IF EXISTS `catalog`;
CREATE DATABASE catalog;
USE catalog;

Is it possible to apply root password within a Dockerfile, so that I won’t specify -e MYSQL_ROOT_PASSWORD=root when starting up a container?

Thanks.

This is expected behavior: the files inside the /docker-entrypoint-initdb.d/ are simply sourced, and will only create a database if they include the SQL statements to do so. The entrypoint script doesn’t implement any sort of magic to try to figure out which commands to issue to create a database for you.

You could indeed set an environment variable in the Dockerfile-- just do something like:

ENV MYSQL_ROOT_PASSWORD=HH76Iyy4ho9dehDU
1 Like