Connecting the container to MariaDB on the host

Hello,
I have a Laravel project that connects to a MariaDB database. I don’t want to use a MariaDB container. I have installed MariaDB on the host and added the following line to the /etc/mysql/mariadb.conf.d/50-server.cnf file:

bind-address = 0.0.0.0

MariaDB is running on the host:

# netstat -tulnp | grep 3306
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      3172972/mariadbd 

I edited the .env file as follows:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_db
DB_USERNAME=root
DB_PASSWORD=123456

I also changed the database.php file of the Laravel project as follows:

 'mariadb' => [
            'driver' => 'mariadb',
            'url' => env('DB_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'laravel_db'),
            'username' => env('DB_USERNAME', 'root'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => env('DB_CHARSET', 'utf8mb4'),
            'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

The compose file looks like this:

services:
  frontend:
    container_name: frontend
    build:
      context: /home/dev/frontend
      dockerfile: Dockerfile
    environment:
      - NODE_ENV=development
      - CHOKIDAR_USEPOLLING=true  
      - WATCHPACK_POLLING=true   
    volumes:
      - /home/dev/frontend:/app
      - /app/node_modules          
    ports:
      - "127.0.0.1:3000:3000"              
    networks:
      - app_network
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M

  # Laravel Backend
  backend:
    build:
      context: /home/dev/portal
      dockerfile: Dockerfile
    container_name: backend
    entrypoint: ["/usr/local/bin/entrypoint.sh"]
    command: ["php-fpm"]
    environment:
      APP_ENV: local
      APP_DEBUG: "true"
      DB_HOST: host.docker.internal
      DB_PORT: 3306
      DB_DATABASE: laravel_db
      DB_USERNAME: root
      DB_PASSWORD: 123456
      XDEBUG_CONFIG: "client_host=host.docker.internal client_port=9003"
    volumes:
      - /home/dev/portal:/var/www
    networks:
      - app_network
    ports:
      - "9000:9000"
    extra_hosts:
      - "host.docker.internal:host-gateway"

networks:
  app_network:
    driver: bridge

After these settings, I ran the containers and connected to the backend container:

# docker exec -u root -it backend bash
#
# nc HOST_IP -v 80
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Connected to 172.20.2.58:80.
#
# nc HOST_IP -v 3306
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: No route to host.

As you can see, from inside the container I can connect to port 80 which is for Nginx, but I can’t connect to MariaDB.

Which part of the settings is wrong?

Thank you.

at a guess… have you got a firewall running on the container (or host? i’m lost) ?

Also if the container’s reaching out for the database, is 127.0.0.1 correct? Wouldnt that just reach the container?

:thinking: Those don’t look right. You’re using env() so why would you be supplying a 2nd argument to it if this should be getting the values from the environment variables?

according to Laravel’s documentation, the second parameter is a default. I suppose equivalent to env(key) ?? default

2 Likes

It would. Try connecting to host.docker.internal instead

Hello,
Thank you so much for your reply.
There is no firewall. As you can see, MariaDB is running on address 0.0.0.0.

Hello,
I ran the following command from within the backend container:

# nc host.docker.internal -v 3306
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: No route to host.

Hello,
I used network_mode: host and the problem was fixed:

services:
  frontend:
    container_name: frontend
    build:
      context: /home/dev/frontend
      dockerfile: Dockerfile
    environment:
      - NODE_ENV=development
      - CHOKIDAR_USEPOLLING=true  
      - WATCHPACK_POLLING=true    
    volumes:
      - /home/dev/frontend:/app
      - /app/node_modules          
    ports:
      - "127.0.0.1:3000:3000"               
    networks:
      - app_network
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M

  # Laravel Backend
  backend:
    build:
      context: /home/dev/backend
      dockerfile: Dockerfile
    container_name: backend
    entrypoint: ["/usr/local/bin/entrypoint.sh"]
    command: ["php-fpm"]
    network_mode: host
    environment:
      APP_ENV: local
      APP_DEBUG: "true"
      DB_HOST: host.docker.internal
      DB_PORT: 3306
      DB_DATABASE: laravel_db
      DB_USERNAME: root
      DB_PASSWORD: 123456
      XDEBUG_CONFIG: "client_host=host.docker.internal client_port=9003"
      FRONTEND_URL: http://127.0.0.1:3000
    volumes:
      - /home/dev/backend:/var/www
    ports:
      - "9000:9000"
    extra_hosts:
      - "host.docker.internal:host-gateway"

My new problem is with PhpMyAdmin. I want PhpMyAdmin to connect to MariaDB on the host:

  phpmyadmin:
    image: phpmyadmin:latest
    container_name: phpmyadmin
    restart: unless-stopped
#    network_mode: host
    environment:
      PMA_HOST: host.docker.internal
      MYSQL_ROOT_PASSWORD: 123456
    ports:
      - "127.0.0.1:8080:80"
    extra_hosts:
      - "host.docker.internal:host-gateway"

When I enter my username and password, the following error is displayed:

mysqli::real_connect(): (HY000/2002): No route to host

Any idea?

I edited the compose file as below:

  phpmyadmin:
    image: phpmyadmin:latest
    container_name: phpmyadmin
    restart: unless-stopped
    environment:
      PMA_SOCKET: /run/mysqld/mysqld.sock
      PMA_HOST: 172.20.2.58
      MYSQL_ROOT_PASSWORD: 123456
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - /var/run/mysqld/mysqld.sock:/var/run/mysqld/mysqld.sock

The new Nginx configuration is as follows:

location /phpmyadmin/ {
        proxy_pass http://127.0.0.1:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Script-Name /phpmyadmin;

        # Add these critical headers:
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-Server $host;

        # Cookie path rewrite
        proxy_cookie_path / /phpmyadmin/;

        # Rest of your existing config...
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Buffer settings
        proxy_buffer_size 128k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;

        # Security headers
        add_header X-Frame-Options "SAMEORIGIN";
        add_header X-Content-Type-Options "nosniff";
        add_header X-XSS-Protection "1; mode=block";
    }

    # Redirect /phpmyadmin to /phpmyadmin/
    location = /phpmyadmin {
        return 301 /phpmyadmin/;
    }

And the problem is solved.

1 Like