POST net::ERR_NAME_NOT_RESOLVED

Hello,
The docker-compose.yml file looks like this:

services:
  frontend:
    container_name: frontend
    build:
      context: /home/project/front-end
      dockerfile: Dockerfile
    ports:
      - "3000:3000"  # Only expose internally, Nginx will handle external access
    environment:
      - NODE_ENV=development
      - REACT_APP_API_URL=http://localhost/api  # Or similar, depending on your frontend framework
      - BUILDKIT_INLINE_CACHE=0
    depends_on:
      - db
      - backend
    networks:
      - app_network

  # PHP-FPM Service
  backend:
    build:
      context: /home/project/portal
      dockerfile: Dockerfile
    container_name: backend
    restart: unless-stopped
    environment:
      APP_ENV: local
      APP_DEBUG: "true"
      DB_HOST: db
      DB_PORT: 3306
      DB_DATABASE: laravel_db
      DB_USERNAME: laravel_user
      DB_PASSWORD: secret
#    volumes:
#      - ./:/var/www
    depends_on:
      - db
    networks:
      - app_network

  # Web Server
  webserver:
    image: nginx:alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
#      - ./:/var/www
      - ./nginx/conf.d:/etc/nginx/conf.d
    networks:
      - app_network
    depends_on:
      - backend
      - frontend
      - db

  # Database
  db:
    image: mariadb:latest
    container_name: db
    restart: unless-stopped
    environment:
      MARIADB_ROOT_PASSWORD: rootsecret
      MARIADB_DATABASE: laravel_db
      MARIADB_USER: laravel_user
      MARIADB_PASSWORD: secret
    volumes:
      - mariadb_data:/var/lib/mysql
      - ./mysql/my.cnf:/etc/mysql/my.cnf
#      - ./file.sql:/docker-entrypoint-initdb.d/file.sql
    ports:
      - "3306:3306"
    networks:
      - app_network


networks:
  app_network:
    driver: bridge

volumes:
  mariadb_data:
    driver: local

And the Nginx configuration file is as follows:

server {
    listen 80;
    server_name _;
    
    location / {
        proxy_pass http://frontend:3000;  # Use service name
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /api {
        try_files $uri $uri/ /index.php?$query_string;
        fastcgi_pass backend:9000;  # Use service name
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /var/www/public$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_param HTTP_HOST $host;
    }
}

I edited the Back-END cors.php file as follows:

 'allowed_origins' => ['http://localhost:3000','http://localhost:3001','http://frontend:3000'],

And I edited the callApi.tsx file for Front-END as follows:

baseURL: 'http://Backend:9000/api',

I went to http://SERVER_IP and when I try to log in to the site with my username and password, I see the following error in the browser console:

POST http://backend:9000/api/login net::ERR_NAME_NOT_RESOLVED      loginForm.tsx:29

Which part of the configuration did I do wrong?

Thank you.

The part where you tell the computer what ā€œbackendā€ is.

ERR_NAME_NOT_RESOLVED means a DNS lookup failed. It tried to find an IP address for ā€œbackendā€ and found none.

1 Like

Hello,
From the frontend container:

/app $ nslookup backend
Server:         127.0.0.11
Address:        127.0.0.11:53
Non-authoritative answer:
Non-authoritative answer:
Name:   backend
Address: 172.19.0.5

The frontend container can see the backend container.

If the frontend is react, isn’t the call to http://backend:9000/api/login, being made by your browser i.e. your local computer and not the frontend server?.

Try the nslookup from the computer that is running the browser

Hi,
Thank you so much for your reply.
Why should the client be able to see the backend container? All containers see each other.

Why should the client be able to see the backend container?

I don’t understand the question. You are calling ā€˜http://backend:9000/api/login’, and you are asking me why?.

The client is calling an api supposedly exposed by the backend service that happens to be running in a container. I don’t see the PHP-FPM port being exposed to the host in your docker.

If you don’t want to expose PHP-FPM to the host, then use Ngix (which is good for security reasons), that looks like you are already doing that (I don’t know if is correctly setup though you’ll have to check).

So your call probably should be: http://SERVER_IP/api/login

Hello,
Thanks again.
Let’s say this is an internet website. Where is my configuration wrong?
I found this. Is my problem with exposing the port?

Let me try to explain.

Containers are like computers. If all the computers are in the same network then they can see each other. How do you accomplish that with containers?.

By setting the

networks:
      - app_network

In all the containers. That is why for example the webserver can see db, frontend, etc.

Now containers run in what is called the host (your computer). If a program in the host is trying to interact with a container, the container has to exposed an outside port.

For example, in the link that you put the backend is exposing the ports: 6002:4001. The first value is port exposed to the host 6002, and 4001 is the internal port of the service. So the user by mistake was calling localhost:4001 instead of localhost:6002.

Ok. Now about your configuration. Like I said in a previous post. Your db is not exposing any port to the host because your using the webserver that is exposing 2 ports the host, and then communicate internally with your backend (remember same network) which by default is listening in port 9000

Here is good tutorial about docker compose with php similar to yours. The only thing missing is the react part

https://www.youtube.com/watch?v=TswVrfNQZHc

Now my understanding is that since your ngix service is exposing both react and api the you can use relative path for the api so your baseURL can be like this:

baseURL: ā€˜/api’

or just use the full path:

baseURL: 'http://localhost/api

then post will be something like this:

const postData = async () => {
  const data = { key: 'value' }; // Replace with your data

  try {
    const response = await fetch(baseURL + '/login', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data),
    });

    if (!response.ok) {
      throw new Error('Network response was not ok');
    }

    const result = await response.json();
    console.log(result);
  } catch (error) {
    console.error('Fetch error:', error);
  }
};

Hope that help

2 Likes

Hello,
Thank you so much for your reply.
I did:

 baseURL: '/api',

And:

'allowed_origins' => ['http://localhost:3000','http://localhost:3001', 'http://localhost'],

Problem solved.