Reputation: 1045
I am learning with docker containers and I'd like to pass .sql file to database using docker exec. How can I do that? I am searching for about an hour now and found this:
cat file.sql | docker exec -it mariadb sh -c 'mysql -u<user> -p<pass>'
or this
docker exec -it mariadb sh -c 'mysql -u<user> -p<pass> "$(< /path/file.sql)"'
but neither of it worked. I think there is problem that I am passing it into sh -c and it tries to load that file from inside the container. How can I do it?
Upvotes: 18
Views: 13038
Reputation: 16304
there's more than one way to do it, of course; most of your invocations are close, but if you execute docker with -t
it will allocate a terminal for i/o and that will interfere with stream opearations.
My recent invocation from shell history was :
docker exec -i mysql mysql -t < t.sql
in my case of course mysql
is the running container name. You'll note that I do not pass -t
to the docker exec
- I do however pass it to mysql
command line program that I exec on the docker host, so don't get confused there.
The shell that interprets that command and executes docker is also the one that opens t.sql
and redirects that file descriptor to docker
's stdin, so t.sql
here is in the current working directory of the host shell, not the container shell.
That having been said, here's why yours didn't work. In the first place, as I said, the use of exec -it
allocates a terminal that interferes with the stdin stream that the bash shell set up from cat
. In the second place, you're really close, but path/file.sql wasn't on the docker image so I'm guessing that threw a 'no such file or directory' because file.sql
is on the host, not the container, yet it's referenced within the -c
parameter to the container's sh
execution. Of course, that would also need -t
to be removed; in neither case does a terminal need to be allocated (you already have one, and it will already be the stdout for the docker execution as it will inherit the shell's un-redirected stdout).
Upvotes: 28