Mysql - Docker: Connection issue - php

My docker-compose.yml looks like this:
version: '3.3'
services:
frontend:
build: frontend
container_name: yii-frontend
ports:
- 20080:80
volumes:
# Re-use local composer cache via host-volume
- ~/.composer-docker/cache:/root/.composer/cache:delegated
# Mount source-code for development
- ./:/app
networks:
- my-marian-net
backend:
build: backend
container_name: yii-backend
ports:
- 21080:80
volumes:
# Re-use local composer cache via host-volume
- ~/.composer-docker/cache:/root/.composer/cache:delegated
# Mount source-code for development
- ./:/app
networks:
- my-marian-net
db:
image: mysql:8.0
container_name: mysql8
command: --user=root --default-authentication-plugin=mysql_native_password
restart: always
environment:
- MYSQL_ROOT_PASSWORD=verysecret
- MYSQL_DATABASE=yii2advanced
- MYSQL_USER=yii2advanced
- MYSQL_PASSWORD=secret
ports:
- 6033:3306
networks:
- my-marian-net
networks:
my-marian-net:
driver: bridge
I get an error message:
'SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed:
nodename nor servname provided, or not known'
Solutions I have tried:
Ping from backend and frontend container to mysql8: docker exec -ti yii-frontend ping mysql8 (It works!)
Manually connect each container to the same network (my-marian-net) docker network connect my-marian-net mysql8 (same for each container)
I have connected into the mysql container and test connection there, it works.
I have connected from containers to mysql8 container MySQL service and it works.
So far no luck getting connected. In my code, I am using "db" as hostname since I am using bridge mode.
After trying different solutions, I have isolated the issue to a connection from
outside docker, Any suggestion?
I am using macOS Mojave. Docker version 19.03

The issue was simpler than I thought, from outside container "db" service does not exist, so no possibility to get connected.
In the future when I run console commands from local, I will change host in database connection to use localhost instead of "db" or get connected to the container itself and run them from inside.
Thanks to #Smankusors for the help.

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'

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:

Docker-Symfony-Mysql: SQLSTATE[HY000] [2002] Connection refused

So I am new to docker and this is the first project I have tried to run using it. I am running into the issue of my php-apache container is not able to connect to my mysql container, but only in the browser. I can do:
docker exec -it <php container id> bash
and then run
composer install
and all of the
php bin/console doctrine:<>
commands just fine with no database errors or connection problems. When I try to actually load up the site in my browser I am met with the "SQLSTATE[HY000] [2002] Connection refused" error. I am not really sure why this is the case and no results I have found on the web seem to work. Here are my files:
docker-compose.yml
version: '3'
services:
db:
restart: always
container_name: hcp-db
build:
context: ../
dockerfile: docker/db/Dockerfile
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
- MYSQL_DATABASE=symfony
- MYSQL_USER=root
- MYSQL_PASSWORD=password
volumes:
- db:/var/lib/mysql
expose:
- 3306
ports:
- "4306:3306"
application:
container_name: hcp-symfony
build:
context: ../
dockerfile: docker/Dockerfile
working_dir: /app
expose:
- 80
ports:
- 8000:80
depends_on:
- db
volumes:
- ../:/app
environment:
- SYMFONY_ENV=dev
- SYMFONY_DEBUG=1
volumes:
db:
parameters.yml
parameters:
database_driver: pdo_mysql
database_host: db
database_port: 3306
database_name: symfony
database_user: root
database_password: null
I am also able to connect to the database just fine through Sequel Pro while my container is running using the same credentials I provide in the parameters, but with the host as "127.0.0.1", which I find interesting.
Any help with what could be wrong would be much appreciated.
Sup, I can't comment yet to ask a bit more of details since I'm kind of new so I will take a wild guess and assume there is no issues on your app.
This kind of issue is usually related to firewall stuff. Docker does a lot of firewall configuration for us so we don't have to deal with the ufw or IP tables ourselves, but that also means that we need to specify how each container will interact with each other ourselves withing our docker compose file.
You have to specify that your app container links to the database container in order to allow hostnaming access since docker modify the container /etc/hosts file everytime a container starts so it maps each container current IP, like this:
services:
...
application:
...
depends_on:
- db
links:
- db
With that done, you just need to make sure your parameters file is configured correctly as #dbrumann pointed out, the database_password should contains your password and not a null value.
It is also a good practice to create a custom network for your docker project so you can have a nice private lan between your containers without being open to any other container using docker's default network, a custom network with defaults can do nicely, like this:
services:
db:
...
networks:
- my_project_network
application:
...
depends_on:
- db
links:
- db
networks:
- my_project_network
networks:
my_project_network:
You don't really need to expose your database port to the host for this to work but having it exposed makes development way easier when checking the database so just remember to remove the database container ports statement when going to production environment to avoid security issues.
Hope this helps, here is a link to docker network documentation in case you want to learn more: https://docs.docker.com/compose/compose-file/#network-configuration-reference

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

