Bash script for creating default user in docker MySQL - mysql

I am developing a "one file script" for run MySQL database inside Docker and many useful thinks. The script should create a container with MySQL and after that create a new user with maximum privileges.
The problem occurs when I try to connect to MySQL command line from the bash script. Part of the script:
#!/bin/bash
mysqlContainerName=project-mysql
mysqlRootUsername=root
mysqlRootPassword=root_pass
mysqlUsername=db_user
mysqlPassword=db_pass
mysqlDb=project_db
echo -e "Creating container \e[31m$mysqlContainerName\e[0m"
docker run --rm -d \
--name=$mysqlContainerName \
--network api-network \
-p 3306:3306 \
-v /opt/docker-data/mysql-volumes:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=$mysqlRootPassword \
-e MYSQL_DATABASE=$mysqlDb \
-t mysql:8.0.19
docker exec $mysqlContainerName \
mysql -h 127.0.0.1 -P 3306 --protocol=tcp \
-uroot -p$mysqlRootPassword -e "CREATE USER '$mysqlUsername'#'localhost' IDENTIFIED BY
'$mysqlPassword';"
So, container successfully created, but all the time I get an error message: ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1' (111)
Any suggestions?

So, after a few hours of searching, I found a solution.
Added bash -c parameter and in quotes connection to MySQL and query.
docker exec $mysqlContainerName bash -c "mysql -h172.21.0.1 -P 3306 --protocol=tcp -u$mysqlRootUsername -p$mysqlRootPassword -e \"CREATE USER '$mysqlUsername'#'localhost' IDENTIFIED BY '$mysqlPassword';\"; exit;"

Related

django.db.utils.OperationalError when running MySQL/MariaDB in Docker: Lost connection to MySQL server at 'reading initial communication packet'

Running MySQL/MariaDB in a Docker container:
docker run -p 3306:3306 --name $(DATABASE_NAME) -v /tmp/mysql:/var/lib/mysql -e MYSQL_DATABASE=$(DATABASE_NAME) -e MYSQL_USER=$(DATABASE_USER) -e MYSQL_ROOT_PASSWORD=$(DATABASE_PASSWORD) -d mariadb:latest > /dev/null
And then running Django version 4 locally with:
manage.py runserver 127.0.0.1:8000
Error
django.db.utils.OperationalError: (2013, "Lost connection to MySQL server at 'reading initial communication packet', system error: 2")
I can successfully connect to the database with MySQL Workbench as well as the command:
mysql -h 127.0.0.1 -P 3306 -u root -p <database>
I am launching Django and the MySQL/MariaDB Docker container from a Makefile.
Makefile
SHELL := /bin/bash
.PHONY: dj-start-local
dj-start-local: start-mysql
PYTHONPATH=. django_project/src/manage.py runserver 127.0.0.1:8000
.PHONY: start-mysql
start-mysql:
docker run -p 3306:3306 --name $(DATABASE_NAME) \
-v /tmp/mysql:/var/lib/mysql \
-e MYSQL_DATABASE=$(DATABASE_NAME) \
-e MYSQL_USER=$(DATABASE_USER) \
-e MYSQL_ROOT_PASSWORD=$(DATABASE_PASSWORD) \
-d mariadb:latest > /dev/null
Use the healthcheck.sh in the container. Use the MARIADB_MYSQL_LOCALHOST_USER=1 to create a mysql#localhost user that the script can use to access the database,
The healthcheck waits until its fully started regardless of the time.
Makefile:
.PHONY: start-mariadb
start-mariadb:
docker run -p 3306:3306 --name $(DATABASE_NAME) \
-e MARIADB_DATABASE=$(DATABASE_NAME) \
-e MARIADB_USER=$(DATABASE_USER) \
-e MARIADB_PASSWORD=$(DATABASE_PASSWORD) \
-e MARIADB_ROOT_PASSWORD=$(DATABASE_PASSWORD) \
-e MARIADB_MYSQL_LOCALHOST_USER=1 \
-v /tmp/mysql:/var/lib/mysql \
-d mariadb:latest
while ! docker exec $(DATABASE_NAME) healthcheck.sh --su=mysql --connect --innodb_initialized; do sleep 1; done
docker exec --user mysql $(DATABASE_NAME) mariadb -e 'select "hello world"'
Test run:
$ make start-mariadb
docker run -p 3306:3306 --name dd \
-e MARIADB_DATABASE=dd \
-e MARIADB_USER=dd \
-e MARIADB_PASSWORD=dd \
-e MARIADB_ROOT_PASSWORD=dd \
-e MARIADB_MYSQL_LOCALHOST_USER=1 \
-d mariadb:latest
53066fffa293ed061743024e387bd7fb6f1c664efd603c7a657ba88e307be308
while ! docker exec dd healthcheck.sh --su=mysql --connect --innodb_initialized; do sleep 1; done
healthcheck connect failed
healthcheck connect failed
healthcheck connect failed
healthcheck connect failed
docker exec --user mysql dd mariadb -e 'select "hello world"'
hello world
hello world
Note: added MARIADB_PASSWORD otherwise the database/user wouldn't be created.
The issue may be due to a race condition, where Django is attempting to connect to the database before it is ready. Try waiting a few seconds after starting the Docker container.
Simple Solution
Makefile
.PHONY: start-mysql
start-mysql:
docker run -p 3306:3306 --name $(DATABASE_NAME) \
-v /tmp/mysql:/var/lib/mysql \
-e MYSQL_DATABASE=$(DATABASE_NAME) \
-e MYSQL_USER=$(DATABASE_USER) \
-e MYSQL_ROOT_PASSWORD=$(DATABASE_PASSWORD) \
-d mariadb:latest
sleep 4
Better Solution using healthcheck.sh
In Dan Black's answer, he pointed out that the MariaDB docker container includes a script healthcheck.sh.
If you only want to check if the MariaDB container can receive connections, then healthcheck.sh can be run without specifying a user (avoiding authorization complications).
The Makefile below will check for a database connection every second until the database is ready.
Makefile (advanced version)
.PHONY: mysql-start
mysql-start: mysql-stop
docker run -p 3306:3306 --name $(DATABASE_NAME) \
-v /tmp/mysql:/var/lib/mysql \
-e MYSQL_DATABASE=$(DATABASE_NAME) \
-e MYSQL_USER=$(DATABASE_USER) \
-e MYSQL_ROOT_PASSWORD=$(DATABASE_PASSWORD) \
-d mariadb:latest
while ! docker exec $(DATABASE_NAME) healthcheck.sh --connect 2> /dev/null; do sleep 1; done

