Symfony + Docker, connection refused - php

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

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'

Mysql - Docker: Connection issue

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.

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

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

Categories