docker-compose mysql_pdo connection fail - php

I have 3 running containers, all is fine (containers are running, database is setted up) except that the PDO connection does not work. There is the error report
Fatal error: Uncaught PDOException: SQLSTATE[HY000] [2002] Connection
refused in /var/www/html/lib/OCFram/PDOFactory.php:9 Stack trace: #0 /var/www
/html/lib/OCFram/PDOFactory.php(9): PDO->__construct('mysql:host=mysq...',
'root', 'root') #1 /var/www/html/lib/OCFram/BackController.php(17):
OCFram\PDOFactory::getMysqlConnexion() #2 /var/www/html/lib/OCFram
/Application.php(69): OCFram\BackController->__construct(Object(App\Frontend
\FrontendApplication), 'Welcome', 'index') #3 /var/www/html/App/Frontend
/FrontendApplication.php(17): OCFram\Application->getController() #4 /var/www
/html/bootstrap.php(30): App\Frontend\FrontendApplication->run() #5 {main}
thrown in /var/www/html/lib/OCFram/PDOFactory.php on line 9
the docker-compose.yml
version: "3.2"
services:
php:
build: './php/'
volumes:
- ./MediterPourGrandir/:/var/www/html/
apache:
build: './apache/'
depends_on:
- php
- mysql
ports:
- "8080:80"
volumes:
- ./MediterPourGrandir/:/var/www/html/
mysql:
image: mysql:5.6.40
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=monsupersite
- MYSQL_USER=root
- MYSQL_PASSWORD=root
ports:
- "3306:3306"
the php docker file
FROM php:7.2.7-fpm-alpine3.7
# RUN apk update; \
# apk upgrade;
# RUN docker-php-ext-install pdo pdo_mysql
# RUN docker-php-ext-install mysqli
RUN apk update --no-cache \
&& apk add --no-cache $PHPIZE_DEPS \
&& apk add --no-cache mysql-dev \
&& docker-php-ext-install pdo pdo_mysql
the pdo connection class
<?php
namespace OCFram;
class PDOFactory
{
public static function getMysqlConnexion()
{
$db = new \PDO('mysql:host=mysql;port=3306;dbname=monsupersite', 'root', 'root');
// $db = new \PDO('mysql:host=mysql;port=3306;charset=utf8', 'root', 'rootpassword');
$db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
echo "Connected succesfully";
return $db;
}
}
I have done so many unsuccessful try. I'am missing something, but can not find out..... If someone got an idea, it would be great.
Thank you.

I finally can find out.
I did not notice it but after few seconds the mysql container were shutting down. The reason is: by default a mysql container name the MYSQL_USER as 'root', so who wants to use 'root' as MYSQL_USER must not declare it. See the github solved issue https://github.com/docker-library/mysql/issues/129
With these settings it works.
mysql:
image: mysql:5.6.40
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=monsupersite
- MYSQL_PASSWORD=root
ports:
- "3306:3306"

Yes. Or you can check php_info() information does php have enable extension or not.

Related

Not able to connect PHP application to db2 database on remote server

