1

So I'm making a dockerfile and I want it to set up a project and import a database after that. I'm using XAMPP and the included MariaDB. I know I need to use CMD for the import since XAMPP must be running. I'm trying to import the DB by running a sql script that does the job in the DB prompt.

I tried using && and ; for chaining commands in a single line but it won't work since it tries to run all commands on the terminal prompt before waiting on MariaDB prompt. Any Ideas?

This is my docker file and last line is my attempt to import the database:

FROM cswl/xampp

COPY . /opt/lampp/htdocs/

WORKDIR /opt/lampp/htdocs/

RUN curl -sS https://getcomposer.org/installer | /opt/lampp/bin/php &&\
  /opt/lampp/bin/php composer.phar install

RUN curl https://s3.amazonaws.com/careers-picpay/lista_relevancia_1.txt --output db/lista_relevancia_1.txt &&\
  curl http://s3.amazonaws.com/careers-picpay/lista_relevancia_2.txt --output db/lista_relevancia_2.txt &&\
  curl https://s3.amazonaws.com/careers-picpay/users.csv.gz --output db/users.csv.gz

RUN gzip -d db/users.csv.gz

CMD /opt/lampp/bin/mysql -u root && source ./initdb.sql

UPDATE: So I also tried to replace my two commands with one with the MariaDB -e option, for executing a line after login... Didn't work, database wasn't created and I don't know why. This is the command:

CMD /opt/lampp/bin/mysql -u root -e "source ./initdb.sql"
1
  • Commonly you would run the database in one container and the application that uses it (XAMPP) in another. It's considered not good practice and it's problematic to run multiple processes in a single container. In my experience, it's also challenging to coordinate database initialization in containers. I suspect your CMD is starting the mysql process and getting no further. Commented Jun 28, 2019 at 4:05

2 Answers 2

1

Edited

With the MariaDB official image one should just copy the init script (initdb.sql) in the directory /docker-entrypoint-initdb.d. See MariaDB Docker Quick Reference. Files in that directory are executed in alphabetical order when the container is created and initialized.

With the XAMPP image, it seems that you have to do it manually. This is definitely not an elegant solution but it should work.

Replace the ENTRYPOINT script of the image with this one:

#!/bin/bash

/opt/lampp/lampp start

# wait for mysql to be ready
while ! /opt/lampp/bin//mysql --protocol TCP  -e "show databases;"; do sleep 2; done

# initialize the database
/opt/lampp/bin/mysql -u root -e "source /init.sql"

## Run tail so we don't exit
/usr/bin/tail -f /opt/lampp/logs/php_error_log

This will wait for mysql to be ready before executing the source command.

Add to the Dockerfile the following to copy the initialization sql script and override the ENTRYPOINT:

FROM cswl/xampp
...

COPY init.sql /init.sql

COPY init.sh /init.sh
RUN chmod +x /init.sh

ENTRYPOINT  ["/init.sh"]
Sign up to request clarification or add additional context in comments.

2 Comments

This works only for MariaDB official image. As you can see in my Dockerfile, I'm using a non-official XAMPP image.
I somehow missed that. That wasn't a really useful answer and I edited it.
1

you may use wait-for-it.sh to check if DB is up by adding it to CMD:

CMD ["path/to/wait-for-it.sh", "localhost:3306", "-t", "6000", "--", "YOUR ACTUAL COMMAND"]

you may at first copy the script to your container.

here is more info

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.