Skip to content
Advertisement

How to solve Laravel cant connect with mysql through docker

Im trying to deploy my laravel app using docker. Then I created docker-compose.yml file and Dockerfile like below.

docker-compose.yml

version: "3.7"
services:
    app:
        build:
            args:
                user: sammy
                uid: 1000
            context: ./
            dockerfile: Dockerfile
        image: travellist
        container_name: travellist-app
        restart: unless-stopped
        working_dir: /var/www/
        volumes:
            - ./:/var/www
        networks:
            - travellist

    db:
        image: mysql:8.0
        container_name: travellist-db
        restart: unless-stopped
        environment:
            MYSQL_DATABASE: '${DB_DATABASE}'
            MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
            MYSQL_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ALLOW_EMPTY_PASSWORD: 1
            SERVICE_TAGS: dev
            SERVICE_NAME: mysql
        volumes:
            - ./docker-compose/mysql:/docker-entrypoint-initdb.d
        networks:
            - travellist

    nginx:
        image: nginx:alpine
        container_name: travellist-nginx
        restart: unless-stopped
        ports:
            - 8000:80
        volumes:
            - ./:/var/www
            - ./docker-compose/nginx:/etc/nginx/conf.d/
        networks:
            - travellist

networks:
    travellist:
        driver: bridge

Dockerfile

FROM php:7.4-fpm

# Arguments defined in docker-compose.yml
ARG user
ARG uid

# Install system dependencies
RUN apt-get update && apt-get install -y 
    git 
    curl 
    libpng-dev 
    libonig-dev 
    libxml2-dev 
    zip 
    unzip

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd

# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Create system user to run Composer and Artisan Commands
RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer && 
    chown -R $user:$user /home/$user

# Set working directory
WORKDIR /var/www

USER $user

And when I try docker-compose up, all the containers run with a any error. And also when I run docker-compose ps, it shows like this,

      Name                    Command               State                  Ports
------------------------------------------------------------------------------------------------
travellist-app     docker-php-entrypoint php-fpm    Up      9000/tcp
travellist-db      docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp
travellist-nginx   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:8000->80/tcp,:::8000->80/tcp

But, when laravel application, tries to connect with mysql, it doesnt happens. And even I cant connect using TablePlus, it shows this.

Lost connection to MySQL server at 'waiting for initial communication packet', system error: 10060

And sometimes, I get like below,

SQLSTATE[HY000] [1045] Access denied for user 'root'@'192.168.48.3' (using password: YES)

How can I fix this ??

Advertisement

Answer

Since you’re networking the services, you only need to expose the port 3306/tcp (this is the default port mysql serves). This makes it inaccessible from 0.0.0.0 but accessible from your nginx and app container.

I have also added the correct volume to persist data (which I am assuming is what you’re trying to do). I moved mysql to latest – feel free to rollback or stick to 8 if you really? need too.

db:
  image: 'mysql:latest'
  restart: 'unless-stopped'
  expose:
    - '3306'
  environment:
    - 'MYSQL_RANDOM_ROOT_PASSWORD=true'
    - 'MYSQL_DATABASE=${DB_DATABASE}'
    - 'MYSQL_USER=${DB_USER}'
    - 'MYSQL_PASSWORD=${DB_PASSWORD}'
    - 'MYSQL_ALLOW_EMPTY_PASSWORD=true'
  volumes:
    - 'laravel-database:/var/lib/mysql/'
  networks:
    - 'travellist'

volumes:
  laravel-database:

Further reading can be found on the Docker hub under mysql.

Inside your Laravel .env, you should connect to the container via its DNS.

DB_HOST=db

If you want to connect to this container externally, you’ll need to bind the port to the server. Do so by replacing expose with the following:

ports:
  - '3306:3306'
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement