Connect from a docker container to a mysql database in another container - mysql

I would like to access mariadb in the db container from the app container with the following folder configuration, but it does not work with an error.
directory structure
.
├── app
│ └── Dockerfile
├── db
│ └── Dockerfile
└── docker-compose.yml
Code
app/Dockerfile
FROM debian:buster
RUN set -x \
&& apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y \
mariadb-client \
vim
CMD [ "tail", "-f" ]
db/Dockerfile
FROM debian:buster
RUN set -x \
&& apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y \
mariadb-server \
mariadb-client \
vim
CMD service mysql start \
&& tail -f /dev/null
docker-compose.yml
version: "3.9"
services:
app:
build: ./app
networks:
- frontend
db:
build: ./db
volumes:
- db_data:/var/lib/mysql
expose:
- 3306
networks:
- frontend
networks:
frontend:
driver: bridge
volumes:
db_data: {}
Execution Commands
I entered the app container and executed the following commands, but I get an error.
root#0e0ad0889639:/# mysql -h db -uroot
ERROR 2002 (HY000): Can't connect to MySQL server on 'db' (115)
root#0e0ad0889639:/# ping db
PING db (192.168.128.3) 56(84) bytes of data.
64 bytes from test_db_1.test_frontend (192.168.128.3): icmp_seq=1 ttl=64 time=0.104 ms
64 bytes from test_db_1.test_frontend (192.168.128.3): icmp_seq=2 ttl=64 time=0.142 ms
How can I connect?
Environment
❯ docker -v
Docker version 20.10.12, build e91ed57
❯ docker-compose -v
docker-compose version 1.29.2, build 5becea4c
❯ sw_vers
ProductName: macOS
ProductVersion: 12.3
BuildVersion: 21E230

The following method in db container solved the problem.
database setting
USE mysql;
GRANT ALL ON *.* TO 'root'#'%' identified by 'pass' WITH GRANT OPTION ;
GRANT ALL ON *.* TO 'root'#'localhost' identified by 'pass' WITH GRANT OPTION ;
FLUSH PRIVILEGES ;
mysql config file setting
echo "bind-address = app" >> etc/mysql/mariadb.conf.d/50-server.cnf

