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.
Related
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"
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
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"'
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 exec is not working for me. If I connect to a running container with docker exec -it mymachine bash and run sh -c 'mysql -u root < /tmp/schema.sql', it works.
If I just run docker exec mymachine sh -c 'mysql -u root < /tmp/schema.sql', it doesn't give any errors, but it doesn't do anything. Nor does it give me any errors if I run docker exec mymachine sh -c 'mysql -u root < /tmp/i_dont_exist.sql'.
How do I fix this?
try this -
docker exec mymachine "sh -c 'mysql -u root < /tmp/schema.sql'"
If not then the '<' operator will be picked up by the shell in the host machine and not the container.
I suspect that the < operator is trying to grab from your host rather than your container. Try enclosing the entire command in quotations.