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

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

Related

Cannot make request internally to my symfony application served on localhost:8000 [duplicate]

I have created an nginx container that is open to port 8080:80
so I could access it from the host.
it is connected to php fpm container that has an open port 9000:9000
nginx successfully runs with php.
My problem is that php tries to access localhost:8080
but the problem is that the php localhost:8080 is not valid, it needs to connect to the nginx container.
here is the error on my wordpress site:
you can see that something is funky there...
below I'll attach my docker-compose.yml
Downloading install package from http://localhost:8080/wp-content/themes/realtyspace/plugins/advanced-custom-fields-pro.zip…
Download failed. cURL error 7: Failed to connect to localhost port 8080: Connection refused
docker-compose.yml
version: '2'
services:
my-nginx:
build: .
volumes:
- ./../:/var/www/html
ports:
- "8080:80"
links:
- my-php
my-php:
build:
context: .
dockerfile: Dockerfile.php-fpm
volumes:
- ./../:/var/www/html
ports:
- "9000:9000"
links:
- my-mysql
my-mysql:
image: mariadb:5.5
volumes:
- /var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: wp
MYSQL_DATABASE: wp
MYSQL_USER: wp
MYSQL_PASSWORD: wp
Use docker's internal networking and configure php to access http://my-nginx:80.
localhost will resolve to the isolated IP of the php container itself, not that of the Docker host that's running everything. And trying to pass http://dockerhost:8080 will result in a non-portable docker-compose.yml and likely issues with iptables firewall and nat rules that are more trouble than they are worth. The value of using the v2 compose files is that you get an isolated network internal to Docker with DNS resolution of each of your containers to work with each other.

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.

Database connection from php container with host name "localhost" instead of container name

Our website-framework(s) are designed to work on both xampp and docker environments. We are recognizing our database hosts by host name/IP-address (dev, test, staging, live env). People who are working with xampp are using https://localhost, so they get the environment variable called Development. People who are working with docker are using https://docker as their host. They get the env-variable called Development/Docker. We need this differentiation because inside the php applications our xampp users are connecting to their mysql service with host localhost. Docker users have to connect via host called mysql (this is the container name of the mysql-service).
Because of the last occurred problems (not relevant to be mentioned here) we want a unique solution for both user-groups concerning the database connection: Docker users should be able to connect to their mysql service with host localhost.
docker-compose.yaml (shortened for better overview):
version: '2'
services:
#######################################
# PHP application Docker container
#######################################
app:
build:
context: .
dockerfile: Dockerfile.development
links:
- mail
- mysql
- redis
ports:
- "80:80"
- "443:443"
- "10022:22"
- "3307:3306"
volumes:
- ./app/:/app/
- ./:/docker/
cap_add:
- SYS_PTRACE
env_file:
- etc/environment.yml
- etc/environment.development.yml
environment:
- POSTFIX_RELAYHOST=[mail]:1025
#######################################
# MySQL server
#######################################
mysql:
build:
context: docker/mysql/
dockerfile: MariaDB-10.Dockerfile
ports:
- "3306"
volumes:
- mysql:/var/lib/mysql
env_file:
- etc/environment.yml
- etc/environment.development.yml
#######################################
# phpMyAdmin
#######################################
# /// #
#######################################
# Mail
#######################################
# /// #
#######################################
# Redis
#######################################
# /// #
# Volumes
volumes:
mysql:
phpmyadmin:
redis:
I tried a lot and played with the docker-compose but didn't find a solution for weeks. Tried with links, networks and so on. I think my docker skills are exhausted by now...
I also added to the mysql.conf:
bind-address = 0.0.0.0
Any ideas?
It is because of docker's networking structure.
docker creates 3 base interfaces. docker0 , host and none.
each container uses docker0 by default. then each container will have a virtual network interface for communicating between containers. so you can use your database with mysql address.
if you want to connect to database with address localhost you should config docker to use host network mode (you can do it by adding one line to defenition of your app service in docker compose file). it will be able to connect to every app which is running on your system. By the way you would loose communication with other container by their name. maybe you loose your connection with your redis (which is connected with redis address)
In this network mode, every dependency should be deployed or be exposed to your localhost.

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

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

Categories