docker compose yaml - command - mysql

I want to run a creation of a new database using mysql
this is the snippet I have in my docker-compose.yml file
mysql:
image: mysql
container_name: mysql-machine
ports:
- 3306:3306
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: true
MYSQL_DATABASE: mxdb
MYSQL_USER: mxdb
MYSQL_PASSWORD: mxdb
command: mysqladmin create testing_db
Now when i run docker-compose up
I watch the console, and it says
mysql_1 | mysqladmin: connect to server at 'localhost' failed
mysql_1 | error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)'
mysql_1 | Check that mysqld is running and that the socket: '/var/run/mysqld/mysqld.sock' exists!
So how do I re-write the command piece, so i get the service working properly?
I want to create more than one database. So manually using commands is the easiest way.

I think you should run the mysql container and then have another container do the data import. Example:
.credentials
MYSQL_ALLOW_EMPTY_PASSWORD=true
MYSQL_USER=mxdb
MYSQL_PASSWORD=mxdb
MYSQL_DATABASE=mxdb
Run the container:
docker run --name mydb -d --env-file .credentials mysql
If you want to import data from file, create a new container, link to the one that is already running and do the import:
docker run --rm -t --link mydb:DB -v /path/to/dump.sql:/dump.sql mysql bash -c "mysql -h DB -u mxdb -pmxdb mxdb < /dump.sql"
If you just want to run a command, use:
docker run --rm -t --link mydb:DB mysql mysql -h DB -u mxdb -pmxdb -e "CREATE DATABASE bar"
or
docker exec -t mydb mysql -u mxdb -pmxdb -e "CREATE DATABASE bar"

I don't think you should override the command to create the database.
In docker-compose, the command should be the command to start the given service in the docker image. In your case, the service is a MySQL server. If you gives a command for the mysql service in your docker_compose.yml, the MySQL server will never start.
What you should do is start the mysql service, and then run commands in it.
mysql:
image: mysql
container_name: mysql-machine
ports:
- 3306:3306
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: true
MYSQL_DATABASE: mxdb
MYSQL_USER: mxdb
MYSQL_PASSWORD: mxdb
Start the service:
docker-compose up
Connect to it:
mysql -umxdb -pmxdb
Then create the database:
create database testing_db;
If you need to automatize this database creation, you could put these SQL commands in a file, and do when needed:
cat init_db.sql | mysql -umxdb -pmxdb

If you use this image of mysql: tutum/mysql
You can add the name of the database you want to create at startup as an environment variable:
environment:
-ON_CREATE_DB="newdatabase"
Another solution is to put a shell script on the command part. In the script you start mysql and then create databases and add users:
command : run.sh
And on you script:
/usr/bin/mysqld_safe &
mysqladmin create testing_db

Related

How to run a MySQL command terminal in Docker, with a docker-compose server

Let's say I have the following compose file :
networks:
my_network:
services:
...
mysql:
container_name: "mysql"
image: "mysql:5.7"
volumes:
- ./mysql.cnf:/etc/mysql/conf.d/mysql.cnf
environment:
MYSQL_ROOT_PASSWORD: "password"
MYSQL_USER: "user"
MYSQL_PASSWORD: "password"
MYSQL_DATABASE: "test-db"
ports:
- "3306:3306"
restart: always
networks:
- my_network
Once I run docker-compose up, my services get started and I can see that my MySQL server is ready to accept connections. Now what do I need to do to access the mysql terminal prompt from "outside" the container ? I remember seeing a teacher run another docker container (from a new terminal), and access the MySQL command prompt, enabling him to manage the database by hand, from another terminal window, but I can't remember the command exactly.
I tried running a new Docker container like this :
docker run -it --rm --name mysqlterm \
--network="compose_project_my_network" \
--link mysql mysql:5.7 \
sh -c 'exec mysql \
-h "localhost" -P 3306" \
-uroot \
-ppassword'
But unfortunatly, the container can't connect to the MySQL server, giving me the following error : ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2).
I guess the "localhost" or 3306 port are wrong ? What should I put in these parameters ?
Thanks in advance for your answers :)
You need an ordinary MySQL client; if your host's package manager (Debian/Ubuntu APT, MacOS Homebrew, ...) has a packaged named something like mysql-client, that's it.
When you run mysql, that tool does not interpret localhost as a host name but rather as a signal to use a Unix socket, so you need to use the corresponding IP address 127.0.0.1 instead. (If the database is running on a different system, use its DNS name or IP address: this is indistinguishable from running the database directly on the host outside of Docker.)
So from the host run:
mysql -h 127.0.0.1 -u root -p
The default port 3306 matches the published ports:, and you'll be prompted to interactively enter the password.

