Can't connect to MYSQL container from Drupal container through drush - php

I try to figure out this problem since a long time now and I've got to admit that I'm out of responses.
Here is the case:
docker-compose.yml
version: "3"
services:
mysql:
image: mysql:8.0
container_name: mysql
hostname: mysql
command: --default-authentication-plugin=mysql_native_password
restart: unless-stopped
env_file: .env
volumes:
- db-data:/var/lib/mysql
networks:
- internal
drupal:
build:
context: .
dockerfile: Dockerfile
container_name: drupal
depends_on:
- mysql
restart: unless-stopped
volumes:
- ./web:/var/www/html/web:rw
- ./vendor:/var/www/html/vendor:rw
- ./drush:/var/www/html/drush
- drupal-data:/var/www/html
- ./php-conf/php.ini:/usr/local/etc/php/php.ini
networks:
- internal
- external
webserver:
image: nginx:1.19.1-alpine
container_name: webserver
depends_on:
- drupal
restart: unless-stopped
ports:
- 80:80
- 443:443
volumes:
- drupal-data:/var/www/html
- ./web:/var/www/html/web:rw
- ./nginx-conf/snippets/self-signed.conf:/etc/nginx/conf.d/snippets/self-signed.conf
- ./nginx-conf/snippets/ssl-params.conf:/etc/nginx/conf.d/snippets/ssl-params.conf
- ./nginx-conf/sites-available/default.conf:/etc/nginx/conf.d/default.conf
- ./ca-certificates/qiminfo-docker.dev+4.pem:/etc/ssl/certs/qiminfo-docker.dev+4.pem
- ./ca-certificates/qiminfo-docker.dev+4-key.pem:/etc/ssl/private/qiminfo-docker.dev+4-key.pem
networks:
- external
networks:
external:
driver: bridge
internal:
driver: bridge
volumes:
drupal-data:
db-data:
Dockerfile (only for drupal container)
FROM drupal:8.9.2-fpm-alpine
RUN apk add mysql-client && apk add openssh
I manage all dependencies via the mounted files in volumes (it works nice btw), but when I run drush through my host machine or through the container it doesn't see the Drupal instance (neither root or database) and I get the classic error message in this case ...
In BootstrapHook.php line 32:
[Exception]
Bootstrap failed. Run your command with -vvv for more information.
But, I use the Dockerfile to get mysql-client installed on drupal container and to allow connection from drupal container to mysql container. And when I try to connect to mysql (which has 'mysql' hostname) container database it works !
➜ docker exec -it drupal sh
/var/www/html # mysql -u drupal -p drupal -h mysql
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 8.0.21 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [drupal]>
The question is:
Why drush doesn't has access to mysql server container while mysql-cli does the job fine ?!
Please help T-T

Related

Link between symfony and docker