Been struggling connecting a PHP site to a remote DB2 database for the last three days in a docker-compose project I'm working on. I keep getting Connection failed:
Error: 58031
[IBM][CLI Driver] SQL1031N The database directory cannot be found on the indicated file system. SQLSTATE=58031 SQLCODE=-1031
Here's my docker-compose setup:
# /docker-compose.yml
---
version: '3.8'
services:
web:
container_name: nginx
depends_on:
- db2
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/nginx.conf
- ./app:/app
links:
- php
- db2
php:
container_name: php
build:
context: .
dockerfile: PHP.Dockerfile
volumes:
- ./app:/app
links:
- db2
db2:
container_name: db2.rn.dk
image: ibmcom/db2:latest
hostname: db2.rn.dk
privileged: true
ports:
- "50000:50000"
environment:
- DB_NAME=testdb
- DB_USER=db2inst1
- DB_PASSWORD=ChangeMe!
- LICENSE=accept
## Creates the database DB_NAME, if its not exists
- STARTUP_MODE=createIfNotExists
- DB_CREATE_SCRIPT=create_wdemo.sql
## loads an old backup of DB_NAME,
## if the dabase DB_NAME does not exist
# - STARTUP_MODE=restoreIfNotExists
# - DB_BACKUP=wdemo.tar.gz
volumes:
- './data/db2:/database'
And the PHP.dockerfile:
FROM php:fpm
RUN apt-get update -qq > /dev/null && \
apt-get install unzip
RUN pecl install xdebug && docker-php-ext-enable xdebug
# Documentation
# https://www.ibm.com/docs/en/db2/11.5?topic=dsd-installing-data-server-driver-odbc-cli-software-linux-unix-operating-systems
# https://www.ibm.com/docs/en/db2/11.5?topic=environment-configuring
# https://stackoverflow.com/questions/37066985/php-connection-to-db2
# https://github.com/nagstaku/php_db2
# https://github.com/php/pecl-database-ibm_db2
# https://github.com/php/pecl-database-pdo_ibm
# Install DB2 php-extensions
RUN mkdir -p /opt/ibm/ && curl https://public.dhe.ibm.com/ibmdl/export/pub/software/data/db2/drivers/odbc_cli/linuxx64_odbc_cli.tar.gz | tar -xz -C /opt/ibm/
# if you prefer to keep the file locally, download it and use:
## set env vars needed for PECL install
ENV IBM_DB_HOME=/opt/ibm/clidriver
ENV LD_LIBRARY_PATH=/opt/ibm/clidriver/lib
# ENV IBM_DB_HOME=/opt/ibm/dsdriver
# ENV LD_LIBRARY_PATH=IBM_DB_HOME/lib
## install ibm_db2 drivers
RUN pecl install ibm_db2 pdo_ibm
RUN echo "extension=ibm_db2.so" > /usr/local/etc/php/conf.d/ibm_db2.ini
RUN echo "extension=ibm_db2.so" >> /usr/local/etc/php/php.ini
RUN echo "extension=pdo.so" >> /usr/local/etc/php/php.ini
RUN echo "extension=pdo_ibm.so" >> /usr/local/etc/php/php.ini
#
# RUN echo "ibm_db2.instance_name=db2inst1" >> /usr/local/etc/php/php.ini
index.php
<?php
...
$database = 'testdb';
$user = 'db2inst1';
$password = 'ChangeMe!';
$hostname = 'db2.rn.dk';
$port = 50000;
$conn_string =
"DRIVER={IBM DB2 ODBC DRIVER};DATABASE=$database;" .
"HOSTNAME=$hostname;PORT=$port;PROTOCOL=TCPIP;UID=$user;PWD=$password;";
$conn = db2_connect($conn_string, '', '');
if ($conn) {
echo "Connection succeeded.\n";
db2_close($conn);
} else {
echo "<p><b>Using ibm_db2 extension:</b></p>";
echo "<p><u>Connection failed:</u></p>";
echo "<p>Error: ".db2_conn_error()."<br />";
echo db2_conn_errormsg()."</p>";
}
?>
Is there something I'm missing regarding the setup, that isn't documented anywhere?
Best regards,
Thomas

Can't connect to Postgres database using PHP PDO and Docker

