19

I am trying to create a mysql database/schema if it doesn't already exist.

Here is what I have tried:

docker-compose.yml

mysql:
  image: mysql:5.6.26
  environment:
   - MYSQL_ROOT_PASSWORD=root
  command: "mysql -uroot -proot < createDB.sql"
  ports:
    - "3306:3306"

createDB.sql

CREATE DATABASE IF NOT EXISTS bignibou;

It does not work. What would be the best way to use docker/docker-compose in order to create a schema if it does not exist?

balteo
  • 23,602
  • 63
  • 219
  • 412

5 Answers5

25

I finally found the beginning of a solution.

The MySQL image takes an environment variable i.e. MYSQL_DATABASE that initialize the container with the name of the database on image startup See here for full documentation.

Or read the excerpt below:

MYSQL_DATABASE

This variable is optional and allows you to specify the name of a database to be created on image startup. If a user/password was supplied (see below) then that user will be granted superuser access (corresponding to GRANT ALL) to this database.

Here is what I came up with:

mysql:
  image: mysql:5.6.26
  environment:
   - MYSQL_ROOT_PASSWORD=root
   - MYSQL_DATABASE=bignibou
  ports:
    - "3306:3306"

I now need a way to specify the default collation but that is another story...

edit: For those interested in specifying a different collation from the default, here are the instructions to use another config file that will override the default one. See below:

Using a custom MySQL configuration file The MySQL startup configuration is specified in the file /etc/mysql/my.cnf, and that file in turn includes any files found in the /etc/mysql/conf.d directory that end with .cnf. Settings in files in this directory will augment and/or override settings in /etc/mysql/my.cnf. If you want to use a customized MySQL configuration, you can create your alternative configuration file in a directory on the host machine and then mount that directory location as /etc/mysql/conf.d inside the mysql container.

If /my/custom/config-file.cnf is the path and name of your custom configuration file, you can start your mysql container like this (note that only the directory path of the custom config file is used in this command):

$ docker run --name some-mysql -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag This will start a new container some-mysql where the MySQL instance uses the combined startup settings from /etc/mysql/my.cnf and /etc/mysql/conf.d/config-file.cnf, with settings from the latter taking precedence.

balteo
  • 23,602
  • 63
  • 219
  • 412
  • Trust me: a lot easier with scripts and a Dockerfile – Grasshopper Aug 24 '15 at 16:13
  • 3
    Here is a way to specify default collation in the docker-compose.yml file: mysql: image: mysql:5.7 command: [mysqld, --character-set-server=utf8mb4, --collation-server=utf8mb4_unicode_ci] – William Dec 20 '16 at 17:26
4

To not lost your data better use volumes as well:

version: '3'
services:
  db:
    image: mysql:5.7
    volumes:
        - mysql-db:/var/lib/mysql
    environment:
        MYSQL_ROOT_PASSWORD: root
        MYSQL_DATABASE: my_db_name
    ports:
        - "3307:3306"
volumes:
  mysql-db:
Codenator81
  • 126
  • 5
2

probably what you are trying to do needs an additional script. So if building an image instead of directly using a prebuilt image is an option for you, you need to use a Dockerfile and use a script file which first imports the script in MySql and then runs the service itself.

take a look at this answer: Docker - Initialize mysql database with schema

Community
  • 1
  • 1
mohamnag
  • 2,709
  • 5
  • 27
  • 40
  • Hi @mohamnag and thanks for your reply! I have added a comment to grasshopper's reply that applies to your post too. – balteo Aug 24 '15 at 15:24
  • the above mentioned link is the situation where you have a dockerfile and you dont know if DB is just a new one or is a older one which shall not be initialised. the best solution in your case very much depends on what version shall be upgraded to which version. some times mounting an external volume and reusing it on new one will work sometimes not. – mohamnag Aug 25 '15 at 19:22
0

From the docker-compose documentation - see Define Services - you can tell which Dockerfile it will use to build the image. Therefore you can create a Dockerfile based on the mysql image and create the database inside it using standard Dockerfile commands.

Grasshopper
  • 1,749
  • 1
  • 14
  • 30
  • Hi. Umm. The only issue is that if I want to upgrade to another version of mysql, I need to change the Dockerfile and update it with my custom command that creates the database. It is not a big deal but not completely clean as I am not extending the Dockerfile but modifying it... – balteo Aug 24 '15 at 15:22
0

This might be useful in case someone lands here in future. The real issue appears to be the "command" statement in the docker-compose file. Once the command finishes successfully the container will get destroyed. This sql script must be run only after docker-compose has run and containers have been created. docker-compose "command" is really to start a service in the container. In this case you overrode the mysql service with your command.

Dean Sha
  • 837
  • 1
  • 10
  • 15