0

I'm trying to get a docker container with a mysql database up and running. I have some additional requirements. There are some properties in the my.cnf, that need to be changed and there are sql files containing data, which should be executed, so that the docker container after startup has all the data available.

This should be done during build of the image, so the container is quickly ready after starting and doesn't have to insert all the data first (it is quite an amount).

So my plan is, to make a dockerfile from mysql-server and RUN the sql scripts. But I can't connect to mysql during build, I get the error

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

Here is the dockerfile

FROM mysql/mysql-server:8.0

ENV MYSQL_ROOT_PASSWORD=root1234

COPY ./config/my.cnf /etc/my.cnf
COPY ./sqlfiles /mnt/sqlfiles

RUN cp -R /mnt/sqlfiles /tmp/sqlfiles
RUN sh -c "cd /tmp/sqlfiles/; gunzip *.gz"
RUN sh -c "cat /tmp/sqlfiles/*.sql | mysql -uroot -proot1234"

And here the complete console output

> docker build -t mysql-test .
[+] Building 0.5s (10/10) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                             0.0s 
 => => transferring dockerfile: 32B                                                                                                                              0.0s 
 => [internal] load .dockerignore                                                                                                                                0.0s 
 => => transferring context: 2B                                                                                                                                  0.0s 
 => [internal] load metadata for docker.io/mysql/mysql-server:8.0                                                                                                0.0s 
 => [1/6] FROM docker.io/mysql/mysql-server:8.0                                                                                                                  0.0s 
 => [internal] load build context                                                                                                                                0.0s 
 => => transferring context: 321B                                                                                                                                0.0s 
 => CACHED [2/6] COPY ./config/my.cnf /etc/my.cnf                                                                                                                0.0s 
 => CACHED [3/6] COPY ./sqlfiles /mnt/sqlfiles                                                                                                                   0.0s 
 => CACHED [4/6] RUN cp -R /mnt/sqlfiles /tmp/sqlfiles                                                                                                           0.0s 
 => CACHED [5/6] RUN sh -c "cd /tmp/sqlfiles/; gunzip *.gz"                                                                                                      0.0s 
 => ERROR [6/6] RUN sh -c "cat /tmp/sqlfiles/*.sql | mysql -uroot -proot1234"                                                                                    0.3s 
------
 > [6/6] RUN sh -c "cat /tmp/sqlfiles/*.sql | mysql -uroot -proot1234":
#10 0.299 mysql: [Warning] Using a password on the command line interface can be insecure.
#10 0.303 ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
------
executor failed running [/bin/sh -c sh -c "cat /tmp/sqlfiles/*.sql | mysql -uroot -proot1234"]: exit code: 1

I have also tried to make it after build with the CMD command, but I get the same message after running docker run. But if I omit this step, and execute it manually after startup via docker exec, it works just fine and dandy. I tried to do my research, but noone seems to even try to do something like that.

Modi57
  • 205
  • 1
  • 10
  • Putting the database dump in `/docker-entrypoint-initdb.d` and loading it on first startup is the standard approach here. You can't do it in the Dockerfile because the database isn't running yet, and also because the database data is in a volume and that is never persisted in an image. The linked questions have more details and workarounds. – David Maze Apr 28 '21 at 11:40

1 Answers1

1

The entrypoint/run command is not executed before the build starts. The Dockerfile defines how the environment should look like when the container is started (after build). During build-time, there is just the environment, not the server process.

Side-note: Im not sure of the way how you want to provision your db is considered best-practice. Maybe its worth thinking about mounting a volume with the prepared DB state into the container instead.

Edit: what should work is to first launch the container, and when its up & running, execute the required command via docker exec (note: exec is important here, run would launch a new container and override the CMD instruction, so there wont be a running server process in the container again)

leberknecht
  • 1,526
  • 15
  • 27
  • Ah, okay, so basically, what I'm trying to achieve is impossible? Another approach of mine was to write a script, which starts the container, does above mentioned stuff and then use the docker image command to make an image of that container, which then can be distributed and used. Is that at least a little closer to best-practice? – Modi57 Apr 28 '21 at 11:37