Is there any way to connect docker mysql from host?

I created mysql docker container
docker run -p 13306:3306 -d -e MYSQL_ROOT_PASSWORD="pass" -e MYSQL_DATABASE="db" --name mysql mysql:5.6.46
and I tried to connect to mysql
mysql -u root -p -h localhost -P 13306
but I can't connect to mysql.
ERROR 1045 (28000): Access denied for user 'root'#'localhost' (using password: YES)
I must connect like this for some reason. not use docker exec -i -t mysql bash
you should try and expand your question a bit and add some more information about the errors you receive.
In my local development environment in order to connect to my MySQL database I give it a static ip address. I tend to use docker-compose and not run it from the docker command directly for simplicity. This is what my docker-compose.yaml file looks like for a mariaDB container :
version: '3.7'
services:
maria:
container_name: maria
image: mariadb:10.4
restart: always
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_USER=user
- MYSQL_PASSWORD=user_password
volumes:
- ./maria:/var/lib/mysql
networks:
static:
ipv4_address: 172.30.0.10
networks:
static:
ipam:
driver: default
config:
- subnet: 172.30.0.0/16
After running the docker-compose up command I can now connect to the mysql shell with the command
mysql -uuser -puser_password -h 172.30.0.10
if you are running linux you can also add a line to your /etc/hosts file like :
172.30.0.10 mysql
you can then connect with the command
mysql -uuser -puser_password -h mysql
I'm pretty confident you can get the same results with a pure docker command but it just seems easier with docker-compose. Anyway I hope ths helps

Running mysqldump for daily backup from a separate Docker container

Is it a bad idea to create a separate docker container to run mysqldump using a cron job for daily backups?
Most people are using either the host machine's cron job or a separate cron container to run mysqldump from inside the container which is being backed up.
I would find it nicer to install mysql and execute mysqldump in the containder dedicated for backups. It would make the entire setup more segregated.
Are there any disadvantages or this approach?
Example of such a docker-compose-yml:
mysql:
image: mysql:latest
environment:
MYSQL_DATABASE: mydb
MYSQL_USER: myuser
MYSQL_PASSWORD: mypassword
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- ./mysql/mysql-data:/var/lib/mysql
mysql-cron:
image: mysql:latest
build: .
environment:
MYSQL_HOST: mysql
MYSQL_DATABASE: mydb
MYSQL_USER: myuser
MYSQL_PASSWORD: mypassword
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- ./backup:/var/backup
The Dockerfile for mysql-cron would install 'cron' and setup crontab (not ready yet).
Referring to the official mysql image's documentation you can docker exec into the running container to dump the database to a path on the host: docker exec some-mysql sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /some/path/on/your/host/all-databases.sql
Assuming that you're using docker on Linux, chances are that you already have cron installed (you don't need to build and maintain your own image with cron).
You can add a cron job on the host where docker is running to exec into the container periodically and dump the database(s) (crontab -e) i.e. every day at 01:00 A.M.: 0 1 * * * docker exec some-mysql sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /some/path/on/your/host/all-databases.sql
Note: cron runs with a specific environment (e.g. ensure docker is in the $PATH available to cron, etc).

Unable to connect to Mysql hosted on Docker on Windows machine