I'm on a symfony project and i'm using docker here's my docker-compose.yml :
version: '3.7'
services:
db:
image: mysql:latest
container_name: ruakh_db
restart: always
volumes:
- db-data:/var/lib/mysql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
networks:
- dev
phpmyadmin:
image: phpmyadmin:latest
container_name: ruakh_phpmyadmin
restart: always
depends_on:
- db
ports:
- 8080:80
environment:
PMA_HOST: db
networks:
- dev
maildev:
image: maildev/maildev
container_name: ruakh_mail_dev
restart: always
command: bin/maildev --web 80 --smtp 25 --hide-exetensions STARTTLS
ports:
- 8081:80
networks:
- dev
apache:
build: php
container_name: ruakh_www
ports:
- 8088:80
volumes:
- ./php/vhosts:/etc/apache2/sites-enabled
- ./:/var/www
restart: always
networks:
- dev
networks:
dev:
volumes:
db-data:`
here's the database url used in my symfony project :
DATABASE_URL=mysql://root:root#ruakh_db/ruakh
I'm trying to run a php bin/console make:migration however when i'm running I get this error :
An exception occurred in driver: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution
I'm assuming that the database url is incorrect, when I changed it to :
DATABASE_URL=mysql://root:root#127.0.0.1:8080/ruakh
This error is thrown:
An exception occurred in driver: SQLSTATE[HY000] [2006] MySQL server has gone away
How can I manage to connect my symfony project to my docker database ?
There is a couple things wrong with your DATABASE_URL.
DATABASE_URL=mysql://root:root#ruakh_db/ruakh
You don't set the password in your service config
You have the wrong host name
You don't specify the database
You are using native authentication, which must be enabled when using MySQL 8
(optional) your database port is not exposed
Password
In your docker-compose.yml. you do not specify the root password and instead allow for an empty password. You can set the root password using an environment variable:
services:
db:
...
environment:
MYSQL_ROOT_PASSWORD: example
Database name
In order to create a default database named ruakh you need to provide another environment variable MYSQL_DATABASE.
Host
The next issue is the host name in your DATABASE_URL: ruakh_db. This is the name of the container, but not the name of the service (i.e. the host in the virtual network that docker-compose sets up). This should be db instead.
Port
You will not be able to access your mysql database from outside the docker container, because you do not expose any ports. That is not necessarily an issue, but you should be aware of it. Looking at your other database url DATABASE_URL=mysql://root:root#127.0.0.1:8080/ruakh this will not work, because the port 8080 is for the web interface provided by phpmyadmin. It is not the port of the actual database. Also, the port for the database is not exposed. You probably want to add:
services:
db:
...
ports:
- 3306:3306
Authentication
Another issue, you will face is using the image mysql:latest this will use MySQL 8.0 which does not allow the authentication mechanism you want to use by default. You will have to change the command executed when running the container or downgrade to MySQL 5.7. If you want to keep MySQL 8, you should add this:
services:
db:
...
command:
- 'mysqld'
- '--character-set-server=utf8mb4'
- '--collation-server=utf8mb4_unicode_ci'
- '--default-authentication-plugin=mysql_native_password'
Summary
This is roughly what your db service should look like to work with your DATABASE_URL:
db:
image: mysql:latest
ports:
- '3306:3306'
environment:
MYSQL_DATABASE: ruakh
MYSQL_ROOT_PASSWORD: 'root'
command:
- 'mysqld'
- '--character-set-server=utf8mb4'
- '--collation-server=utf8mb4_unicode_ci'
- '--default-authentication-plugin=mysql_native_password'

PHP app cannot connect to docker mysql container at 127.0.0.1

Mysql is in it's own docker-compose.yml as I want a mysql server up and running that any other php application can connect to. So I do not have php and mysql in the same docker-compose.yml. From the php application, I can connect to mysql if I use the mysql container's gateway ip address by looking it up and then hard coding it into the php application. docker inspect mysql-db. But docker will change that 172... ip address each time mysql restarts so that is not ideal for development.
I can connect to mysql via mysql -h 127.0.0.1 no problem, but from the php application if I try to use 127.0.0.1 I get connection refused. I can only connect if I use the 172... gateway ip address.
How do I get the mysql container listening for connections from the host to 127.0.0.1?
docker-compose.yml for mysql
version: "3"
services:
mysql:
container_name: mysql-db
image: mysql
build:
dockerfile: Dockerfile
context: ./server/mysql
environment:
- MYSQL_ROOT_PASSWORD=admin
volumes:
- ./data/mysql:/var/lib/mysql
ports:
- 3306:3306
docker-compose.yml for php
version: "3"
services:
nginx:
container_name: nginx_myapp
image: nginx
build:
dockerfile: Dockerfile
context: ./server/nginx
ports:
- 80:80
- 443:443
volumes:
- ./app:/var/www/html
networks:
- myapp
php:
container_name: php_myapp
image: php:7.3-fpm
build:
dockerfile: Dockerfile
context: ./server/php-fpm
environment:
CI_ENV: development
volumes:
- ./app:/var/www/html
networks:
- myapp
networks:
myapp:
127.0.0.1 is the loopback address. It points to localhost. In the context of docker, localhost is the container itself. There is no db running on your php container so the connection will never succeed.
What you need to do is to configure the default network in you mysql compose file so that you will predictably control its name for later convenience (else it will be calculated from your compose project name which could change if you rename the containing folder...):
Important note: for the below to work, you need to use compose file version >= 3.5
---
version: '3.7'
#...
networks:
default:
name: shared_mysql
You can now use that shared_mysql network as external from any other compose project.
version: '3.7'
services:
nginx:
#...
networks:
- myapp
php:
#...
networks:
- myapp
- database
networks:
myapp:
database:
external: true
name: shared_mysql
You can then connect to mysql from your php container using the service name mysql (e.g. mysql -h mysql -u user -p)
Reference: https://docs.docker.com/compose/networking/
Few solutions for you
1) you can duplicate mysql section in each file using same volume path, in that case when you start project you will have same databases
project1
version: "3.2"
services:
mysql:
volumes:
- /var/mysql:/var/lib/mysql
php:
build:
context: './php/'
project2
version: "3.2"
services:
mysql:
volumes:
- /var/mysql:/var/lib/mysql
php:
build:
context: './php/'
2) you can connect using host.docker.internal or macos (docker.for.mac.localhost) directly to your host machine more information here From inside of a Docker container, how do I connect to the localhost of the machine?

Why docker not syncing files inside container on Windows 10?

I have issue after last docker update (seems so) on Windows 10 (local development). When I changed files in PhpStorm (and in another editors - Sublime, Notepad+), after a while, files inside container didn't receive changes.
Steps that can help for a while:
If I completely shut down all containers and after that arise them again. docker-compose down && docker-compoes up
If I get into php-fpm container and for file that not changed ran touch file.php (this file will be immidiatly changed).
What I tried and it didn't help:
I restarted php-fpm and nginx containers docker-compose restart php-fpm nginx (Yes it's strange, because down|up for all container helped)
I changed inside PhpStorm setting Use Safe write(save changes for temporary file first)
Also I checked inode for file inside container. With ls -lai file.php. Before changes worked and after they broked I had the same inode number. There is no determined number of changes I must to do to break syncing, it's random, sometime 2 changes enough.
I have:
Docker version 19.03.5, build 633a0ea
docker-compose version 1.25.2, build 698e2846
docker-compose.yml
version: '3'
services:
nginx:
container_name: pr_kpi-nginx
build:
context: ./
dockerfile: docker/nginx.docker
volumes:
- ./:/var/www/kpi
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./docker/nginx/fastcgi.conf:/etc/nginx/fastcgi.conf
ports:
- "8081:80"
links:
- php-fpm
networks:
- internal
php-fpm:
container_name: pr_kpi-php-fpm
build:
context: ./
dockerfile: docker/php-fpm.docker
volumes:
- ./:/var/www/kpi
links:
- kpi-mysql
environment:
# 192.168.221.1 -> host.docker.internal for Mac and Windows
XDEBUG_CONFIG: "remote_host=host.docker.internal remote_enable=1"
PHP_IDE_CONFIG: "serverName=Docker"
networks:
- internal
mailhog:
container_name: pr_kpi-mailhog
image: mailhog/mailhog
restart: always
ports:
# smtp
- "1025:1025"
# http
- "8025:8025"
networks:
- internal
kpi-mysql:
container_name: pr_kpi-kpi-mysql
image: mysql:5.7
command: mysqld --sql_mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
volumes:
- ./docker/storage/kpi-mysql:/var/lib/mysql
environment:
# We must change prod secrets, this is not good approach
- "MYSQL_ROOT_PASSWORD=pass"
- "MYSQL_USER=user"
- "MYSQL_PASSWORD=user_pass"
- "MYSQL_DATABASE=kpi_db"
ports:
- "33061:3306"
networks:
- internal
kpi-npm:
container_name: pr_kpi-npm
build:
context: ./
dockerfile: docker/npm.docker
volumes:
- ./:/var/www/kpi
- /var/www/kpi/admin/node_modules
ports:
- "4200:4200"
networks:
- internal
tty: true
# For xdebug
networks:
internal:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.221.0/28
P.S. There is opened issue:
https://github.com/docker/for-win/issues/5530
P.P.S. We need to update Docker from 2.2.0.0 to 2.2.0.3, Seems it's fixed
I have a separate container for syncing my folder:
app:
image: httpd:2.4.38
volumes:
- ./:/var/www/html
command: "echo true"
I just use the basic apache image, you could use anything really though. Then in my actual containers, I use the following volumes_from key:
awesome.scot:
build: ./build/httpd
links:
- php
ports:
- 80:80
- 443:443
volumes_from:
- app
php:
build: ./build/php
ports:
- 9000
- 9001
volumes_from:
- app
links:
- mariadb
- mail
environment:
APPLICATION_ENV: 'development'
I've never had an issue using this set up, files always sync fast, and I have tested both on Mac OSX and MS Windows.
If you're interested, here is my full LAMP stack on Github https://github.com/delboy1978uk/lamp
I have the same issue on Windows10 since 31st Jan.
I have commented a line in PhpStorm and checked it in the container using vim.
The changes were not there.
If I run docker-compose down and up, the changes go in the container.
Docker version 19.03.5, build 633a0ea
docker-compose version 1.25.4, build 8d51620a
Nothing changed in my docker-compose.yml since 2018.

docker mysql connection refused while connecting from PHP script

Basically I want to run the LAMP stack in an Docker container.
All services are so far running but as soon I try to connect to an mysql from within an PHP script I get following error:
Warning: mysqli::__construct(): (HY000/2002): Connection refused
docker-compose.yml
version: '3.2'
services:
php:
build: ./php/
networks:
- backend
volumes:
- './public/:/var/www/html'
apache:
build: ./apache/
depends_on:
- php
- mysql
networks:
- frontend
- backend
ports:
- '8080:80'
volumes:
- './public/:/var/www/html'
mysql:
image: 'mysql:5.6.40'
ports:
- "3306:3306"
networks:
- backend
environment:
- MYSQL_DATABASES=test
- MYSQL_ROOT_PASSWORD=root
- MYSQL_HOST=127.0.0.1
- MYSQL_PORT=3306
- MYSQL_USER=user
- MYSQL_PASSWORD=password
- MYSQL_MY_DATABASE=test
networks:
frontend: null
backend: null
Dockerfile for PHP:
FROM php:7.2.7-fpm-alpine3.7
RUN apk update; \
apk upgrade;
RUN docker-php-ext-install mysqli
I had tested it with the following approach:
docker exec -ti <mysql_docker> bash
and used the same crendatial for entering the mysql mode:
mysql -uroot -h127.0.0.1 -P3306 -p
and there is not problem with it.
So what may cause the above connection refused?

Docker SQLSTATE[08006] for pgsql service only from php service

Not sure if my title is accurate, but here's my issue. I am running a basic laravel site on Docker and cannot get the site itself to connect to the PostgreSQL service. I will post my docker-compose.yml below. When i run php artisan migrate i get no errors and it all works. I can even use my Postico PostgreSQL client to connect to the DB and run queries. But, when i try and connect to the DB from the site, it errors out saying this:
SQLSTATE[08006] [7] could not connect to server: Connection refused Is the server running on host "127.0.0.1" and accepting TCP/IP connections on port 5433?
Here are my PostgreSQL client settings (which DO work):
Host: 127.0.0.1
Port: 5433
User: homestead
Password: homestead
Database: homestead
I have been messing around with different settings and things so here is my docker-compose.yml, although i'm sure there are things i don't need in there:
version: '2'
services:
php:
image: jguyomard/laravel-php:7.2
build:
context: .
dockerfile: infrastructure/php/Dockerfile
volumes:
- ./:/var/www/
- $HOME/.composer/:$HOME/.composer/
networks:
- default
links:
- postgresql
- redis
nginx:
image: jguyomard/laravel-nginx:1.13
build:
context: .
dockerfile: infrastructure/nginx/Dockerfile
ports:
- 81:80
networks:
- default
links:
- postgresql
- redis
postgresql:
image: postgres:9.6-alpine
volumes:
- pgsqldata:/var/lib/postgresql/data
environment:
- "POSTGRES_DB=homestead"
- "POSTGRES_USER=homestead"
- "POSTGRES_PASSWORD=homestead"
ports:
- "5433:5432"
networks:
- default
redis:
image: redis:4.0-alpine
command: redis-server --appendonly yes
ports:
- "6379:6379"
networks:
- default
# elastic:
# image: elasticsearch:5.5-alpine
# ports:
# - "9200:9200"
volumes:
pgsqldata:
networks:
default:
Any thoughts on why the site can't connect to the DB?
My docker network ls output:
NETWORK ID NAME DRIVER SCOPE
2bf85424f466 bridge bridge local
c29d413f768e host host local
0bdf9db30cd8 none null local
f3d9cb028ae3 my-app_default bridge local
The error message ask Is the server running on host "127.0.0.1" but in your case PostgreSQL is running on a different docker container which is not 127.0.0.1 reference to php app so, change the server host to postgresql inside your php application.
And for the modified error, it is because that you have used port 5433 inside the php application which is the port of host machine which is for use outside the docker container (for host machine, that's why your Postico PostgreSQL client worked). But the port you have to use inside the docker network is 5432 change the server port to 5432 inside your php application.
And you have made the compose file complex by defining network in each host as default network. (You can follow this link for more details) If you don't have a requirement for that you don't need to do that as docker-compose will deploy all containers in single network.
And you don't need to use links they are deprecated. When multiple containers are in one docker-compose.yml file they are automatically deployed in a same single network.
So this simplified compose file will be recommended.
version: '2'
services:
php:
image: jguyomard/laravel-php:7.2
build:
context: .
dockerfile: infrastructure/php/Dockerfile
volumes:
- ./:/var/www/
- $HOME/.composer/:$HOME/.composer/
nginx:
image: jguyomard/laravel-nginx:1.13
build:
context: .
dockerfile: infrastructure/nginx/Dockerfile
ports:
- 81:80
postgresql:
image: postgres:9.6-alpine
volumes:
- pgsqldata:/var/lib/postgresql/data
environment:
- "POSTGRES_DB=homestead"
- "POSTGRES_USER=homestead"
- "POSTGRES_PASSWORD=homestead"
ports:
- "5433:5432"
redis:
image: redis:4.0-alpine
command: redis-server --appendonly yes
ports:
- "6379:6379"
# elastic:
# image: elasticsearch:5.5-alpine
# ports:
# - "9200:9200"
volumes:
pgsqldata:

Categories