4

I have docker installed on ubuntu machine and I'm trying to run a laravel app.

MySQL service has service_name: mysql in docker-compose.yml file and .env file has DB_HOST=mysql.

As I remember .env file should figure out that DB_HOST=mysql points to the mysql docker service IP. However this isn't happening and after running migrations I get:

Illuminate\Database\QueryException : SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution (SQL: SHOW FULL TABLES WHERE table_type = 'BASE TABLE')

First I ran docker-compose build, after which I ran docker-compose up -d and all of my 3 services are up and running.

If I extract the IP of MySQL service and use it in .env file like this:

DB_HOST=172.18.0.2

I can then run migrations successfully and in this case everything works fine.

However, I consider this as bad practice since IP address could be changed if MySQL service is restarted. Am I missing something here, why using service_name in my .env file for DB_HOST fails resolving db host name?

docker-compose.yml:

version: '3'

networks:
  laravel:

services:
  nginx:
    image: nginx:stable-alpine
    container_name: nginx
    ports:
      - "8080:80"
    volumes:
      - ./src:/var/www/html
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php
      - mysql
    networks:
      - laravel
  mysql:
    image: mysql:5.7.22
    container_name: mysql
    restart: unless-stopped
    tty: true
    ports: 
      - "3306:3306"
    volumes: 
      - ./mysql:/var/lib/mysql
    environment:
      MYSQL_DATABASE: laraone
      MYSQL_USER: laraone_user
      MYSQL_PASSWORD: secret
      MYSQL_ROOT_PASSWORD: secret
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    networks:
      - laravel
  php:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: php
    volumes: 
      - ./src:/var/www/html
    depends_on:
      - mysql
    ports:
      - "9000:9000"
    networks:
      - laravel

.env:

APP_NAME=Laraone
APP_ENV="local"
APP_KEY=base64:PMwGrcSu2ioPEj75dv5gcdWAogESOtt8UCr/gs0nOtw=
APP_DEBUG=true
APP_URL=http://localhost:8080

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laraone
DB_USERNAME=laraone_user
DB_PASSWORD=secret

BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=

MAIL_FROM_ADDRESS=noreply@example.com
MAIL_FROM_NAME="${APP_NAME}"

MAIL_SENDMAIL="/usr/sbin/sendmail -bs"
J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
themystery
  • 43
  • 1
  • 1
  • 6
  • 1
    `DB_HOST=mysql` This should probably be `localhost` or `127.0.0.1`. It needs the hostname or IP in order to find the server. – aynber Jan 22 '20 at 15:09
  • 1
    @aynber That’s wrong in a Docker context: `localhost` is almost always “this container”. (But if the question is about trying to run migrations from the host with the stack otherwise running in Docker, `localhost` would be right then.) – David Maze Jan 22 '20 at 15:13
  • 1
    @aynber I would disagree with that. `DB_HOST` should be set to `mysql` as that is the service name of the container in the `docker-compose.yml` file. I run a laravel app and that is exactly how it is configured. I feel like something is wrong with the networks but can't see why. What i'd do is `docker-compose exec php bash` and `ping mysql` or `telnet mysql 3306`. You may need to download and install either of those packages within the container. – leeman24 Jan 22 '20 at 15:16
  • @aynber If I use localhost then I get: `Illuminate\Database\QueryException : SQLSTATE[HY000] [2002] No such file or directory (SQL: SHOW FULL TABLES WHERE table_type = 'BASE TABLE')` If I use 127.0.0.1 migrations are executed without any exceptions and afterwards when I load the app in browser I get 404 on all routes. In this case database host is recognised but not correctly connected to the laravel app. – themystery Jan 22 '20 at 15:18
  • 1
    Thanks, @leeman24, for the explanation. I use homestead, not Docker, so HOST is localhost or an IP for me. I didn't realize Docker set a mysql hostname. – aynber Jan 22 '20 at 15:21
  • @leeman24 I did what you stated above and this is the result: `--- mysql ping statistics --- 63 packets transmitted, 63 received, 0% packet loss, time 486ms rtt min/avg/max/mdev = 0.070/0.106/0.472/0.051 ms` I'm still unsure why mysql container_name doesn't get resolved in env file – themystery Jan 22 '20 at 16:03
  • 1
    @themystery, Agreed that is odd behaviour. This probably won't help but exec into php and run `echo $DB_HOST`. Maybe your `.env` file is not being applied properly although when you said you changed the value it gave different behaviour. – leeman24 Jan 22 '20 at 16:47
  • @leeman24 Thanks for this advice. I get an odd response when I do `echo $DB_HOST`, I uploaded it from my terminal here > https://prnt.sc/qre0wm It looks like $DB_HOST doesn't get any value, and I'm still unsure why is this happening – themystery Jan 22 '20 at 17:30
  • Actually sorry, that is not necessarily an indication that things are misconfigured. I moved my laravel project to Kubernetes and am defining those as environment variables. Where is that `.env` file? My laravel project running on docker we put it gets mounted under `/var/www/api/.env` where I think you should have it under `/var/www/html/.env` possibly. – leeman24 Jan 22 '20 at 17:36

5 Answers5

10

I think you try to run "php artisan migrate" command outside php docker container.

You should run php artisan migrate command inside php container.

Try following;

docker ps --> list running containers

docker exec -it <your_container_id> bash

and now you can run;

php artisan migrate

Edit: You can also write artisan command without entering container bash as following;

docker exec -i <your_container_id> php artisan migrate
Tuncay Elvanagac
  • 1,048
  • 11
  • 13
1

For anyone still wanting a dockerized Laravel enviroment, check out Laravel Sail. It lets you route commands to the docker instance easily with an alias sail. Like sail artisan migrate.

https://laravel.com/docs/8.x/sail

Laravel Sail is a light-weight command-line interface for interacting with Laravel's default Docker development environment. Sail provides a great starting point for building a Laravel application using PHP, MySQL, and Redis without requiring prior Docker experience.

Daniel Dewhurst
  • 2,533
  • 2
  • 21
  • 39
1

SOLUTION 1:

Always run docker ps to check if your ports are well mapped. below you can see what I mean.

enter image description here

to fix this you need to check if you have another instance of MySQL running with this port number and stop it or try a different port enter image description here

SOLUTION 2:

change your credentials to

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=root
DB_PASSWORD=

here is mysql yml enter image description here

Ejeh
  • 425
  • 5
  • 7
0

I resolved the issue by installing laravel app inside a php container. Simple 1-line command which helped me solve this problem: docker exec -it php php artisan app:install

themystery
  • 43
  • 1
  • 1
  • 6
0

Similar issue, with console command I created, with docker containers to mysql and php
(just entrypoint for dev runnig php artisan serve --host 0.0.0.0)
and I tried to run on host
php artisan my:console:command
which return :
SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution (SQL: select * from `mytable` limit 5)

By running :
docker exec -it myPhpContainerName php artisan my:console:command
it works fine

bcag2
  • 1,988
  • 1
  • 17
  • 31