1

A mariadb/mysql docker container is running. I want to restore a sql dump from the host.

docker exec -i container_name \
  /bin/sh -c 'exec mysql -uroot -psecret' \
  < gunzip -c backup.sql.gz

The backup file exists. But I get this error:

-bash: gunzip: No such file or directory

1

2 Answers 2

1

I will not recommend restoring using docker exec command, the best way to put dump file in docker-image if it is small, or mount the dump file to /docker-entrypoint-initdb.d.

So add this to your Dockerfile and you will need to run these command once the container is up,

FROM mariadb
COPY backup.sql.gz /docker-entrypoint-initdb.d

So when you start the container it will automatically populated.

Second thing, you can also use host bind volume.

docker run -v $PWD/backup.sql.gz:/docker-entrypoint-initdb.d/ -it mariadb

Initializing a fresh instance

When a container is started for the first time, a new database with the specified name will be created and initialized with the provided configuration variables. Furthermore, it will execute files with extensions .sh, .sql and .sql.gz that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. You can easily populate your mariadb services by mounting a SQL dump into that directory and provide custom images with contributed data. SQL files will be imported by default to the database specified by the MYSQL_DATABASE variable.

mariadb-dockerhub

3
  • Thanks - that is a good approach. But why are you against using docker exec? The official docs recommend it. Curious to know your thoughts?
    – lonix
    Commented Oct 29, 2019 at 13:04
  • 1
    what if you share the DB docker image with your team and you have twenty members, do you think they will like to run this command every time? and what if remove the container you lost everything and again you will run the same command every time when your container up. it will save your and team time.
    – Adiii
    Commented Oct 29, 2019 at 13:14
  • Oh okay, good points. But sometimes it's just nice to make a quick backup before making some changes, and reloading the backup while the db is still running. I guess it depends on what you are trying to do.
    – lonix
    Commented Oct 29, 2019 at 13:17
0

Your local shell gets first pass at reading this command. It sees the redirection < gunzip, and tries to open a local file named gunzip in the current directory and use that as the docker exec command’s standard input. When that file doesn’t exist, you get the error you see.

You’re looking for a shell pipeline, not a redirection

gunzip -c backup.sql.gz \
  | mysql -h127.0.0.1 -uroot -psecret

This requires the MySQL command-line tools to be installed on your host, but it is the same way you would deal with any not-specifically-local MySQL installation.

If you really wanted to do it via docker exec the same basic layout applies

gunzip -c backup.sql.gz \
  | sudo docker exec container_name \
    mysql -uroot -psecret
4
  • In the last example you give, why do you skip the sh -c 'mysql ...' format that I typically see?
    – lonix
    Commented Oct 29, 2019 at 13:07
  • 1
    You’re not doing anything in the actual command that needs a shell (environment variable expansions, redirections, ...) so it’s unnecessary.
    – David Maze
    Commented Oct 29, 2019 at 13:29
  • Thanks again. When you give as the last option "if you really want to do it via docker exec ..." does that mean you feel that is a poor approach? Or am I looking for nuance that isn't there? :)
    – lonix
    Commented Oct 29, 2019 at 13:38
  • For ordinary network clients in a development environment, my general experience has been that it’s much easier to just install the tools you need locally and use them.
    – David Maze
    Commented Oct 29, 2019 at 15:21

Not the answer you're looking for? Browse other questions tagged or ask your own question.