Docker: SQLSTATE[HY000] [2002] No such file or directory - php

Hey guys I'm trying to connect Yii2 with mysql running on mariadb.
I'm using docker and I have these containers
mariadb and php-fpm I can connect to mysql inside mariadb container using this command mysql -u root -p with no problem.
also using mysql workbench i can connect to mysql also through tunneling no problem there also.
But when I ran the site eg. mysite.com/user/login, when logging in I get this error
SQLSTATE[HY000] [2002] No such file or directory
Caused by: PDOException
this is my mariadb config inside docker-compose file
mariadb:
image: bitnami/mariadb:latest
container_name: mariadb
working_dir: /bitnami/mariadb
volumes:
- ./data/mariadb:/bitnami/mariadb
environment:
- MARIADB_ROOT_PASSWORD=rootpass
- MARIADB_DATABASE=mydb
- MARIADB_USER=david
- MARIADB_PASSWORD=pass
ports:
- "8890:3306"
on my main.php config in Yii2 I have this as my dsn
mysql:host=ipvalueofmysite.com;port=8890;dbname=mydb

In my case I found the solution here
Basically when in docker, the db service name becomes the hostname of the database, I needed to exchange localhost to db and the error was gone. Weird, I know. :)

Related

Docker php DPO to MariaDB - Error: Could not find driver

I'm learning PDO now and I found it better to learn it in a LEMP docker stack (Nginx, php-fpm, MariaDB, phpMyadmin) on my Ubuntu 18.04LTS.
This is my php file:
<?php
try {
$mydb = new PDO('mysql:host=database;dbname=mysql;charset=utf8', 'root', 'admin');
} catch (Exception $e) {
die('Error : ' . $e->getMessage());
}
?>
As you can see, I try to make a PDO in my php code to recover some datas from my db.
But everytime I got that message on my browser (Firefox 69.0.2):
Error : could not find driver
I saw that post here: "Docker can't connect to mariadb with PHP". The problem was quite similar to mine but it didn't work for me.
Note: php-fmp and Nginx work perfeclty together. Same for MariaDB and phpMyAdmin.
Here is my docker-compose.yml file:
version: "3"
services:
nginx:
image: tutum/nginx
ports:
- "7050:80"
links:
- phpfpm
volumes:
- ./nginx/default:/etc/nginx/sites-available/default
- ./nginx/default:/etc/nginx/sites-enabled/default
- ./logs/nginx-error.log:/var/log/nginx/error.log
- ./logs/nginx-access.log:/var/log/nginx/access.log
phpfpm:
image: php:fpm
links:
- database:mysql
ports:
- "7051:9000"
volumes:
- ./public:/usr/share/nginx/html
database:
image: mariadb
environment:
MYSQL_ROOT_PASSWORD: admin
ports:
- "7052:3306"
phpmyadmin:
image: phpmyadmin/phpmyadmin
restart: always
links:
- database:mysql
ports:
- "7053:80"
environment:
PMA_HOST: mysql
PMA_USER: root
PMA_PASSWORD: admin
PMA_ARBITRARY: 1
If it is possible to solve this without building my own Dockerfiles, it would be great.
But if I must, I will. This isn't a problem.
docker-compose is an "api" of sorts for a Dockerfile. You need to add those libraries (apt-get etc...) in the Dockerfile
Dockerfile is your friend!
Is your PHP file inside a docker container or is it running outside docker, in the host machine?
If it is running inside the docker container, which service is it in? Please note that the nginx service does not have the "links" configuration, meaning it only accesses the database through the "database" hostname. Check the port as well (in the end of this post).
If your PHP file is running outside, then you have to use localhost instead of mysql in your connection string, like so: 'mysql:host=localhost;dbname=mysql;charset=utf8'. This is because docker's internal DNS is just that: internal. You can't access this hostname (database or mysql) outside docker.
Equally important, your connection string is not specifying the port, which is 7052 in your case. Since you're redirecting from 7052 to 3306, I think 3306 is mysql's default port, and the driver assumes 3306 if you do not specify it. It's always a good idea to be explicit about hosts and ports. Check the documentation on PHP databse connection strings about it (as I know nothing about php). It's probably ...;port=7052 or something.
Also, read up on docker-compose links, which you are using. It's deprecated now, so I advise to not use it in future projects, I even advise to spend some time removing it. Should take like 30 seconds to 5 minutes if everything goes well, and it won't haunt you anymore.
A found the solution.
First of all, the host must be mysql and not the name of my container (which is database):
$mydb = new PDO('mysql:host=mysql;dbname=mysql;charset=utf8', 'root', 'admin');
Inside the phpfpm container (accessible via the command docker-compose run --rm <container-name> bash), I had to enable the extension=php_pdo_msql line in my config file php.ini by removing the semicolon at the beginning of its line.
To avoid doing this manually every time after a docker-compose up, I replaced the phpfpm service in my docker-compose.yml file the following Dockerfile:
FROM php:fpm
RUN docker-php-ext-install pdo pdo_mysql
Finally, just build the image with the command docker-compose build . (replace the . by the path to the directory containing the docker-compose.yml file).
It works perfectly for me.