I am running a Docker app that is built on three images: php:7.4-fpm, nginx:stable-alpine and postgres:alpine.
I was previously attempting to use the image php:7.4-fpm-alpine, but apparently it does not come with the Postgres PDO driver, which was causing a could not find driver error. This post explains more about that, and how to fix it. I followed the steps in that post, including creating a Dockerfile for my PHP FPM service (though I did not create a PHP CLI service), and that remedied my driver issues. However, I am now getting the following error when I try to connect to my PSQL database using PDO:
SQLSTATE[08006] [7] could not connect to server: Connection refused Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 6432?
I know my database is running (on port 6432) because I can access it from my terminal and from Positco, and have created tables after my Docker app was created. I also tried to connect to a database on port 5432 (through which my Postgres desktop app is running), but that did not work either. I also tried to restart my Postgres container, but that did not help.
Here is my PHP:
class Database {
private $connection;
private static $options = array(
PDO::ATTR_EMULATE_PREPARES => FALSE,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
public function __construct() {
try {
$dsn = 'pgsql:host=localhost;port=6432;dbname=db_my_test_app';
$username = 'root';
$password = 'secret';
$connection = new PDO($dsn, $username, $password, self::$options);
$this->connection = $connection;
return $connection;
} catch (PDOException $e) {
exit($e->getMessage());
}
}
}
$database = new Database();
...and my docker-compose.yml file:
version: '3'
networks:
my_test_app:
services:
# nginx
nginx-service:
image: nginx:stable-alpine
container_name: nginx-container
ports:
- "8080:80"
volumes:
- ./app:/var/www/project
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php-fpm-service
- postgres-service
networks:
- my_test_app
# php
php-fpm-service:
build:
context: .
dockerfile: ./php-fpm/Dockerfile
container_name: php-fpm-container
ports:
- "9000:9000"
working_dir: /var/www/project
volumes:
- ./app:/var/www/project
networks:
- my_test_app
# postgres
postgres-service:
image: postgres:alpine
container_name: postgres-container
ports:
- "6432:5432"
volumes:
- ./postgres:/var/lib/postgresql/data
restart: always
environment:
POSTGRES_USER: root
POSTGRES_PASSWORD: secret
POSTGRES_DB: db_my_test_app
networks:
- my_test_app
...and the PHP service Dockerfile (from the aforementioned site):
FROM php:7.4-fpm
RUN apt-get update && apt-get install -y libpq-dev
RUN docker-php-ext-install pdo pdo_pgsql pgsql
RUN ln -s /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
RUN sed -i -e 's/;extension=pgsql/extension=pgsql/' /usr/local/etc/php/php.ini
RUN sed -i -e 's/;extension=pdo_pgsql/extension=pdo_pgsql/' /usr/local/etc/php/php.ini
You are configuring docker under the default network mode: bridge. In order for the php-fpm-service to be able to access the postgres-service you need to make the following modifications:
In the docker-compose.yml file you'll need to add depends_on to php-fpm-service
# php
php-fpm-service:
build:
context: .
dockerfile: ./php-fpm/Dockerfile
container_name: php-fpm-container
ports:
- "9000:9000"
working_dir: /var/www/project
volumes:
- ./app:/var/www/project
networks:
- my_test_app
depends_on:
- postgres-service
In your PHP config, you need modify localhost to postgres-service and using port 5432:
$dsn = 'pgsql:host=postgres-service;port=5432;dbname=db_my_test_app';

Why PHP docker container can't lookup the hostname of the MYSQL container?

I have created and linked php-apache container with MYSQL container. But when I try to establish connection using PDO from a php file I got the error. Does anybody know how it could be fixed ? Thanks.
PDO error:
Fatal error: Uncaught PDOException: PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Name or service not known in /var/www/html/index.php:3 Stack trace: #0 /var/www/html/index.php(3): PDO->__construct('mysql:host=mysq...', 'root', 'root') #1 {main} Next PDOException: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known in /var/www/html/index.php:3 Stack trace: #0 /var/www/html/index.php(3): PDO->__construct('mysql:host=mysq...', 'root', 'root') #1 {main} thrown in /var/www/html/index.php on line 3
My directory structure:
.
├── mysql
├── php
| └── Dockerfile
├── src
| └── index.php
└── docker-compose.yml
Content of my index.php:
$connection = new PDO('mysql:host=mysql-db,dbname=app', 'root', 'root');
PHP Dockerfile:
FROM php:7.3.3-apache
RUN docker-php-ext-install -j$(nproc) pdo_mysql
docker-compose.yml:
version: '3'
services:
apache-php:
build:
./php
volumes:
- ./src:/var/www/html
ports:
- "8080:80"
depends_on:
- mysql-db
links:
- mysql-db
mysql-db:
image: mysql:5.7
ports:
- "3306:3306"
volumes:
- /mysql:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: app
First, you don't need the links: that will be done automatically since both services are in the same network.
Second, depends_on will not wait until the MySQL server is up and running and there is a chance the PHP service starts communicating before it is ready and that is why you receive this error.
In such cases, IT is better to implement a "wait for" functionality for your PHP service.
for that, you need to add an entry point to your PHP service and code like this
docker file
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
docker-entrypoint.sh
#!/bin/sh -e
until nc -vz mysql-db:3306 > /dev/null; do
>&2 echo "mysql-db:3306 is unavailable - sleeping"
sleep 2
done
>&2 echo "mysql-db is up"
exec "YOUR COMMAND"
exit 0
I had 2 issues doing this:
1) php:apache images need a lot of work to run php applications, it's better to just make your own, I did mine from ubuntu 18:04 image
2) I don't recall why, but mysql needs to be set to allow mysql_native_passwords in order to work with (in my case) php
Here's the docker-compose file I did for an test in class (thus the tag called examen)to share my web app:
version: '3'
services:
app:
image: gnomejodas/httpd-php:examen
ports:
- 80:80
volumes:
- ./src:/var/www/html
links:
- db
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
volumes:
- ./db:/var/lib/mysql
PD. I'm a super newbie developer (still studying), please go easy on me.
EDIT. If you make your own image, dont forget CMD apachectl -D FOREGROUND so your apache service starts when you run the container.
After all, find out that in my php code I have a comma after host definition, instead of semicolon. My apologizes.

