Can't call my Laravel API from the Node.js container but I can call it from Postman

I have the following 4 containers:

  1. php-fpm for Laravel API backend
  2. node.js container for the Next.js frontend
  3. nginx container
  4. mysql container

I am able to call the Laravel API and get the correct JSON data from Postman using http://localhost:8088/api , but when I try from the Node container, I get FetchError: request to http://localhost:8088/api/ failed, reason: connect ECONNREFUSED 10.0.238.3:8088. I am not sure if it’s the nginx configuration issue, or docker-compose.yml configuration issue.
I also tried to call the API from the node container using several other options (none of them worked):

  1. http://php:8088/api/
  2. http://localhost:8088/api
  3. http://php:9000/api/ - gives a different error: FetchError: request to http://php:9000/api/products/ failed, reason: read ECONNRESET

This is the docker-compose.yml:

networks:
    laravel:
        driver: bridge

services:
    nginx:
        image: nginx:stable-alpine
        container_name: nginx
        ports:
            - "8088:80"
        volumes:
            - ./laravel-app:/var/www/html 
            - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
        
        depends_on:
            - php
            - mysql           
            - node             
        networks:
            - laravel
            
    mysql:
        image: mysql
        container_name: mysql
        restart: unless-stopped
        tty: true
        ports:
            - "4306:3306"
        volumes:
            - ./mysql:/var/lib/mysql
        environment:
            MYSQL_DATABASE: laravel          
            MYSQL_ROOT_PASSWORD: password
            SERVICE_TAGS: dev
            SERVICE_NAME: mysql            
        networks:
            - laravel
                     
    
    php:
        build:
            context: .
            dockerfile: Dockerfile
        container_name: php
        volumes:
            - ./laravel-app:/var/www/html
        ports:
            - "9000:9000"
        networks:
            - laravel

    node:
        build:
            context: ./nextjs
            dockerfile: Dockerfile
        container_name: next
        
        volumes:
            - ./nextjs:/var/www/html
        ports:
            - "3000:3000"
            - "49153:49153"

        networks:
            - laravel

And this is the nginx default.conf file:

server {
    listen 80;
    index index.php index.html;
    server_name localhost;
    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/html/public;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {        
        try_files $uri = 404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
    
}

This works from the host machine, because of the ports: "8088:80" mapping of your Nginx container, which publishes the Nginx port 80 to port 8088 on the host machine. This mapping is not used for container-to-container traffic.

In the Node container, localhost is that container.

You were close with your other tries though; to access the Nginx container from another container, use the container’s internal port: http://nginx:80/api or simply http://nginx/api.

However, your Nginx will effectively delegate .php requests to fastcgi_pass php:9000, so I’d expect http://php:9000/api/ to work too. But apparently:

Hmmm, are you sure you requested /api and got an error about /api/products/? (If yes: is some redirecting happening?)

I think we’d need to know about the PHP container. Or maybe you need to add index.php, like http://php:9000/api/products/index.php.

Aside, is the Node container running any JavaScript, so: does the Node container need to access the API from the container? If it’s only the user’s browser on the host machine that needs to access the API, then http://localhost:8088/api from the frontend’s JavaScript should work, just like Postman running on the host machine. (In that case the Node container would actually only serve static files, without running any JavaScript itself. That’s typically something that Nginx could do better. But unrelated to your question.)

2 Likes

Also posted on docker - Can't call my Laravel API from the Node.js container but I can call it from Postman - Stack Overflow It seems I wasted my time trying to help. Please don’t waste people’s time by posting on multiple places, or for the very least provide links to the other places you asked, and keep all places updated with any solution you get. Thanks.

1 Like

It’s not wasting time , because every one can show different approach and so I can collect more information. For you it’s wasting time only because you found the post on Stack Overflow, otherwise you wouldn’t even know.

If a tree falls in a forest and no one is around to hear it, does it make a sound?

Basically, every time you answer people and help them for free on forums is “wasting time”, although you know it’s not correct, because some people love to help others - like you, I believe, and for that I’m thankful.

(By the way, I also posted it on Reddit, but you didn’t find that one :wink:)

It is wasting time to me. Why would I bother to post answers that others may already have posted elsewhere, while the one asking the question doesn’t even bother to tell people about those other places? This is exactly what drives helpful people away from places like this.

So, did you point the readers on Reddit to the solutions you already got in the other places?

1 Like

Nope, there they did not answer so I deleted. So then I started posting “double posts”, but as you suggested, next time I should post in one website, and then refer to this website from other places and at the end post the solution

Also, the other way around also happened: That posts in Stack Overflow remained unanswered and I was answered here or in Reddit. Or that answers were not good enough or not correct in one place and were correct in the other

Aside, that’s also a good reason to keep things linked or in one place: so others can validate/improve answers others posted. (Especially true for people who try to get help through private messages.)

1 Like