Я устанавливаю Dockerfile, где я могу запускать свои автоматические тесты, и у меня возникают проблемы с подключением к базе данных MySQL.
Dockerfile зависит от предварительно созданного образа и выглядит так:
# 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"]
Я добавил RUN mysqladmin -u root -p status
чтобы попытаться отладить, почему не удалось подключиться к mysql, и я получил
Введите пароль: mysqladmin: ошибка подключения к серверу на локальном хосте: ошибка: "Не удается подключиться к локальному серверу MySQL через сокет"/var/run/mysqld/mysqld.sock(2 "Нет такого файла или каталога") этот mysqld работает и что сокет: '/var/run/mysqld/mysqld.sock' существует!
Чтобы запустить это я бегу
docker build -t $TEST_DOCKER_NAME --build-arg PHP_IMAGE=$DOCKER_IMAGE_NAME_PHP -f Dockerfile.test .
TEST_DOCKER_NAME
и DOCKER_IMAGE_NAME_PHP
хранятся в файле env и читаются оттуда. Образ PHP был успешно создан, и я использую его для копирования файлов отсюда сюда, чтобы я мог запустить PHPUnit.
Когда я удаляю эту строку RUN
моя сборка завершается неудачно, когда я пытаюсь запустить скрипт, который создает базу данных
mysqladmin: ошибка подключения к серверу на локальном хосте: ошибка: "Не удается подключиться к серверу MySQL на локальном хосте" (99 "Невозможно назначить запрошенный адрес") "Убедитесь, что mysqld работает на локальном хосте и что порт 3306. Вы можете проверьте это с помощью команды telnet localhost 3306
Что мне нужно сделать в моем Dockerfile, чтобы он работал?
Это распространенная ошибка, которую люди допускают при использовании докера. Когда вы используете директиву RUN
в Docker, вы выполняете команду до конца, фиксируете изменения файловой системы и затем завершаете работу.
Поэтому, когда у вас есть строки
RUN /etc/init.d/mysql start
RUN mysqladmin -u root -p status
Первый запускает MySQL. Но затем изменения фиксируются, контейнер закрывается, а затем запускается новый для запуска команды mysqladmin
. Поэтому процесс mysql больше не работает.
Чтобы избежать этого, вы можете объединить их в одну строку, как
RUN /etc/init.d/mysql start && mysqladmin -u root -p status
Однако вам нужно будет делать это каждый раз, когда вы захотите использовать mysql. Такие, как в вашем develop.sh
.
Не рекомендуется запускать несколько процессов в вашем контейнере, а также не рекомендуется использовать init.d
или другие среды запуска системы в вашем контейнере.
Похоже, вы рассматриваете свой контейнер как виртуальную машину, и у вас возникают проблемы, потому что контейнеры не являются виртуальными машинами.
Я рекомендую вам изучить запуск mysql в отдельном контейнере, а затем использовать инструмент типа docker-compose для запуска и остановки ваших контейнеров.
status
- пароль, правильный синтаксис должен бытьmysqladmin -u root -pstatus
mysqladmin
...