Zelf
Zelf

Reputation: 2250

PHP app cannot connect to docker mysql container at 127.0.0.1

Mysql is in it's own docker-compose.yml as I want a mysql server up and running that any other php application can connect to. So I do not have php and mysql in the same docker-compose.yml. From the php application, I can connect to mysql if I use the mysql container's gateway ip address by looking it up and then hard coding it into the php application. docker inspect mysql-db. But docker will change that 172... ip address each time mysql restarts so that is not ideal for development.

I can connect to mysql via mysql -h 127.0.0.1 no problem, but from the php application if I try to use 127.0.0.1 I get connection refused. I can only connect if I use the 172... gateway ip address.

How do I get the mysql container listening for connections from the host to 127.0.0.1?

docker-compose.yml for mysql

version: "3"

services:
  mysql:
    container_name: mysql-db
    image: mysql
    build:
      dockerfile: Dockerfile
      context: ./server/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=admin
    volumes:
      - ./data/mysql:/var/lib/mysql
    ports:
      - 3306:3306

docker-compose.yml for php

version: "3"

services:
  nginx:
    container_name: nginx_myapp
    image: nginx
    build:
      dockerfile: Dockerfile
      context: ./server/nginx
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./app:/var/www/html
    networks:
      - myapp
  php:
    container_name: php_myapp
    image: php:7.3-fpm
    build:
      dockerfile: Dockerfile
      context: ./server/php-fpm
    environment:
      CI_ENV: development
    volumes:
      - ./app:/var/www/html
    networks:
      - myapp

networks:
  myapp:

Upvotes: 4

Views: 2890

Answers (3)

Rajon Kobir
Rajon Kobir

Reputation: 173

I coudn't allow "localhost" or "127.0.0.1" as the DB_HOST in .env of my Laravel app. But successfully done other settings in docker-compose.yml :

  db:
    image: mysql:latest
    container_name: shadibari-mysql
    restart: always
    environment:
    #   MYSQL_HOST: 127.0.0.1
    #   MYSQL_ROOT_HOST: 127.0.0.1
    #   MYSQL_UNIX_PORT: 3306
    #   MYSQLX_UNIX_PORT: 3306
      MYSQL_ALLOW_EMPTY_PASSWORD: true
      MYSQL_ROOT_PASSWORD:
      MYSQL_DATABASE: shadibari
      MYSQL_USER: shadibari
      MYSQL_PASSWORD:
    volumes:
      - db_data:/var/lib/mysql
    ports:
      - "3306:3306" # db port
    # extra_hosts:
    #   - localhost:127.0.0.1
    networks:
      - laravel

So, in my case I had to use "DB_HOST=shadibari-mysql" in .env :

DB_CONNECTION=mysql
# DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=shadibari
DB_USERNAME=root
DB_PASSWORD=

# docker starts
DB_HOST=shadibari-mysql
# docker ends

Upvotes: 0

Few solutions for you

1) you can duplicate mysql section in each file using same volume path, in that case when you start project you will have same databases

project1
version: "3.2"
services:
  mysql:
    volumes:
      - /var/mysql:/var/lib/mysql
  php:
    build:
      context: './php/'

project2
version: "3.2"
services:
  mysql:
    volumes:
      - /var/mysql:/var/lib/mysql
  php:
    build:
      context: './php/'

2) you can connect using host.docker.internal or macos (docker.for.mac.localhost) directly to your host machine more information here From inside of a Docker container, how do I connect to the localhost of the machine?

Upvotes: -1

Zeitounator
Zeitounator

Reputation: 44615

127.0.0.1 is the loopback address. It points to localhost. In the context of docker, localhost is the container itself. There is no db running on your php container so the connection will never succeed.

What you need to do is to configure the default network in you mysql compose file so that you will predictably control its name for later convenience (else it will be calculated from your compose project name which could change if you rename the containing folder...):

Important note: for the below to work, you need to use compose file version >= 3.5

---
version: '3.7'
#...
networks:
  default:
    name: shared_mysql

You can now use that shared_mysql network as external from any other compose project.

version: '3.7'

services:
  nginx:
    #...
    networks:
      - myapp
  php:
    #...
    networks:
      - myapp
      - database

networks:
  myapp:
  database:
    external: true
    name: shared_mysql

You can then connect to mysql from your php container using the service name mysql (e.g. mysql -h mysql -u user -p)

Reference: https://docs.docker.com/compose/networking/

Upvotes: 6

Related Questions