Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Into's avatar
Level 1

Laravel Sail bridge network does not allow connections between containers

We have begun the process of breaking up our application into containers making use of Laravel Sail. As a first step, we separated out a part of the app called 'formulas' into its own container and wish to connect the two with a bridged network. Here are the docker-compose configs:

main

# For more information: https://laravel.com/docs/sail
version: '3'
services:
  laravel.test:
    build:
      context: ./vendor/laravel/sail/runtimes/8.1
      dockerfile: Dockerfile
      args:
        WWWGROUP: '${WWWGROUP}'
    image: sail-8.1/app
    ports:
      - '${APP_PORT:-80}:80'
    environment:
      WWWUSER: '${WWWUSER}'
      LARAVEL_SAIL: 1
      XDEBUG_IDEKEY: 'PHPSTORM'
      PHP_IDE_CONFIG: 'serverName=0.0.0.0'
      XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
      XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
    volumes:
      - '.:/var/www/html'
    networks:
      - sail
      - formulas_app-shared
    extra_hosts:
      - "host.docker.internal:host-gateway"
networks:
  sail:
  formulas_app-shared:
    external: true

formulas

version: '3'
services:
    laravel.test:
        build:
            context: ./vendor/laravel/sail/runtimes/8.1
            dockerfile: Dockerfile
            args:
                WWWGROUP: '${WWWGROUP}'
        image: sail-8.1/formulas
        container_name: formulas
        extra_hosts:
            - 'host.docker.internal:host-gateway'
        ports:
            - '${APP_PORT:-80}:80'
        environment:
            WWWUSER: '${WWWUSER}'
            LARAVEL_SAIL: 1
            XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
            XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
        volumes:
            - '.:/var/www/html'
        networks:
            - sail
            - app-shared
networks:
    sail:
    app-shared:
        driver: bridge

The "formulas" container is just a barebones API endpoint at this stage, but the URL http://localhost:3001/api/formulas/all should return a list of all formulas in the (shared, local) DB, which it does when the URL is entered into the browser. However, when I try to access that route with an Http request within the app like so:

Route::get('/formulas', function() {
    $endpoint       = 'http://localhost:3001/api/formulas/all';// env('FORMULA_API_HOST'). '/api/formulas/all';
    return Http::withOptions([
        'debug' => false,
    ])->get($endpoint); //json

});

I can only get this error - both through tinker and through the browser when I go to the URL localhost:8000/formulas:

cURL error 7: Failed to connect to localhost port 3001: Connection refused (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for http://localhost:3001/api/formulas/all
http://localhost:8000/formulas

Does anybody have any idea what I might be doing wrong? This is Windows and the containers are hosted within WSL2. I disabled my VPN and the Firewall, but still get the same error. The 'main' container simply cannot make an Http request to the other.

ETA: For what it's worth, I can make Http requests from within the app to, say, Google, so it is a problem with connecting to the other container, not an issue with making requests in general.

0 likes
5 replies
pmieleszkiewicz's avatar
Level 3

If I understand correctly you have 2 different repos with Laravel Sail and you want these 2 services to be in the same Docker network, right? If yes, then I tried to implement that few days ago and this is what I ended with.

Let's assume that we have 2 applications: one exposes REST API and second is consumer (client).

API:

docker-compose.yml

# For more information: https://laravel.com/docs/sail
version: '3'
services:
    api.local:
        build:
            context: ./vendor/laravel/sail/runtimes/8.1
            dockerfile: Dockerfile
            args:
                WWWGROUP: '${WWWGROUP}'
        image: sail-8.1/app
        extra_hosts:
            - 'host.docker.internal:host-gateway'
        ports:
            - '${APP_PORT:-80}:80'
        environment:
            WWWUSER: '${WWWUSER}'
            LARAVEL_SAIL: 1
            XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
            XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
        volumes:
            - '.:/var/www/html'
        networks:
            - my-network
        depends_on:
            - pgsql
            - redis
    pgsql:
        image: 'postgres:13'
        ports:
            - '${FORWARD_DB_PORT:-5432}:5432'
        environment:
            PGPASSWORD: '${DB_PASSWORD:-secret}'
            POSTGRES_DB: '${DB_DATABASE}'
            POSTGRES_USER: '${DB_USERNAME}'
            POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}'
        volumes:
            - 'sailpgsql:/var/lib/postgresql/data'
        networks:
            - my-network
        healthcheck:
            test: ["CMD", "pg_isready", "-q", "-d", "${DB_DATABASE}", "-U", "${DB_USERNAME}"]
            retries: 3
            timeout: 5s
    redis:
        image: 'redis:alpine'
        ports:
            - '${FORWARD_REDIS_PORT:-6379}:6379'
        volumes:
            - 'sailredis:/data'
        networks:
            - my-network
        healthcheck:
            test: ["CMD", "redis-cli", "ping"]
            retries: 3
            timeout: 5s
    mailhog:
        image: 'mailhog/mailhog:latest'
        ports:
            - '${FORWARD_MAILHOG_PORT:-1025}:1025'
            - '${FORWARD_MAILHOG_DASHBOARD_PORT:-8025}:8025'
        networks:
            - my-network