Console PHP script runs differently when executes through docker exec or through PhpStorm

I'm trying to run console run Doctrine 2's console script through the PhpStorm. Docker is set up as Deploy server.
If I run this:
$ docker exec container_name /var/www/vendor/bin/doctrine-module orm:schema-tool:create
it prints:
No Metadata Classes to process.
But when I run PHP Run/Debug configuration in PhpStorm:
File: /home/username/PhpstormProjects/proj/vendor/bin/doctrine-module
it prints:
docker://image_name/container_name /var/www/vendor/bin/doctrine-module
Fatal error: Uncaught PDOException: PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Name or service not known in /var/www/vendor/zendframework/zend-servicemanager/src/ServiceManager.php on line 765
Zend\ServiceManager\Exception\ServiceNotCreatedException: Service with name "doctrine.connection.orm_default" could not be created. Reason: An exception occured in driver: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known in /var/www/vendor/zendframework/zend-servicemanager/src/ServiceManager.php on line 765
Call Stack:
0.0001 349368 1. {main}() /var/www/vendor/doctrine/doctrine-module/bin/doctrine-module:0
0.0268 360480 2. include('/var/www/vendor/doctrine/doctrine-module/bin/doctrine-module.php') /var/www/vendor/doctrine/doctrine-module/bin/doctrine-module:4
0.9376 4076096 3. Zend\ServiceManager\ServiceManager->get() /var/www/vendor/doctrine/doctrine-module/bin/doctrine-module.php:61
0.9376 4076096 4. Zend\ServiceManager\ServiceManager->doCreate() /var/www/vendor/zendframework/zend-servicemanager/src/ServiceManager.php:200
Process finished with exit code 255
I checked that when PDO is creating it receives absolutely the same arguments
new PDO("mysql:host=db;port=3306;dbname=dbname", "user", "pass", [])
docker-compose.yml:
version: '2'
services:
nginx:
container_name: nginx
build:
context: .
dockerfile: DockerfileNginx
ports:
- "80:80"
depends_on:
- php
working_dir: /var/www
links:
- php
volumes:
- .:/var/www
links:
- db
php:
container_name: php
build:
context: .
dockerfile: DockerfilePhp
- db
volumes:
- .:/var/www
expose:
- "9000"
depends_on:
- db
db:
container_name: db
image: "mysql:5.6"
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: pass
MYSQL_DATABASE: dbname
MYSQL_USER: user
MYSQL_PASSWORD: pass
I had the same problem and I found out, that PHPStorm starts a new, dedicated Docker container for your PHP calls. So, all your docker-compose configuration is missing at this point.
I did the following:
start your Docker stack with compose
after that find your network name with docker network ls (see Cannot link to a running container started by docker-compose for help)
inside PHPStorm goto your preferences for your Docker container (Languages & Frameworks -> PHP -> PHPUnit: Docker container ...) and add a link to your db (something like: name = your_containter_name_1, alias = db) and change the network mode from bridge to your network name

Categories