Symfony 4 "Connection refused" while trying to connect to docker mysql container

My question is how to configure connection to mysql container.
Here is my docker-compose.yml
version: '3'
services:
php:
build: ./php-fpm
volumes:
- ./iym:/var/www/iym
- ./php-fpm/php.ini:/usr/local/etc/php/php.ini
depends_on:
- mysql
web:
build: ./nginx
ports:
- "8888:80"
volumes:
- ./iym:/var/www/iym
- ./nginx/iym.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
mysql:
image: mysql:5.6
restart: always
command: --default-authentication-plugin=mysql_native_password
volumes:
- ${DB_PATH_HOST}:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: "symf0ny"
ports:
- "3306:3306"
And here is my DATABASE_URL in .env file
DATABASE_URL=mysql://root:symf0ny#127.0.0.1:3306/iym
When i try to run php bin/console doctrine:database:create i get an error like "SQLSTATE[HY000] [2002] Connection refused". OS - ubuntu 18.04. What should i do to connect to DB? Many thanks!
I assume you are trying to connect from another container/service defined in docker-compose and you are using current version of docker-compose (2.4 or 3.7)
You need to change
DATABASE_URL=mysql://root:symf0ny#127.0.0.1:3306/iym
to
DATABASE_URL=mysql://root:symf0ny#mysql:3306/iym
The reason is that 127.0.0.1 is refering to the localhost of the machine on which php runs. In this case it's the php's container localhost. But the db doesn't run there. It runs in another docker container, which can be reached under the service name, mysql in this case.
In docker-compose networking docs is written:
By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.
but, the service is discoverable under the container name (which is automatically generated to projectName_serviceName_1 (project name begin by default folder name), but also under service name, link and service alias if defined. I would recommend using service name wherever possible.
More in docs: https://docs.docker.com/compose/networking/
In my case, the Docker variable overrides the parameter from .env file and I'm trying to connect to the wrong host. Found that via dd($this->constructPdoDsn($params)) in the Doctrine\DBAL\Driver\PDO\MySQL\Driver::connect, maybe it will be helpful

Can't connect to between mysql container and php in docker

Trying to connect to mysql 8 (mysql:latest) from a php:latest image (without apache or nginx) and I'm getting this annoying error:
Fatal error: Uncaught PDOException: SQLSTATE[HY000] [2002] Connection refused in /src/conn.php:5
Stack trace:
#0 /src/conn.php(5): PDO->__construct('mysql:host=data...', 'root', '12345678')
#1 {main}
thrown in /src/conn.php on line 5
I've looked for +20 solutions here on stackoverflow but none of them was able fix my problem. I can connect without a problem using mysql workbench or DataGrid using the following credentials:
server: localhost user: root pass: 12345678
But any configuration I use on the php image I can't make them connect with each other.
My docker-compose file:
version: '3'
services:
composer:
container_name: composer
networks:
- backend
image: composer
volumes:
- .:/app
command: install
database:
container_name: mysql
networks:
- backend
image: mysql:latest
volumes:
- ./database/mysqldata:/var/lib/mysql
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: 12345678
MYSQL_DATABASE: testdb
ports:
- "3306:3306"
php:
build:
context: .
container_name: php
networks:
- backend
image: php:apache
links:
- database
env_file:
- .env
volumes:
- .:/
command:
php /src/conn.php
depends_on:
- composer
- database
networks:
backend:
My conn.php:
<?php
$db = new PDO('mysql:host=database;dbname=testdb', 'root', '12345678');
What I did until now to try to fix the problem:
Change conn.php host to 127.0.0.1
Change conn.php host to localhost
Tried to use mysqli (got also connection refused)
Tried another php images (with apache, nginx etc)
Tried to use mysql as a host
PS: I'm using docker for mac
After 5 hours of research I really don't know what else to do and as I'm not a docker expert, would appreciate any help to point me the direction of the fix.
Thank you!
In your case, you can't connect to mysql via localhost or 127.0.0.1. If you connect like this. It call to localhost inside php container. But there is no mysql install in your php container.
You must connetc via container name. Or docker inspect you mysql container and get the container IP. For example with your docker-compose
database:
container_name: mysql
Now your mysql database host is mysql - container name instead localhost
Was able to find the solution. Turns out I need to wait for mysql service to be available before I start the php script. So I used the wait-for-it solution and did this on docker-compose:
command: >
bash -c "chmod +x /docker/./wait-for-it.sh
&& /docker/./wait-for-it.sh database:3306 -- echo 'database is up'
&& php phpscript.php"
Thank you for the help

Symfony + Docker, connection refused

I'm seasoned in Symfony but quite new to docker, and I have a "connection refused error" I don't manage to solve.
Pretty sure it is a beginner error and that the solution here is quite simple...
Here is the content of my docker-compose file:
version: '3.2'
services:
cg-demo:
build: docker/cg-demo
container_name: cg-demo
working_dir: /var/www/html
volumes:
- .:/var/www/html
- ./docker/demo/vhost.conf:/etc/apache2/sites-available/000-default.conf:ro
- ./docker/demo/php.ini:/usr/local/etc/php/php.ini:ro
- ~/.ssh:/var/www/.ssh
- ~/.composer:/var/www/.composer
environment:
- SYMFONY_ENV
- DOMAIN_NAME: cg-demo.docker
- VIRTUAL_HOST: cg-demo.docker
depends_on:
- database
env_file: .env
ports:
- 8000:80
database:
image: percona:5.6
ports:
- 3306:3306
expose:
- 3306
container_name: cg-demo-database
volumes:
- /docker/database:/etc/mysql/conf.d
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: demo
tmpfs:
- /var/lib/mysql
- /tmpfs:size=300M
This has been based from another project that works, but I'm not sure of all that's happening here...
I also have a phpmyadmin container, not shown here. PhpMyAdmin connects correctly to the database and can use it without problem from any web server. However when it comes to the symfony container, I have this whenever trying to use the database:
[Doctrine\DBAL\Exception\ConnectionException]
An exception occured in driver: SQLSTATE[HY000] [2002] Connection refused
[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[HY000] [2002] Connection refused
[PDOException]
SQLSTATE[HY000] [2002] Connection refused
The connection information is the following, in a .env file:
# Database credentials
DATABASE_HOST=database
DATABASE_PORT=3306
DATABASE_USER=root
DATABASE_PASSWORD=root
DATABASE_DB=cg-demo
Calling docker ps gives me this:
CONTAINER ID IMAGE COMMAND
CREATED STATUS PORTS NAMES
16a67dadeebb phpmyadmin/phpmyadmin "/run.sh phpmyadmin" 15 minutes ago Up 15 minutes 0.0.0.0:8001->80/tcp cg.phpmyadmin.docker
8bd783aa1dd1 cg_cg-demo "entrypoint.sh apa..." 15 minutes ago Up 15 minutes 0.0.0.0:8000->80/tcp cg-demo
2fc7cd9105ba percona:5.6 "docker-entrypoint..." 15 minutes ago Up 15 minutes (healthy) 3306/tcp cg-database
I've tried to ping database from the demo container and it works...
EDIT 1:
Added the following to the database container:
ports:
- 3306:3306
EDIT 2:
Removed the following from all containers:
networks:
- default
EDIT 3:
My doctrine configuration in app/config/config.yml:
dbal:
host: "%env(DATABASE_HOST)%"
port: "%env(DATABASE_PORT)%"
dbname: "%env(DATABASE_DB)%"
user: "%env(DATABASE_USER)%"
password: "%env(DATABASE_PASSWORD)%"
charset: UTF8
mapping_types:
enum: string
server_version: 5.6
EDIT 4:
Added the following to the database configuration:
expose:
- 3306
This answer is for docker-compose version 2 and it also works on version 3:
The problem is a Linking Containers problem. We need to define additional aliases that services can use to reach one another.
Expose 3306 port will not solve your problem. mysql or percona container will expose by deffault that port. Take a look to the docker hub of percona image.
. It's mentioned there:
Connect to MySQL from an application in another Docker container
This image exposes the standard MySQL port (3306), so container
linking makes the MySQL instance available to other application
containers. Start your application container like this in order to
link it to the MySQL container:
$ docker run --name some-app --link some-percona:mysql -d application-that-uses-mysql
So, you should links the database to you cg-demo container. There's tow solutions:
1) Add a link under configuration :
services:
cg-demo:
build: docker/cg-demo
container_name: cg-demo
.
.
.
links:
- mysql
The diffirence between depeds_on and links is that depends_on docker-compose up will start services in dependency order. In your following example, database will be started before web.
We can also access data. But this is not enough, because we want to make sure that your web container (cg-demo) always connect to the database container.
Links allow you to define extra aliases by which a service is reachable from another service.
In the following example, database is reachable from web (cg-demo) at the hostname database. This means that thecg-demo can connect the database contanier from the 3306 port.
2) The second solution, is to configure the default network instead of (or in addition to) customizing your own network. Simply define a default entry under networks:
networks:
bridge_name:
driver: bridge
And then you should link every container to that bridge via networks tag:
cg-demo:
.
.
networks:
- bridge_name
database:
.
.
networks:
- bridge_name

