7

I have an issue connecting to mysql running in the local machine in my DockerFile i have mentioned

FROM php:7
RUN apt-get update -y && apt-get install -y openssl zip unzip git
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN docker-php-ext-install pdo mbstring pdo_mysql
WORKDIR /home
COPY . /home
RUN composer install --ignore-platform-reqs

CMD php artisan serve --host=0.0.0.0 --port=8081
EXPOSE 8081

and this in my .env configuration

DB_HOST=localhost
DB_DATABASE=databasename
DB_USERNAME=root
DB_PASSWORD=testpassword

I have very less clue about where it is failing. Do i need to install mysql for Docker container also?

Divyesh pal
  • 952
  • 1
  • 11
  • 17
  • there is no reference for mysql in that docker file? – mrhn May 27 '19 at 07:19
  • can you share the `docker-compose.yml` – Efrat Levitan May 27 '19 at 07:32
  • hi i don't have docker-compose.yml i am writing only dockerfile for the service as there is only one service to run. also over the same instance i have mysql running but that is not in docker it is installed in the machine itself – Divyesh pal May 27 '19 at 07:46
  • Possible duplicate of [From inside of a Docker container, how do I connect to the localhost of the machine?](https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach) – David Maze May 27 '19 at 10:05

4 Answers4

18

A much simpler solution (for Mac OSX & Docker for Windows) is to replace the host address from localhost to host.docker.internal

DB_HOST=host.docker.internal
DB_DATABASE=databasename
DB_USERNAME=root
DB_PASSWORD=testpassword

Basically the DNS namehost.docker.internal will resolves to the internal IP address used by the host.

NB: If you have changed your address to host.docker.internal but you still receive connection refused error, it’s most probably because MySQL is currently configured to only listen to the local network.

To resolve that, please update the value of the bind_address to 0.0.0.0 in your my.cnf configuration file.

eliarms
  • 551
  • 4
  • 6
  • Wow, That solve my problem. I did not know about host.docker.internal could actually connect to the localhost. – Mohammad.Kaab Dec 12 '20 at 09:21
  • great man, that is solution for dockers running on mac – iWizard Mar 05 '21 at 15:05
  • While other solutions like "localhost, 127.0.0.1 or local IP" causes conflicts for database migration, this one is valid for Windows 11 as well. Great solution. – Melih Jul 15 '23 at 18:34
3

you are trying to connect to mysql in localhost, which is (surprisingly) the reference to the local host. since its a relative address, inside the container it is being resolved as the container own address, and no mysql is awaiting you there... so to solve it - just give it your real host ip instead of localhost or 127.0.0.1.

step 1 - fix .env file:

DB_HOST=<your_host_ip> #run `ifconfig` and look for your ip on `docker0` network
DB_DATABASE=databasename
DB_USERNAME=laravel_server #not root, since we are going to allow this user remote access.
DB_PASSWORD=testpassword

step 2 - create dedicated user:

open your mysql: mysql -u root -p, give your root password, and run the following:

CREATE USER 'laravel_server'@'%' IDENTIFIED BY 'testpassword';
GRANT ALL PRIVILEGES ON databasename.* TO 'laravel_server'@'%'; 
FLUSH PRIVILEGES;

we created the user and gave it the permissions.

step 3 - open mysql to remote access:

we have to make it listening on all interfaces and not just localhost and therefore we run:

sudo sed 's/.*bind-address.*/bind-address=0.0.0.0/' /etc/mysql/mysql.conf.d/mysqld.cnf

(you will be prompted for password. this command is just replacing the line in mysql configuration file)

step 4 - updating:

  1. in the project directory: php artisan config:cache
  2. service mysql restart

then docker build and run a new container again. it should work for you.

Efrat Levitan
  • 5,181
  • 2
  • 19
  • 40
  • hi i tried putting my public ip in the environment but still it is failing to connect – Divyesh pal May 27 '19 at 09:56
  • SQLSTATE[HY000] [2002] No such file or directory (SQL: select * from `mdk_services_types` where `service_name` like %diabetic-care% limit 1) – Divyesh pal May 27 '19 at 10:17
  • i am getting no such file or directory found – Divyesh pal May 27 '19 at 10:17
  • @Divyeshpal make sure you dont have any `DB_SOCKET` env variable. also list here your `config/database.php` file and i will do my best to help – Efrat Levitan May 27 '19 at 10:23
  • Hey thanks for the response please find my database.php : 'mysql' => [ 'driver' => 'mysql', 'read' => [ 'host' => env('DB_HOST', 'localhost'), ], 'write' => [ 'host' => env('DB_HOST', 'localhost') ], 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', ] – Divyesh pal May 27 '19 at 11:09
  • after providing my public ip of machine in env i facing the Connection timeout error – Divyesh pal May 27 '19 at 11:10
  • you have to allow remote connections to mysql. to do that, change `bind_address` in the `/etc/mysql/mysql.conf.d/mysqld.cnf` file from `127.0.0.1` to `0.0.0.0`, and allow access to your user. – Efrat Levitan May 27 '19 at 13:33
  • hey @Divyeshpal i edited my answer. do you mind trying it and tell me if its working? – Efrat Levitan May 27 '19 at 18:02
  • Hi @Efrat thank you for so much support i resolved the issue by setting the bind address it is working fine! you effort is really appreciable thanx! – Divyesh pal May 28 '19 at 13:24
0

I see two options -

  1. Use the private IP of your docker host i.e where mysql server is running.

  2. Use the host network mode while running container in case you want to use localhost.

    docker container --net=host ...

vivekyad4v
  • 13,321
  • 4
  • 55
  • 63
0

In my case (Ubuntu 20.04 Desktop), I had MariaDB already running and using port 3306. So when the app inside the docker container was trying to start MySQL that was inside the container it failed because it was trying to listen to an already used port. I switched off the already-running MariaDB using the command below :

sudo systemctl stop mariadb.service

Then tried starting the docker app. It ran successfully because port 3306 was now free and used by MySQL inside the container. But since I intend to use both of them, a much more permanent solution would be to configure either of the Database systems i.e the one inside the docker container or the one outside the docker container to use a different port other than the default 3306.