`docker exec -i db_mysql mysqldump` doesn't produce any backup - mysql

I have a MySQL Docker container (db_mysql) with database wp_almond
When I try to dump it with docker exec -i db_mysql mysqldump it doesn't work
$ docker exec -i db_mysql mysqldump -u root -p wp_almond > wp_almond.sql
$ docker exec -i db_mysql ls # Notice that "wp_almond.sql" was not created
bin
boot
dev
docker-entrypoint-initdb.d
entrypoint.sh
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
But entering the container and then doing the mysqldump inside works
$ docker exec -it db_mysql sh
$ mysqldump -u root -p wp_almond > wp_almond.sql
$ ls # Here "wp_almond.sql" is present
bin
boot
dev
docker-entrypoint-initdb.d
entrypoint.sh
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
wp_almond.sql
I don't know why, I need to do it without entering the container with sh for a backup script

When you run
docker exec -i db_mysql mysqldump -u root -p wp_almond
then the output is produced to stdout (of your host terminal)
Therefore, when you run
docker exec -i db_mysql mysqldump -u root -p wp_almond > wp_almond.sql
It simply redirects the output of your terminal to file on your host itself.
If you want to save it in the container, try this instead
docker exec -i db_mysql sh -c "mysqldump -u root -p wp_almond > wp_almond.sql"

Related

mysql command not found in docker bash shell script

I have a shell script that copies a .sql script to a docker container and executes it.
When I execute the line:
docker exec -it $existingMySQLContainer bash -c '"mysql -u root -proot < setup_db.sql"'
on my host machine outside of the script, it works. But when I execute it from within the script, I get:
bash: mysql -u root -proot < setup_db.sql: command not found
Why doesn't this work within the script?
Script:
#!/bin/sh
# check to see if the container with the name exists.
existingMySQLContainer=$(docker ps -a -q -f name="local-test-mysql-db")
if [ ! -z "$existingMySQLContainer" ]
then
# conatiner has been found so tear it down for a clean database
echo "Found existing local test db " $existingMySQLContainer
docker rm -f $existingMySQLContainer
fi
docker run --name local-test-mysql-db -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=root mysql:8
# run the docker container
existingMySQLContainer=$(docker ps -a -q -f name="local-test-mysql-db")
docker cp setup_db.sql $existingMySQLContainer:/setup_db.sql
docker exec -it $existingMySQLContainer bash -c '"mysql -u root -proot < setup_db.sql"'
I tried arranging the double quotes in various ways and no success.
Removing the doubles quotes to give just
Removing doubles quotes so the last line is:
ocker exec -it $existingMySQLContainer bash -c '"mysql -u root -proot < setup_db.sql"'
gives:
bash: mysql -u root -proot < setup_db.sql: command not found
SOLUTION
Docker MySQL just hadn't finished loading yet. I was trying to access it before it had finished loading.

Bash: file not created with '>' command

I'm writing a script to create backups of a MySQL database running in a docker container. The database is correctly up and running.
My current code is
#!/bin/bash
PATH=/usr/bin:/usr/local/bin:/root/.local/bin:$PATH
docker-compose exec -T db mkdir -p /opt/booking-backup
docker_backup_path="/opt/booking-backup/dump_prod_$(date +%F_%R).sql"
copy_backup_path="/root/backup_scripts/booking_prod/dump_prod_$(date +%F_%R).sql"
docker-compose exec db mysqldump --add-drop-database --add-drop-table --user=root --password="pw" booking > "$docker_backup_path"
docker-compose exec db mysqldump --add-drop-database --add-drop-table --user=root --password="pw" booking > "/opt/booking-backup/dump_prod.sql"
[ -d ./backup ] || mkdir ./backup
docker cp $(docker-compose ps -q db):$docker_backup_path $copy_backup_path
However, when I execute it it throws this error:
Error: No such container:path: f0baa241becd20d2690bb901fb257a4bbec8cac17e6f1ce6d50adb9532bbae03:/opt/booking-backup/dump_prod_2019-05-28_14:23.sql
What makes this weirder is that I have the exact same code (but with booking switched out for abc, and with PSQL instead of MySQL) that works correctly.
It appears that this line
docker-compose exec db mysqldump --add-drop-database --add-drop-table --user=root --password="pw" booking > $docker_backup_path
does not create the output file, but when I use tee I can see the contents of the dump and they are correct.
What's going wrong here?
The shell redirections
docker-compose exec db mysqldump ... > "$docker_backup_path"
docker-compose exec db mysqldump ... > "/opt/booking-backup/dump_prod.sql"
# -----------------------------------^ here
... will be expanded by your local shell, not inside the container. Meaning the files are written to your local filesystem not to the container's filesystem.

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"'

How to import an existing MySQL-Database in my MySQL-Docker Container?

I have created a docker container based on the official image of MySQL from Docker Hub. It works fine, but I have some troubles with the database import.
My file with the SQL-Instructions is already stored in the folder /docker-entrypoint-initdb.d of my container, but it doesn't work! I have copied my sql-import.sql to /var/lib/docker/volumes/mysql-dump/_data, but I can only see the name of my database when I call "SHOW DATABASES;" within my container. There is no table available when I call "SHOW TABLES FROM myDB;". What can I do to import the content of my MySQL Database?
Here is my Dockerfile:
FROM mysql:5.7
ADD ./init-scripts/*.sql /docker-entrypoint-initdb.d/
ADD ./config/my.cnf /root/
RUN cd /root/ && \
chmod 0600 my.cnf && \
mv my.cnf .my.cnf
ENV MYSQL_DATABASE=regex
ENV MYSQL_ROOT_PASSWORD=mypassword
EXPOSE 3306
There are several methods to import. With docker exec if your contener is running:
Solution 1:
docker exec -i <id_conteneur> /usr/bin/mysql -u <fooUser> -e "CREATE DATABASE mydb"
cat schema.sql | docker exec -i <id_conteneur> /usr/bin/mysql -u <fooUser> --password=<password> <database>
Solution 2:
In a bash script:
#!/bin/bash
/usr/bin/mysqld_safe --skip-grant-tables &
mysql -u <fooUser> -e "CREATE DATABASE mydb"
mysql -u <fooUser> mydb < schema.sql
And add to your DockerFile with Run command:
ADD create_db.sh /tmp/create_db.sh
RUN /tmp/create_db.sh

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).