How to create a docker container which every night make a backup of mysql database?

Hello i have created mysql image and with this command
docker run --name db-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:latest --> Run container with my sql
docker pull mysql --> create image with mysql
docker run --name db_mysql-e MYSQL_ROOT_PASSWORD=1234 -e MYSQL_DATABASE=mami -p 3306:3306 -d mysql
i execute it but after that i don't know what to do and how to make a DB in this container and the job for the backup
If someone can help me with step by step what to do
You could use the cron service from your host system to run the following command as described in the documentation for the mysql docker image:
crontab example for running the command every night at 2:00 am:
00 02 * * * /usr/bin/docker exec db-mysql sh -c 'exec mysqldump --all-databases -uroot -p"my-secret-pw"' > /some/path/on/your/host/all-databases.sql
Alternatively you could run another container designed just for this task such as deitch/mysql-backup:
docker run --name db-mysql -d \
-e MYSQL_ROOT_PASSWORD=my-secret-pw \
-e MYSQL_USER=my-user \
-e MYSQL_PASSWORD=my-user-password \
-e MYSQL_DATABASE=my-db \
mysql:latest
docker run -d --restart=always \
--name=db-backup \
-e DB_DUMP_BEGIN=0200 \
-e DB_SERVER=db-mysql \
-e DB_USER=my-user \
-e DB_PASS=my-user-password \
-e DB_NAMES=my-db \
-e DB_DUMP_TARGET=/db \
-v /somewhere/on/your/host/:/db \
databack/mysql-backup
You also need to make sure the /somewhere/on/your/host/ folder is writable by users of group 1005:
sudo chgrp 1005 /somewhere/on/your/host/
sudo chmod g+rwX /somewhere/on/your/host/
But this container must have a mean to connect to your db-mysql container. For that you create a docker network and connect both containers to it:
docker network create mysql-backup-net
docker network connect mysql-backup-net db-backup
docker network connect mysql-backup-net db-mysql

mysqldump in Jenkinsfile can't connect to server

