Reputation: 11670
I'm setting up a Dockerfile where I can run my automated tests, and I'm having troubles with connecting to mysql database.
The Dockerfile depends on a prevoously built image and looks like this:
# Stage 0, assign argument as multistage image alias
ARG PHP_IMAGE
FROM ${PHP_IMAGE} as image
# Stage 1, start tests
FROM php:7.2-fpm
RUN curl -sS https://getcomposer.org/installer | php \
&& chmod +x composer.phar && mv composer.phar /usr/local/bin/composer
RUN apt-get update && apt-get install -y gnupg
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - && \
apt-get install -yq nodejs build-essential \
git unzip \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng-dev \
subversion \
&& curl -sL https://deb.nodesource.com/setup_8.x | bash - \
&& pecl install mcrypt-1.0.1 \
&& docker-php-ext-enable mcrypt \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd \
&& docker-php-ext-install -j$(nproc) mysqli
RUN apt-get install -y mysql-server
RUN /etc/init.d/mysql start
RUN mysqladmin -u root -p status
RUN yes | pecl install xdebug \
&& echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.remote_enable=on" >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.remote_autostart=off" >> /usr/local/etc/php/conf.d/xdebug.ini
RUN npm install -g npm
COPY --from=image /var/www/html/ /var/www/html/
WORKDIR /var/www/html/
COPY scripts/develop.sh develop.sh
COPY scripts/docker-test.sh docker-test.sh
RUN ["/bin/bash", "-c", "bash develop.sh && bash docker-test.sh"]
I've added RUN mysqladmin -u root -p status
to try to debug why connecting to mysql failed and I got
Enter password: mysqladmin: connect to server at 'localhost' failed error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2 "No such file or directory")' Check that mysqld is running and that the socket: '/var/run/mysqld/mysqld.sock' exists!
To run this I am running
docker build -t $TEST_DOCKER_NAME --build-arg PHP_IMAGE=$DOCKER_IMAGE_NAME_PHP -f Dockerfile.test .
The TEST_DOCKER_NAME
and DOCKER_IMAGE_NAME_PHP
are stored in an env file and read from there. The PHP image was built successfuly and I'm using it to copy the files from there to here so that I can run PHPUnit.
When I remove that RUN
line my build fails when I'm trying to run a script that creates the database
mysqladmin: connect to server at 'localhost' failed error: 'Can't connect to MySQL server on 'localhost' (99 "Cannot assign requested address")' Check that mysqld is running on localhost and that the port is 3306. You can check this by doing 'telnet localhost 3306'
What do I need to do in my Dockerfile to make it work?
Upvotes: 1
Views: 2532
Reputation: 3773
This is a common mistake people make when using docker. When you use the RUN
directive in docker you are running a command through to completion, capturing the filesystem changes and then exiting.
So when you have the lines
RUN /etc/init.d/mysql start
RUN mysqladmin -u root -p status
The first one is starting mysql. But then the changes are captured, the container is exited and then a new one is started to run the mysqladmin
command. Therefore the mysql process is no longer running.
To avoid this you could combine them into a single line like
RUN /etc/init.d/mysql start && mysqladmin -u root -p status
However you will need to do this every time you want to use mysql. Such as in your develop.sh
.
It is not recommended to run multiple processes within your container and it is also not recommended to use init.d
or other system startup frameworks within your container.
You seem to be treating your container like a virtual machine and are having issues because containers are not VMs.
I recommend you explore running mysql in a separate container and then using a tool like docker-compose to start and and stop your containers.
Upvotes: 3