I already executed mentioned here: Unable to connect to MYSQL from Docker Instance, but this time I'm running docker on windows machine.
pc#DESKTOP-NQ639DU MINGW64 /c/Program Files/Docker Toolbox
$ docker pull mysql/mysql-server
Using default tag: latest
latest: Pulling from mysql/mysql-server
e64f6e679e1a: Pull complete
799d60100a25: Pull complete
85ce9d0534d0: Pull complete
d3565df0a804: Pull complete
Digest: sha256:59a5854dca16488305aee60c8dea4d88b68d816aee627de022b19d9bead48d04
Status: Downloaded newer image for mysql/mysql-server:latest
pc#DESKTOP-NQ639DU MINGW64 /c/Program Files/Docker Toolbox
$ docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -d mysql/mysql-server:latest
79ff1c03452ab2eac0d798b576ffeabde24d4c5aa6954d3d5c5bef99dcc40ce8
pc#DESKTOP-NQ639DU MINGW64 /c/Program Files/Docker Toolbox
$ mysql -uroot -ppassword
bash: mysql: command not found
pc#DESKTOP-NQ639DU MINGW64 /c/Program Files/Docker Toolbox
$ docker exec -it mysql bash
bash-4.2# mysql -uroot -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
bash-4.2# mysql -uroot -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
bash-4.2#
You should try to connect through the loopback interface, as you don't have access to the socket.
mysql -h 127.0.0.1 -uroot -p
In this case, it's like if your server is running on another machine, this only thing share with your host machine is the exposed port.
If you download the MySQL client from https://dev.mysql.com/downloads/windows/ then you'll be able to access the Docker-hosted MySQL in the same way you'd access any other MySQL database (of note without needing to get a root shell in the database container). Since you're using Docker Toolbox you'd probably use 192.168.99.100 as the IP address of the database server.
Try adding below in docker-compose.y\ml
services:
db:
image: mysql:5.7
environment:
MYSQL_DATABASE: 'Dbname'
# So you don't have to use root, but you can if you like
MYSQL_USER: 'username'
# You can use whatever password you like
MYSQL_PASSWORD: 'Password'
# Password for root access
MYSQL_ROOT_PASSWORD: 'RootPassword'
ports:
# <Port exposed> : < MySQL Port running inside container>
- '3307:3306'
expose:
# Opens port 3306 on the container
- '3306'
# Where our data will be persisted
volumes:
- my-db:/var/lib/mysql
volumes:
my-db:

Import data.sql MySQL Docker Container