Docker MYSQL '[2002] Connection refused'

I was trying out Docker for the first time. Got a LEMP stack up and running, but I can't connect to the MYSQL Database. Not on my Symfony application, not on PHPMyAdmin. The applications are returning the following error code:
An exception occured in driver: SQLSTATE[HY000] [2002] Connection refused
This is my docker-compose.yml:
nginx:
image: tutum/nginx
ports:
- "80:80"
links:
- phpfpm
volumes:
- ./nginx/default:/etc/nginx/sites-available/default
- ./nginx/default:/etc/nginx/sites-enabled/default
- ./logs/nginx-error.log:/var/log/nginx/error.log
- ./logs/nginx-access.log:/var/log/nginx/access.log
phpfpm:
build: phpfpm/
ports:
- "9000:9000"
volumes:
- ./public:/usr/share/nginx/html
mysql:
image: mariadb
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: admin
phpmyadmin:
image: phpmyadmin/phpmyadmin
restart: always
links:
- mysql
ports:
- 8183:80
environment:
MYSQL_USERNAME: admin
MYSQL_ROOT_PASSWORD: admin
PMA_ARBITRARY: 1
Dockerfile PHPFPM:
FROM php:fpm
RUN docker-php-ext-enable opcache
RUN apt-get update \
&& apt-get install -y --no-install-recommends libpq-dev \
&& docker-php-ext-install mysqli pdo_pgsql pdo_mysql
GitHub URL: https://github.com/MolengraafFrank/DockerSymfony
Could someone help me out? Thank you for your time.
The '[2002] Connection refused' means you can reach the database server, but you don't have right access for the user (in your case admin). By default mariadb have a root user with the password given by MYSQL_ROOT_PASSWORD and this user can connect from any server (%).
If you want use an over login to your databases, you have to create it in the databases server with the right granting on databases from chosen locations.
The problem here is that you have named your database server as 'mysql' (service name in the docker-compose file). But by default phpmyadmin tries to connect to a database server named 'db'. Adding PMA_HOST: mysql under the environment section of the phpmyadmin service will resolve this problem.
I think that MYSQL_USERNAME and PMA_ARBITRARY are useless if you work with default configuration (connection with root to your databases server)
I had this challenge because I am running 3 different containers with different IP Addresses
db - 172.18.0.3 - container for MYSQL
app - 172.18.0.2 - container for Laravel app
so I fixed it by editing my Laravel .env file
DB_CONNECTION=mysql
DB_HOST=172.18.0.3
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=username
...
To get your containers Ip addresses. From your docker host
docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)
UPDATED:
For latest docker versions and based on the services name, "mysql", in your docker-compose.yml
mysql:
image: mariadb
ports:
- 3306:3306
You can try this:
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=username
DB_HOST is the name of MySQL service name defined in docker-compose.yml
I've managed to connect to the mysql instance using mysql command line tool, this is the command I used - mysql -u root -p -h 127.0.0.1, and the entering the admin password. Is that a sufficient solution for you?
In my case I was running mysql in a docker container whose port was mapped to the host mac (3306:3306). I tried connecting to this database from a phpmyadmin docker container using 127.0.0.1 . But it won't work because the localhost on the phpmyadmin docker container does not have the required mysql running.
To connect to the host from docker network
docker.for.mac.host.internal
Docker Networking Docker Compose Networking
For my instance, the issue was with port mapping somehow.
In my case it was 3307:3306, as soon as I changed it to 3307 on the right side as well, I could connect to the DB instance.
Adding DB_READ_HOST=db solved this problem for me
If you want to know why your connexion failed, you can use in your terminal php artisan tinker and then
like
DB::connection()->getPdo();
Unfortunately this will only give you a part of the error.
Quit tinker and then use this command php artisan db will give you more information like database type, host, port, ad user about the issue.
Like this one
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1:3306' (61)
Symfony\Component\Process\Exception\ProcessFailedException
The command "'mysql' '--host=127.0.0.1' '--port=3306' '--user=root' '--default-character-set=utf8mb4' 'laravel'" failed.
Exit Code: 1(General error)
Working directory: /Users/Dev/Documents/www/laravel_docker/src/addressAPI
Output:
================
Error Output:
================
at vendor/symfony/process/Process.php:270
266▕ */
267▕ public function mustRun(callable $callback = null, array $env = []): self
268▕ {
269▕ if (0 !== $this->run($callback, $env)) {
➜ 270▕ throw new ProcessFailedException($this);
271▕ }
272▕
273▕ return $this;
274▕ }
+14 vendor frames
15 artisan:37
Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
This will not give you the answer on what is wrong, but at least you can understand why your config is wrong.
you need to link the phpfpm container to mysql.

Categories