networks:
    my-network:
        name: my-network
        driver: bridge
volumes:
    sailpgsql:
        driver: local
    sailredis:
        driver: local

.env

# add this line, it should be the same as your service name in docker-compose.yml
APP_SERVICE=api.local

Client:

docker-compose.yml

# For more information: https://laravel.com/docs/sail
version: '3'
services:
    client.local:
        build:
            context: ./vendor/laravel/sail/runtimes/8.1
            dockerfile: Dockerfile
            args:
                WWWGROUP: '${WWWGROUP}'
        image: sail-8.1/app
        extra_hosts:
            - 'host.docker.internal:host-gateway'
        ports:
            - '${APP_PORT:-80}:80'
        environment:
            WWWUSER: '${WWWUSER}'
            LARAVEL_SAIL: 1
            XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
            XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
        volumes:
            - '.:/var/www/html'
        networks:
            - proxy
networks:
    proxy:
        external:
            name: my-network

.env

# add this line, it should be the same as your service name in docker-compose.yml
APP_SERVICE=client.local

And now the most important tip. You can't use http://localhost:3000 inside containers, because I assume that port 3000 is exposed outside containers. If you want to access API endpoint from client app you should call services by their names, e.g.

In client app

Route::get('/formulas', function() {
    $endpoint = 'api.local' . '/api/formulas/all'; // api.local is going to be translated to appropriate URL by Docker, it's the same as service name in docker-compose.yml in API
    return Http::withOptions([
        'debug' => false,
    ])->get($endpoint);
});
2 likes
Into's avatar
Level 1

@pmieleszkiewicz Thanks very much for your reply! Thanks for showing me your docker_compose files, it turns out that the way the shared network was configured was incorrect - which is strange because it was working just fine on my colleagues' Linux/Mac OS machines. I'm not sure what the function of APP_SERVICE is since it works without, but thanks for showing me how to configure the network and connect to the api correctly!

drewdan's avatar

With our Docker environment, to communicate with the machines in the internal network, we reference them by their name. For example, in our env file, our mysql host is mysql as that's the name of the machine in docker. Maybe as they are communicating internally, you need to make a request to:

http://formulas/api/formulas/all

Also, worth noting, although we have port forwards, so we can connect to our contains from our windows machines, the machines communicate internally on their internal ports. For example, we have Two MYSQL containers, one binds externally to 3307 and the other to 3306, but both bind interally to 3306, but when we use them in the network, we access them on their internal port, so both 3306.

Hope that helps!

1 like
Into's avatar
Level 1

@drewdan You're right, I can't just use localhost:3001 - thanks very much!

Please or to participate in this conversation.