If I have a data.sql, how I can import database to my mysql docker container? How I can import database data. In a dockerised world this adds a layer of complexity. some methods please.
Here my docker-compose.yml:
nginx:
build: ./nginx/
container_name: nginx-container
ports:
- 80:80
links:
- php
volumes_from:
- app-data
php:
build: ./php/
container_name: php-container
expose:
- 9000
links:
- mysql
volumes_from:
- app-data
app-data:
image: php:7.0-fpm
container_name: app-data-container
volumes:
- ./www/html/:/var/www/html/
command: "true"
mysql:
image: mysql:latest
container_name: mysql-container
ports:
- 3306:3306
volumes_from:
- mysql-data
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: name_db
MYSQL_USER: user
MYSQL_PASSWORD: password
mysql-data:
image: mysql:latest
container_name: mysql-data-container
volumes:
- /var/lib/mysql
command: "true"
You can import database afterwards:
docker exec -i mysql-container mysql -uuser -ppassword name_db < data.sql
Mount your sql-dump under/docker-entrypoint-initdb.d/yourdump.sql utilizing a volume mount
mysql:
image: mysql:latest
container_name: mysql-container
ports:
- 3306:3306
volumes:
- ./dump.sql:/docker-entrypoint-initdb.d/dump.sql
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: name_db
MYSQL_USER: user
MYSQL_PASSWORD: password
This will trigger an import of the sql-dump during the start of the container, see
https://hub.docker.com/_/mysql/ under "Initializing a fresh instance"
I can't seem to make this work with the latest mysql or mysql:5.7. So I use mariaDB instead. Here is my docker-compose.yaml code.
version: '3'
services:
mysql:
image: mariadb:10.3
container_name: mariadb
volumes:
- container-volume:/var/lib/mysql
- ./dump.sql:/docker-entrypoint-initdb.d/dump.sql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: name_db
ports:
- "3306:3306"
volumes:
container-volume:
Another option if you don't wanna mount a volume, but wanna dump a file from your local machine, is to pipe cat yourdump.sql. Like so:
cat dump.sql | docker exec -i mysql-container mysql -uuser -ppassword db_name
See:
https://gist.github.com/spalladino/6d981f7b33f6e0afe6bb
Just write docker ps and get the container id and then write the following;
docker exec -i your_container_id mysql -u root -p123456 your_db_name < /Users/your_pc/your_project_folder/backup.sql
Import using docker-compose
cat dump.sql | docker-compose exec -T <mysql_container> mysql -u <db-username> -p<db-password> <db-name>
combine https://stackoverflow.com/a/51837876/1078784
and answers in this question, I think the best answer is:
cat {SQL FILE NAME} | docker exec -i {MYSQL CONTAINER NAME} {MYSQL PATH IN CONTAINER} --init-command="SET autocommit=0;"
for example in my system this command should look like:
cat temp.sql | docker exec -i mysql.master /bin/mysql --init-command="SET autocommit=0;"
also you can use pv to moniter progress:
cat temp.sql | pv | docker exec -i mysql.master /bin/mysql --init-command="SET autocommit=0;"
And the most important thing here is "--init-command" which will speed up the import progress 10 times fast.
I can import with this command
docker-compose exec -T mysql mysql -uroot -proot mydatabase < ~/Desktop/mydatabase_2019-10-05.sql
you can follow these simple steps:
FIRST WAY :
first copy the SQL dump file from your local directory to the mysql container. use docker cp command
docker cp [SRC-Local path to sql file] [container-name or container-id]:[DEST-path to copy to]
docker cp ./data.sql mysql-container:/home
and then execute the mysql-container using (NOTE: in case you are using alpine version you need to replace bash with sh in the given below command.)
docker exec -it -u root mysql-container bash
and then you can simply import this SQL dump file.
mysql [DB_NAME] < [SQL dump file path]
mysql movie_db < /home/data.sql
SECOND WAY : SIMPLE
docker cp ./data.sql mysql-container:/docker-entrypoint-initdb.d/
As mentioned in the mysql Docker hub official page.
Whenever a container starts for the first time, a new database is created with the specified name in MYSQL_DATABASE variable - which you can pass by setting up the environment variable see here how to set environment variables
By default container will execute files with extensions .sh, .sql and .sql.gz that are found in /docker-entrypoint-initdb.d folder. Files will be executed in alphabetical order. this way your SQL files will be imported by default to the database specified by the MYSQL_DATABASE variable.
for more details you can always visit the official page
do docker cp file.sql <CONTAINER NAME>:/file.sql first
then docker exec -it <CONTAINER NAME> mysql -u user -p
then inside mysql container execute source \file.sql
Trying "docker exec ... < data.sql" in Window PowerShell responses with:
The '<' operator is reserved for future use.
But one can wrap it out with cmd /c to eliminate the issue:
cmd /c "docker exec -i mysql-container mysql -uuser -ppassword name_db < data.sql"
This one work for me
$ docker exec -i NAME_CONTAINER_MYSQL mysql -u DB_USER -pPASSWORD DATABASE < /path/to/your/file.sql
First if do you want to know what is the NAME_CONTAINER_MYSQL, you should use
this command below :
$ docker ps
In the output column NAME you will see the NAME_CONTAINER_MYSQL that do you need to replace in the command above.
You can run a container setting a shared directory (-v volume), and then run bash in that container. After this, you can interactively use mysql-client to execute the .sql file, from inside the container. obs: /my-host-dir/shared-dir is the .sql location in the host system.
docker run --detach --name=test-mysql -p host-port:container-port --env="MYSQL_ROOT_PASSWORD=my-root-pswd" -v /my-host-dir/shared-dir:/container-dir mysql:latest
docker exec -it test-mysql bash
Inside the container...
mysql -p < /container-dir/file.sql
Custom parameters:
test-mysql (container name)
host-port and container-port
my-root-pswd (mysql root password)
/my-host-dir/shared-dir and /container-dir (the host directory that will be mounted in the container, and the container location of the shared directory)
you can copy the export file for e.g dump.sql using docker cp into the container and then import the db. if you need full instructions, let me know and I will provide