As pointed out by comments, the default Debian MariaDB configures a bind-address to localhost. This is why the Docker Library mariadb image removes those configuration items.
If all you want is a vim installed in your container maybe the following to gain all the benefits of a maintained and tested container image:
db/Dockerfile
FROM mariadb:10.6
ENV MARIADB_ROOT_PASSWORD=pass
RUN set -x \
&& apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y \
vim; \
rm -rf /var/lib/apt/lists/*
note small editors exist if you are interested.

Related

install wordpress with cli in docker gives "error establishing database connection" with mariadb container

I try to set up a wordpress website with docker-compose, by having one container for nginx, one for mariadb, and a last one for wordpress, and also two volumes for worpdress and mariadb
I'm not there yet, I'm stuck at an intermediate step : using wp-cli (https://make.wordpress.org/cli/handbook/how-to-install/) I want to configure wordpress with the database, but I get an error :
project architecure :
|_ docker-compose.yml
|_ .env
|_ mariadb/
|_ Dockerfile
|_ wordpress/
|_ Dockerfile
wordpress dockerfile : (it's missing steps, like an entrypoint or a cmd, but i'm already getting an error)
FROM debian:buster
RUN apt update && apt install -y \
php7.3 \
php7.3-mysqli \
curl
# install wp-cli : https://make.wordpress.org/cli/handbook/guides/installing/
RUN curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar &&\
chmod +x wp-cli.phar && \
mv wp-cli.phar /usr/local/bin/wp
ARG WP_DIR=/var/www/html
ARG DB_NAME
ARG DB_USER
ARG DB_PSWD
ARG WP_URL
ARG WP_TITLE
ARG WP_ADMIN
ARG WP_ADMIN_PSWD
ARG WP_ADMIN_EMAIL
# install wordpress with cli : https://make.wordpress.org/cli/handbook/how-to-install/
RUN wp core download --path=${WP_DIR} --allow-root
RUN wp config create --dbname=${DB_NAME} \
--dbuser=${DB_USER} \
--dbpass=${DB_PASS} \
--path=${WP_DIR} \
--allow-root \
--skip-check
# this command gives an error :
RUN wp core install --url=${WP_URL} \
--title=${WP_TITLE} \
--admin_user=${WP_ADMIN} \
--admin_password=${WP_ADMIN_PSWD} \
--admin_email=${WP_ADMIN_EMAIL} \
--path=${WP_DIR} \
--allow-root
mariadb dockerfile :
FROM debian:buster
ARG DB_NAME
ARG DB_USER
ARG DB_PSWD
RUN apt update && apt install -y \
mariadb-client \
mariadb-server \
&& \
rm -rf /var/lib/apt/lists/*
# configure wp database
RUN service mysql start && \
mariadb --execute="CREATE DATABASE ${DB_NAME};" && \
mariadb --execute="CREATE USER '${DB_USER}'#'localhost' IDENTIFIED BY '${DB_PSWD}';" && \
mariadb --execute="GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'#'localhost' with grant option;"
# start mysql server (https://www.mysqltutorial.org/mysql-adminsitration/start-mysql)
CMD [ "service", "mysql", "start" ]
docker-compose.yml :
version: "3.8"
services:
mariadb:
env_file: .env
build:
context: ./mariadb
args:
- DB_NAME=${DB_NAME}
- DB_USER=${DB_USER}
- DB_PSWD=${DB_PSWD}
image: mariadb
container_name: mymariadb
wordpress:
env_file: .env
build:
context: ./wordpress
args:
- WP_URL=${WP_URL}
- WP_TITLE=${WP_TITLE}
- WP_ADMIN=${WP_ADMIN}
- WP_ADMIN_PSWD=${WP_ADMIN_PSWD}
- WP_ADMIN_EMAIL=${WP_ADMIN_EMAIL}
- DB_NAME=${DB_NAME}
- DB_USER=${DB_USER}
- DB_PSWD=${DB_PSWD}
image: wordpress
container_name: mywordpress
.env file :
## MARIADB SETUP
DB_NAME=db_wp
DB_USER=db_user
DB_PSWD=db_pswd
## WORDPRESS SETUP
WP_URL=wp_url.fr
WP_TITLE=wp_blog
WP_ADMIN=wp_admin
WP_ADMIN_PSWD=wp_admin_pswd
WP_ADMIN_EMAIL=wp_email#wp.fr
if I run docker-compose build I get this error :
Error establishing a database connection. This either means that the username and password information in your `wp-config.php` file is incorrect or that contact with the database server at `localhost` could not be established. This could mean your host’s database server is down.
I think that the wordpress container cannot use the database running in the mariadb container. I tried to gives an explicit network but it didn't works either. I also tried to make wordpress build depends on mariadb, but it was not successful either :
wordpress:
...
depends_on:
mariadb:
condition: service_completed_successfully
...
I don't know if it's even possible to install wordpress during build time ? maybe I should launch a script at run time ? I'm new to all of this (docker, worpress, mariadb, and nginx, php, php-fpm that I didn't show here because it's not relevant to this error) so I'm certainly doing a lot of mistakes, my apologies
I'm confused about the line CMD [ "service", "mysql", "start" ] in mariadb dockerfile, it doesn't act good, if I run the container it stays up for 5 or 6 seconds then it exits. But if I use CMD [ "mysqld" ] instead it works great, although I don't understand why. But I don't think it is connected to my problem with wordpress installation

Gitlab-CI : ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/run/mysqld/mysqld.sock'

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/run/mysqld/mysqld.sock' (2)
Hi guys !
I have a little (big) issue with my gitlab-ci.yml :(
I'm trying to run my tests PHPUnit on the pipeline but when I want to create a mysql database and to connect it, it fails.
This is my .gitlab-ci.yml :
image: jakzal/phpqa:php8.0
before_script:
- composer install
stages:
- SecurityChecker
- UnitTests
cache:
paths:
- vendor/
- ~/.composer/cache/files
#On teste qu'il n'y a pas de faille de sécurité dans les différentes librairies
security-checker:
stage: SecurityChecker
script:
- local-php-security-checker composer.lock
allow_failure: false
#On lance les tests unitaires PHP UNIT
phpunit:
stage: UnitTests
services:
- name: mysql:latest
before_script:
- apt-get update && apt-get dist-upgrade && apt-get install -y git libzip-dev autoconf build-essential pkg-config libmariadb-dev-compat libmariadb-dev default-mysql-client mariadb-client mariadb-server
- curl -sSk https://getcomposer.org/installer | php -- --disable-tls && mv composer.phar /usr/local/bin/composer
- docker-php-ext-install mysqli pdo pdo_mysql zip
# Connect MySQL
- echo "SET PASSWORD FOR 'root'#'localhost' = PASSWORD('password');" | mysql -u root
- echo "SELECT 'OK';" | mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -h mysql "$MYSQL_DATABASE"
# Import BDD tests
- mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -h localhost < "database.sql"
script:
- vendor/bin/phpunit --testdox
allow_failure: false
This is the result :
Pipeline error
Do you have any ideas fo my issue ?
I didn't found anything on the different forums for now... :sleepy:
Thanks a lot !
Take a look here: https://docs.gitlab.com/ee/ci/services/
I was able to get it work like this:
stages:
- test
services:
- mariadb
test:
stage: test
image: mariadb
variables:
MARIADB_ROOT_PASSWORD: password
MARIADB_DATABASE: dbname
script:
- mysql --user=root --password="$MARIADB_ROOT_PASSWORD" --host=mariadb
Might you have to change -h localhost to -h mysql.
The answer to my issue is this code !
It works for me :)
#On lance les tests unitaires PHP UNIT
phpunit:
stage: UnitTests
services:
- name: mysql:8.0.11
variables:
MYSQL_DATABASE: 'database-name'
MYSQL_ROOT_PASSWORD: ''
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
DB_USERNAME: 'runner'
DB_PASSWORD: 'password'
DB_HOST: 'mysql'
before_script:
# Install packages and docker
- apt-get update -y && apt-get dist-upgrade -y && apt-get install -y git libzip-dev autoconf curl libmcrypt-dev build-essential pkg-config libmariadb-dev-compat libmariadb-dev default-mysql-client mariadb-client mariadb-server
- docker-php-ext-install mysqli pdo pdo_mysql zip
# Config MySQL
- rm -f /tmp/mysql.sock.lock
- sleep 10
# Import BDD for tests units
- mysql -u root -h "$DB_HOST" < "web/files/database-test.sql"
# Check BDD
- echo "SHOW tables;" | mysql -u root -h "$DB_HOST" -D "$MYSQL_DATABASE"
script:
- vendor/bin/phpunit --testdox
allow_failure: false

Accessing mysql from build commands in bitbucket pipelines

I'm getting ERROR 2002 (HY000): Can't connect to local MySQL when trying to execute a mysql command during my CI process.
Here is my bitbucket-pipelines.yml file
image: theotherperson/php-ci:5.6
pipelines:
default:
- step:
caches:
- composer
script:
- apt-get update && apt-get install -y unzip mysql-client
- curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
- composer install --no-scripts --no-plugins
- cp test-assets/vhosts/000-default.conf /etc/apache2/sites-enabled/000-default.conf
- cp test-assets/hosts/hosts /etc/hosts
- rm /var/www/html/index.html
- cp -R $BITBUCKET_CLONE_DIR /var/www/html
- service apache2 restart
- mysql -u root -p$MYSQL_ROOT_PASSWORD -e "test < $BITBUCKET_CLONE_DIR/data/test/test.sql"
- phantomjs --webdriver=4444 &
- vendor/bin/behat -p test_behat
services:
- mysql
definitions:
services:
mysql:
image: mysql
environment:
MYSQL_DATABASE: 'test'
MYSQL_ROOT_PASSWORD: 'mypassword'
And here is the error:
+ mysql -u root -p$MYSQL_ROOT_PASSWORD -e "test < $BITBUCKET_CLONE_DIR/data/test/test.sql"
Enter password: ERROR 2002 (HY000): Can't connect to local MySQL
What do I need to do to be able to access mysql from this command line?
look at their documentation
Host name: 127.0.0.1 (avoid using localhost, as some clients will attempt to connect via a local "Unix socket", which will not work in Pipelines)

Error while executing mysql commands inside docker-compose

When I execute the xdcomp_my_sql_client command it pings the ip but then when it tries to reach the mysql server it fails. If I do the exact same command once the container is running it works. It seems that the mysql server is not running at the moment the command is executed. But I have used the "depends_on" command, so what I'm doing wrong?
Thank you.
version: '2'
services:
xdcomp_my_sql_server:
image: mysql/mysql-server:latest
environment:
MYSQL_ROOT_PASSWORD: diego
MYSQL_USER: otro
MYSQL_PASSWORD: otro
MYSQL_ROOT_HOST: 172.28.0.101
networks:
SQLNetwork:
ipv4_address: 172.28.0.102
xdcomp_my_sql_client:
build: .
command: sh -c 'ping -c 5 172.28.0.102 && mysql -h 172.28.0.102 -u root -pdiego sys < /lafayette/forensic.sql && tail -f /etc/hostname'
ports:
- 83:80
networks:
SQLNetwork:
ipv4_address: 172.28.0.101
depends_on:
- xdcomp_my_sql_server
networks:
SQLNetwork:
driver: "bridge"
ipam:
config:
- subnet: 172.28.0.0/24
gateway: 172.28.0.201
Client Dockerfile
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get install -y mysql-client
RUN apt-get install -y git
RUN git clone https://github.com/linkedin/lafayette
RUN apt-get update
RUN apt-get install -y python-dnspython
RUN apt-get install -y python-pip
RUN pip install Flask
RUN pip install python-dateutil
RUN apt-get install -y python-mysqldb
RUN pip install requests
RUN pip install multiprocessing
RUN pip install multiprocess
RUN apt-get install -y vim
RUN apt-get -y install iputils-ping
Working with docker includes 2 steps:
building a image
creating container based on image and running this container
The point is you mysql client can connect to server only on second step.
Dockerfile "executes" while you build image. In this time you don't have any containers, therefore you can`t connect to them.
You need move command
RUN cd lafayette && mysql –h 172.25.0.102 –u root –ppass sys < forensic.sql
from Dockerfile to entrypoint.sh
Can you show me your Dockerfile? I will try to fix the issue
The problem was the following: the mysql server was not running at the time the client command was executed. Even when the key "depends_on" was present (see:https://docs.docker.com/compose/startup-order/) For that reason the solution was to wait for the mysql server. This was done with the following command:
command: sh -c 'until nc -z -v -w20 172.28.0.102 3306; do sleep 1;
echo "Waiting for mysqlserver to come up..."; done && ping -c 5 172.28.0.102 &&
mysql -h 172.28.0.102 -u root -pdiego sys < /lafayette/forensic.sql &&
tail -f /etc/hostname'
The wait for was made by the following line:
until nc -z -v -w20 172.28.0.102 3306; do sleep 1;
echo "Waiting for mysqlserver to come up..."; done
nc= netcat command, it check the connection to a given ip and port

Accessing docker container mysql databases

I am trying to access mysql databases from my docker host to the container.
It's my own dockerfile which install a database expose on port 3306.
I launch my docker with docker-compose, and my compose file is mapping 3308 host port on 3306 container port.
I can access to mysql from the host like this :
mysql -h localhost -P 3308 -u root -pMyPassword
It's working well, but what I can't figure out, is why I can't see any datas from my container?
From inside the container, I have a test databases which I can connect to without any problem. But when I connect from the host to the container mysql process, It seems to show me the mysql datas from the host machine, not from the container one.
Any ideas?
Thanks :)
EDIT 1 :
So here is the first way I can connect to mysql into the container :
docker exec -it MyContainer mysql -uroot -pMyPassword
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test_db |
+--------------------+
It show me my db : test_db
But If i access from :
mysql -h localhost -P 3308 -u root -pMyPassword
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+
My test_db isn't here.
And the result of docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a0de6a691d72 MyContainer "docker-entrypoint.sh" 3 hours ago Up 3 hours 9000/tcp, 0.0.0.0:8085->80/tcp, 0.0.0.0:3308->3306/tcp, 0.0.0.0:8084->8000/tcp, 0.0.0.0:8086->8080/tcp MyContainer
EDIT 2 :
I am developing a standard docker container for web hosting production environnement. Each host is controlled by ajenti. The host work with an nginx reverse proxy which redistribute websites on correct container. Every thing is wokring well. So here is my Dockerfile :
FROM php:5.6-fpm
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
libxml2-dev \
python \
build-essential \
make \
gcc \
python-dev \
locales \
python-pip
RUN dpkg-reconfigure locales && \
locale-gen C.UTF-8 && \
/usr/sbin/update-locale LANG=C.UTF-8
ENV LC_ALL C.UTF-8
ARG MYSQL_ROOT_PASSWORD
RUN export DEBIAN_FRONTEND=noninteractive; \
echo mysql-server mysql-server/root_password password $MYSQL_ROOT_PASSWORD | debconf-set-selections; \
echo mysql-server mysql-server/root_password_again password $MYSQL_ROOT_PASSWORD | debconf-set-selections;
RUN apt-get update && apt-get install -y -q mysql-server php5-mysql
RUN rm /etc/apt/apt.conf.d/docker-gzip-indexes
RUN apt-get update && apt-get install -y wget
RUN wget http://repo.ajenti.org/debian/key -O- | apt-key add -
RUN echo "deb http://repo.ajenti.org/debian main main debian" > /etc/apt/sources.list.d/ajenti.list
RUN apt-get update && apt-get install -y ajenti cron unzip ajenti-v ajenti-v-php-fpm ajenti-v-mysql ajenti-v-nginx
RUN apt-get install -y python-setuptools python-dev \
&& easy_install -U gevent==1.1b3 \
&& sed -i -e s/ssl_version=PROTOCOL_SSLv3/ssl_version=PROTOCOL_SSLv23/ /usr/local/lib/python2.7/dist-packages/gevent-1.1b3-py2.7-linux-x86_64.egg/gevent/ssl.py
EXPOSE 80 8000 8080 3306
RUN mkdir /tmp/tempfiles \
&& mv /srv /tmp/tempfiles \
&& mv /var/lib/mysql /tmp/tempfiles \
&& mv /var/log /tmp/tempfiles \
&& mv /etc/ajenti /tmp/tempfiles
COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s /usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]
As I said, I wanted to be able do deploy a new container easily. So I created a docker-entrypoint.sh which copy wanted files to my volume when I start the container :
#!/bin/bash
DIR="/var/lib/mysql"
# look for empty dir
if [ ! "$(ls -A $DIR)" ]; then
cp -avr /tmp/tempfiles/mysql /var/lib/
fi
# rest of the logic
DIR="/srv"
# look for empty dir
if [ ! "$(ls -A $DIR)" ]; then
cp -avr /tmp/tempfiles/srv /
fi
# rest of the logic
DIR="/var/log"
# look for empty dir
if [ ! "$(ls -A $DIR)" ]; then
cp -avr /tmp/tempfiles/log /var/
fi
# rest of the logic
DIR="/etc/ajenti"
# look for empty dir
if [ ! "$(ls -A $DIR)" ]; then
cp -avr /tmp/tempfiles/ajenti /etc/
fi
# rest of the logic
Finally, my docker-compose.yml to launch everything and map ports :
version: '2'
services:
ajenti:
build:
context: ./dockerfiles/
args:
MYSQL_ROOT_PASSWORD: MyPassword
volumes:
- ./logs:/var/log
- ./html:/srv
- ./ajenti:/etc/ajenti
- ./mysql-data:/var/lib/mysql
- ./apache2:/etc/apache2
ports:
- "8084:8000"
#NGINX
- "8085:80"
#APACHE
- "8086:8080"
- "3308:3306"
Hope this will help to find a solution !
I finally found a solution and it was pretty simple...
First of all, I need to let mysql bind external address, so I changed the line bind-address to '0.0.0.0' inside the container.
Next I just changed the command line with mysql -h 127.0.0.1 -P 3308 -u root -pMyPassword
Now it's fine, I can access container mysql data from the host.
Thanks all for your help :)
In my case I was confused because docker used a different host and port. So you need to find them then do this:
mysql -P <portnumber> -h <host IP> -u db_name -p
Most people would put the docker DB related variables into the environment of the docker container so do this:
sudo docker exec -it container_name env
See if there's a variable called DB_HOST or DB_PORT or something like that. If not then look thru the source code. If it's a PHP project then find a config directory and look in main.php and see
if you execute MySQL operation as entrypoint in the dockerfile file, you will only see that operation when you connect to the container. try changing the entrypoint.
https://docs.docker.com/engine/reference/builder/#entrypoint