This is the stage in Jenkinsfile where the problem comes from :
stage ('Build & Run container') {
imageMysql = docker.build('backend-server-mysql-dev', '--no-cache -f build/docker/mysql/Dockerfile .')
containerMysql = imageMysql.run("--name backend-server-mysql-dev -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -e MYSQL_ROOT_USER=root -e MYSQL_PASSWORD=mahmoud -e MYSQL_DATABASE=soextremedb")
sh 'docker ps | docker exec -it backend-server-mysql-dev /bin/bash | ls -l | mysqldump -u root -proot soextremedb < soextremedb.sql'
}
This is the error message:
Shell Script -- docker ps | docker exec -it backend-server-mysql-dev /bin/bash | ls -l | mysqldump -u root -proot soextremedb < soextremedb.sql -- (self time 566ms)
[soextremeBackEnd_Dev-MBC6SQWYSNVE6ADN2QOAOGZ4YYVT5E6K7Y2FUP6ROOROWRMCPFOA] Running shell script
+ docker ps
+ docker exec -it backend-server-mysql-dev /bin/bash
+ ls -l
+ mysqldump -u root -proot soextremedb
**mysqldump: Got error: 2002: "Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2 "No such file or directory")" when trying to connect the input device is not a TTY**
I think there are a couple of issues with the sh command.
First, | is used to send the output of one command on to the next command, but it looks like you're just trying to execute a sequence of commands. For that, you can use ; or &&. You might take a look at this answer for a great summary of shell operators.
Then, for your docker exec command, I think you actually want to call a series of commands non-interactively: leave off off the -it and use /bin/bash -c to pass a command string to the shell.
This will give you something like:
sh 'docker ps ; docker exec backend-server-mysql-dev /bin/bash -c "ls -l ; mysqldump -u root -proot soextremedb < soextremedb.sql"'

Set up MySQL using Dockerfile

I'm just getting started with Docker and was able to set up MySQL according to my needs, by running tutum/lamp and doing a bunch of exec. For example:
docker run -d -p 80:80 -p 3306:3306 --name test tutum/lamp
...
docker exec test mysqldump --host somehost --user someuser --password --databases somedatabase > dump.sql
docker exec test mysql -u root < dump.sql
However, I'm having issues converting this to a Dockerfile. Specifically, the following results in ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock':
FROM tutum/lamp
EXPOSE 80 3306
...
RUN mysqldump --host=$DB_IP --user=$DB_USER --password=$DB_PASSWORD --databases somedatabase > dump.sql
RUN mysql -u root < dump.sql
You will need to override run.sh in order to do that, because when you run a container it will install mysql for the first time.
That is why you can not connect to mysql prior to that (in my previous answer I wasn't aware of that).
I've managed to execute mysql command by adding this to Dockerfile
FROM tutum/lamp
ADD . /custom
RUN chmod 755 /custom/run.sh
CMD ["/custom/run.sh"]
Then in the same folder create a file run.sh
#!/bin/bash
VOLUME_HOME="/var/lib/mysql"
sed -ri -e "s/^upload_max_filesize.*/upload_max_filesize = ${PHP_UPLOAD_MAX_FILESIZE}/" \
-e "s/^post_max_size.*/post_max_size = ${PHP_POST_MAX_SIZE}/" /etc/php5/apache2/php.ini
if [[ ! -d $VOLUME_HOME/mysql ]]; then
echo "=> An empty or uninitialized MySQL volume is detected in $VOLUME_HOME"
echo "=> Installing MySQL ..."
mysql_install_db > /dev/null 2>&1
echo "=> Done!"
/create_mysql_admin_user.sh
else
echo "=> Using an existing volume of MySQL"
fi
( sleep 20 ; mysql -u root < /custom/dump.sql ; echo "*** IMPORT ***" ) &
exec supervisord -n
This file is the same as /run.sh with one line added to run sql import after 20 seconds to make sure mysql service is up and running (there must be more elegant way to run a command just after mysql is started, of course).

Docker MariaDB/Mysql dump

How can i mysqldump from running container on https://hub.docker.com/_/mariadb/ ?
I cant find any useful documentation or data?
Any method for backup and restore database.
This is my my continaer run command :
docker run --name myaapp-mariadb -v /databases/maria:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=password -d mariadb:10
If we assume you created the mariadb server container this way:
docker run --name some-mariadb -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mariadb:latest
Then you access it from another client container:
docker run -it --link some-mariadb:mysql \
--rm mariadb:latest \
sh -c 'exec mysqldump -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD" database_name' > database_name_dump.sql
There's lots more helpful usage tip in the mysql official image page.
Accepted answer stands accepted & correct in all its sense. Adding, this for the case where we have mapped the database to an external volume.
So, for example if the container was created using below command
docker run --name mysqldb -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -v /dir_path_on_your_machine/mysql-data:/var/lib/mysql -d mariadb:latest
then, we can execute the below command from cmd line or terminal
docker exec mysqldb mysqldump --user=root --password=password dbname > /dir_path_on_your_machine/mysql-data/dump/db.sql
However, the dump created using above commands will not dump stored procedures, functions and events. We would need extra params with the in order to do that
--triggers Dump triggers for each dumped table.
--routines Dump stored routines (functions and procedures).
--events Dump events.
So, we can modify our command to include the above params for desired result.
Sample update command
docker exec mysqldb mysqldump --routines --triggers --user=root --password=password dbname > /dir_path_on_your_machine/mysql-data/dump/db1.sql
In case, you encounter any import related error ,, check if this helps.