61SQLSTATE[HY000] [2002] Connection refused in Docker Container PHP/Apache

I have recently switched from XAMPP to Docker for PHP Development and have managed to get my project running. The project was running fine on XAMPP, but for whatever reason the database kept on getting corrupt, hence the switch to Docker. This question has probably been asked before, but i have not been able to find an answer for it so far.
I have a login page, from where i submit the data to a php script, which makes a connection with the database and in that part, it runs into an exception:
61SQLSTATE[HY000] [2002] Connection refused61SQLSTATE[HY000] [2002] Connection refused
Warning: Cannot modify header information - headers already sent by (output started at /var/www/inc/cDBConnection.inc.php:61)
I have a docker-compose.yml file:
version: "3.2"
services:
php:
build: './php/'
networks:
- backend
volumes:
- ./project/:/var/www/html/
- ./inc/:/var/www/inc/
apache:
build: './apache/'
depends_on:
- php
- mysql
networks:
- frontend
- backend
ports:
- "8080:80"
volumes:
- ./project/:/var/www/html/
mysql:
image: mysql:5.6.40
ports:
- "3306:3306"
volumes:
- ./db:/var/lib/mysql
networks:
- backend
environment:
- MYSQL_ROOT_PASSWORD=password
networks:
frontend:
backend:
A Dockerfile in the apache folder:
FROM httpd:2.4.33-alpine
RUN apk update; \
apk upgrade;
# Copy apache vhost file to proxy php requests to php-fpm container
COPY apache.conf /usr/local/apache2/conf/apache.conf
RUN echo "Include /usr/local/apache2/conf/apache.conf" \
>> /usr/local/apache2/conf/httpd.conf
A Dockerfile in the php folder:
FROM php:7.2.7-fpm-alpine3.7
RUN apk update; \
apk upgrade;
RUN docker-php-ext-install pdo pdo_mysql mysqli
the DBConnection.php:
$this->_config = $databaseConfig;
$dsn = "" .
$this->_config['driver'] .
":host=" . $this->_config['host'] .
";dbname=" . $this->_config['dbname'];
try {
$this->dbc = new PDO( $dsn, $this->_config[ 'username' ], $this->_config[ 'password' ] );
} catch( PDOException $e ) {
echo __LINE__.$e->getMessage(); // here i run into this exception
}
I assume i'm missing some extension in the dockerfile, but if i log in through a mysql query browser, i am able to log in as root user. For the project i have another user, which i created with:
CREATE USER 'sec_user'#'localhost' IDENTIFIED BY 'password';
GRANT SELECT, INSERT, UPDATE ON `project`.* TO 'sec_user'#'localhost';
when i tried to log in with this user, i got an error "access denied", so i followed checked with:
SELECT user, host FROM mysql.user;
UPDATE mysql.user SET host='%' WHERE user='sec_user';
FLUSH PRIVILEGES
and the login worked with the query browser but on the frontend I'm unable to get in. Does anyone know what the problem here is?
I found the solution to this issue. The credentials are passed on through the environment variables and connecting to localhost or 127.0.0.1 will not work.
the credentials should be in the dockerfile:
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=test_db
- MYSQL_USER=sec_user
- MYSQL_PASSWORD=password
these are then accessed in the DBConnection.php like this:
'host' => "mysql", //this is from the dockerfile, docker does the mapping for you
'port' => '3306',
'dbname' => $_ENV["MYSQL_DATABASE"],
'username' => $_ENV["MYSQL_USER"],
'password' => $_ENV["MYSQL_PASSWORD"]
and succesfully connected!

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?

Categories