问题
I would like to create a MySQL database using environment variables in docker-compose.yml file, but it is not working. I have the following code:
# The Database
database:
image: mysql:5.7
volumes:
- dbdata:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: homestead
MYSQL_USER: root
MYSQL_PASSWORD: secret
ports:
- "33061:3306"
Could someone explain the function of this vars?
回答1:
There is also an option to provide an init file for mysql container which will be applied each time a container is created.
database:
image: mysql:5.7
ports:
- "33061:3306"
command: --init-file /data/application/init.sql
volumes:
- ./init.sql:/data/application/init.sql
environment:
MYSQL_ROOT_USER: root
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: homestead
MYSQL_USER: root
MYSQL_PASSWORD: secret
Such file (init.sql) could contain your initial database structure and data - for example:
CREATE DATABASE IF NOT EXISTS dev;
CREATE DATABASE IF NOT EXISTS test;
USE dev;
CREATE TABLE IF NOT EXISTS (...);
回答2:
The database is probably already initialized and the configuration is stored in /var/lib/mysql. Since you defined a volume for that location the config will survive a restart. The MySQL image will not reconfigure the database over and over again, it only does this once.
volumes:
- dbdata:/var/lib/mysql
If your database is empty you can reset the database by performing docker-compose down -v where the -v removes the volumes defined in the volume section. See https://docs.docker.com/compose/reference/down/. On the next docker-compose up the MySQL image will start fresh and will initialize the database with the configuration you've provided throug the environment section.
回答3:
For version 2 of docker-compose you'll .yml or .yaml can look like this:
version: '2'
volumes:
dbdata:
services:
mysql:
image: mysql:5.7
container_name: mysql
volumes:
- dbdata:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=homestead
- MYSQL_USER=root
- MYSQL_PASSWORD=secret
ports:
- "33061:3306"
start it with docker-compose up -d
and check:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a3567fb78d0d mysql:5.7 "docker-entrypoint..." 2 minutes ago Up 2 minutes 0.0.0.0:33061->3306/tcp mysql
docker exec -it a3567fb78d0d bash
root@a3567fb78d0d:/# mysql -u root -p homestead
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.17 MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| homestead |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
Your volume will be persisted in docker volume nameoffolder_dbdata (/var/lib/docker/volumes/...)
回答4:
Answering your question ...
One thing I use to do when building a new docker container is understand what the image I pull from does when is builded.
In your docker-compose.yml tou have this
# The Database
database:
image: mysql:5.7
This is the image you pull from, "mysql:5.7"
Dockerhub is a repository where you can find info of this images.
Do a google search "mysql:5.7 dockerhub"
First result is https://hub.docker.com/_/mysql/
There you have your image 5.7, if you click on 5.7 you have this
https://github.com/docker-library/mysql/blob/607b2a65aa76adf495730b9f7e6f28f146a9f95f/5.7/Dockerfile
Which is the Dockerfile from the image, you can have a look at interesting things that happen when building the image.
One of this is ENTRYPOINT ["docker-entrypoint.sh"]
This is the file that got executed when image is ready
I you go one level up in the repo you will see this file
https://github.com/docker-library/mysql/tree/607b2a65aa76adf495730b9f7e6f28f146a9f95f/5.7
The you can see your environment variables being used to create new database etc...
file_env 'MYSQL_DATABASE'
if [ "$MYSQL_DATABASE" ]; then
echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" | "${mysql[@]}"
mysql+=( "$MYSQL_DATABASE" )
fi
回答5:
If I understand your question correctly, you want to to have a container with a specific database in it. Like have a MySQL container with CREATE DATABASE mydb, etc. already executed. If so you need to use docker-entrypoint-initdb.d:
https://docs.docker.com/samples/library/mysql/#docker-secrets
When the official MySQL container is started for the first time, a new database will be created first. Then it will execute files with extensions .sh, .sql and .sql.gz that are found in /docker-entrypoint-initdb.d. So all you need to do is create /docker-entrypoint-initdb.d directory and put your initialisation script there.
回答6:
The official MySQL docker image added support for init scripts in their base image. They document the feature under their "Initializing a fresh instance" on the Docker Hub page.
Here are the steps I took to solve creating multiple database and users in the MySQL docker image:
- Create the init file (the Docker image recognizes .sh, .sql, and .sql.gz files) named
setup.sqlin the local directory named.docker - Place the commands inside
setup.sql(see below for an example) - Mount the setup script into the directory
fwithin thedocker-compose.yamlfile (see below for an example) - Run
docker-compose up -dand MySQL will run the code insidesetup.sql
Note: the script will run files alphabetically, so keep that in mind.
Example docker-compose.yaml
version: "3.5"
services:
mysql:
image: mysql
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: SomeRootPassword1!
MYSQL_USER: someuser
MYSQL_PASSWORD: Password1!
MYSQL_DATABASE: somedatabase
volumes:
- .docker/setup.sql:/docker-entrypoint-initdb.d/setup.sql
- db_data:/var/lib/mysql
volumes:
db_data:
Example setup.sql
-- create the databases
CREATE DATABASE IF NOT EXISTS projectone;
-- create the users for each database
CREATE USER 'projectoneuser'@'%' IDENTIFIED BY 'somepassword';
GRANT CREATE, ALTER, INDEX, LOCK TABLES, REFERENCES, UPDATE, DELETE, DROP, SELECT, INSERT ON `projectone`.* TO 'projectoneuser'@'%';
FLUSH PRIVILEGES;
来源:https://stackoverflow.com/questions/43322033/create-database-on-docker-compose-startup