Skip to main content

[SOLVED] "Unknown host" error calling containerized backend from frontend - docker

[SOLVED] Resolving the “Unknown Host” Error When Accessing a Containerized Backend from the Frontend in Docker

In this chapter, we will talk about the annoying “Unknown host” error. This error happens when we try to connect a frontend app to a containerized backend in Docker. It can come from different network settings and resolution issues in Docker. It is important for us to understand how Docker networking works. This helps us when we work with containerized apps. We will look at different ways to fix this error. This way, we can make sure our frontend and backend services communicate well.

Here are the solutions we will discuss:

  • Solution 1: Check Docker Network Settings
  • Solution 2: Use Docker Compose for Service Finding
  • Solution 3: Look at Hostname Resolution in Docker
  • Solution 4: Make Sure API Endpoint is Right in Frontend
  • Solution 5: Connect Containers Using Docker Networking
  • Solution 6: Change /etc/hosts for Local Work

By the end of this chapter, we will know how to fix the “Unknown host” error in Docker. We will also learn how to connect our frontend and backend apps smoothly. For more details about Docker networking, we can check our guide on Docker Networking.

Solution 1 - Verify Docker Network Configuration

The “Unknown host” error when we call a containerized backend from the frontend often comes from wrong Docker network settings. It is very important that both our frontend and backend containers are on the same network. This helps them communicate well. Here are the steps to check and set up our Docker network.

  1. Check Existing Docker Networks: We can run this command to see all existing Docker networks:

    docker network ls

    We should look for a network that fits our application. If we use the default bridge network, it may not work well for multi-container communication.

  2. Create a New Network (if needed): If we don’t have a good network, we can make a new bridge network with:

    docker network create my_network
  3. Connect Containers to the Network: When we run our containers, we must make sure that both our frontend and backend are on the same network. For example, we can do this:

    docker run -d --name backend --network my_network backend_image
    docker run -d --name frontend --network my_network frontend_image
  4. Inspect Network Configuration: To check the network settings of our new network, we use:

    docker network inspect my_network

    We need to make sure that both frontend and backend containers show up in the Containers section.

  5. Test Connectivity: We can test if the frontend can reach the backend by using a ping or curl command from the frontend container:

    docker exec -it frontend_container_name ping backend_container_name

    If the ping works, it means our network settings are correct.

  6. Use Service Name: When we talk to our backend from the frontend, we should use the service name (container name) as the hostname. For example, if our backend container is named backend, we use http://backend:port in our frontend code.

By making sure that both our frontend and backend containers are set up in the same Docker network, we can fix the “Unknown host” error. For more details on Docker networking, we can look at this guide.

Solution 2 - Use Docker Compose for Service Discovery

We can simplify managing and setting up multi-container Docker apps by using Docker Compose. This helps fix the “Unknown host” error when we call a backend that runs in a container from a frontend service. Docker Compose helps us find services through its built-in network features. Each service in the docker-compose.yml file can talk to others using their service names as hostnames.

Step-by-Step Guide to Using Docker Compose

  1. Create a docker-compose.yml File:

    We need to define our application setup in a docker-compose.yml file. Here is a simple example where a frontend service talks to a backend service:

    version: "3.8"
    
    services:
      frontend:
        image: your-frontend-image
        ports:
          - "3000:3000"
        depends_on:
          - backend
        networks:
          - app-network
    
      backend:
        image: your-backend-image
        ports:
          - "5000:5000"
        networks:
          - app-network
    
    networks:
      app-network:
        driver: bridge

    In this setup:

    • The frontend service talks to the backend service using the hostname backend.
    • Both services connect through a custom network called app-network.
  2. Run Docker Compose:

    We run the following command in the folder with the docker-compose.yml file:

    docker-compose up

    This command builds and starts our containers as we wrote in the YAML file.

  3. Accessing the Backend from the Frontend:

    In our frontend code, we have to use the service name to call the backend API. For example, if we use Fetch API in JavaScript, it looks like this:

    fetch("http://backend:5000/api/endpoint")
      .then((response) => response.json())
      .then((data) => console.log(data))
      .catch((error) => console.error("Error:", error));
  4. Verifying Network Configuration:

    We should check that both services are on the same network. We can see the network setup by running:

    docker network ls

    Then we can check the specific network:

    docker network inspect app-network

    This will show us the containers in the network and check if our services can talk to each other.

  5. Utilizing Service Discovery:

    With Docker Compose, service discovery happens automatically. We do not have to manage IP addresses by ourselves. By just using the service name (backend in this case), Docker takes care of connecting the hostname to the right container IP.

Using Docker Compose for service discovery helps us fix the “Unknown host” problem. It also makes our applications easier to scale and maintain. For more advanced setups, like using environment variables or external networks, we should look at the official Docker Compose documentation.

Solution 3 - Check Hostname Resolution in Docker

We can often face hostname resolution problems. These problems can cause “Unknown host” errors when we try to call a containerized backend from a frontend application in Docker. To fix these issues, we should check if hostname resolution is working well. Here are the steps to check and fix hostname resolution in Docker:

  1. Inspect Docker Network Settings: First, we need to look at the network settings of our Docker containers. We can use this command to list all networks and find the one our containers are using:

    docker network ls

    After we find the network, we can inspect it to see details about the containers:

    docker network inspect <network_name>

    We need to make sure that both our frontend and backend containers are on the same Docker network. If they are not, we might need to connect them ourselves.

  2. Test Hostname Resolution Inside the Container: We can access the shell of the frontend container and try to ping the backend container using its service name:

    docker exec -it <frontend_container_name> /bin/sh

    Then, inside the shell, we run:

    ping <backend_service_name>

    If the ping works, hostname resolution is fine. If it does not work, we might need to check more.

  3. Check Docker Daemon DNS Settings: Docker has a built-in DNS server to resolve container names. We should check if our Docker daemon is set to use the default DNS settings. We can look at the /etc/docker/daemon.json file. If it does not exist, we can create it. It should look like this:

    {
      "dns": ["8.8.8.8", "8.8.4.4"]
    }

    This setup uses Google Public DNS servers. After we change this file, we need to restart the Docker service:

    sudo systemctl restart docker
  4. Modify /etc/hosts File (if necessary): Sometimes, we might need to change the /etc/hosts file on our local machine. This helps to map container names to IP addresses. But usually, we do not need to do this if we use Docker’s default networking.

  5. Review Docker Compose Configuration: If we use Docker Compose, we need to check that the service names in our docker-compose.yml file are correct. Each service can be accessed using its service name as a hostname. Here is an example:

    version: "3"
    services:
      frontend:
        image: frontend-image
        depends_on:
          - backend
    
      backend:
        image: backend-image

    In this example, the frontend can reach the backend container by using the hostname backend.

By making sure hostname resolution works in Docker, we can fix the “Unknown host” error when we call a containerized backend from our frontend. For more help on networking in Docker, we can check this article on Docker networking.

Solution 4 - Ensure Correct API Endpoint in Frontend

To fix the “Unknown host” error when we call a containerized backend from the frontend, we need to check that the API endpoint in our frontend app is correct and can be reached. This means we have to look at the endpoint URL in our frontend code and make sure it matches the service name or hostname of the backend container.

  1. Check API Endpoint URL: We must make sure that the URL we use in our API calls points to the right service name as we set up in Docker. If we use Docker Compose, the service name acts as the hostname in the same Docker network.

    For example, if our Docker Compose file looks like this:

    version: "3"
    services:
      backend:
        image: my-backend-image
        ports:
          - "5000:5000"

    Then our frontend API calls should be like this:

    const response = await fetch("http://backend:5000/api/data");
  2. Use Environment Variables: If we are deploying our frontend app, we should think about using environment variables to manage our API endpoint settings. This way we can easily switch between development, staging, and production environments.

    Here is an example using environment variables in a React app:

    const apiEndpoint =
      process.env.REACT_APP_API_ENDPOINT || "http://localhost:5000/api";
    const response = await fetch(`${apiEndpoint}/data`);

    We need to set the REACT_APP_API_ENDPOINT variable in our environment configuration.

  3. Cross-Origin Resource Sharing (CORS): If our frontend and backend are on different origins, we have to make sure that our backend server has CORS enabled. This allows requests from our frontend. In a Node.js/Express backend, we can enable CORS like this:

    const cors = require("cors");
    app.use(cors());
  4. Check Network Configuration: If our frontend runs outside of Docker (like on our local machine) and needs to reach a Dockerized backend, we must use the right network interface. In this case, we might need to use localhost or the IP address of the Docker host, depending on how we set things up.

    For example, if the backend runs on port 5000, our API call should look like this:

    const response = await fetch("http://localhost:5000/api/data");
  5. Inspect Network Requests: We can use the browser’s developer tools (F12) to check network requests. We should look at the console for any errors about failed requests. Also, we need to verify that the request URL is correct. This can give us clues if the endpoint is set wrong or cannot be reached.

By following these steps, we can make sure the API endpoint in our frontend app is correct. This way, we can solve the “Unknown host” error when we communicate with our containerized backend. For more details about fixing communication issues between Docker containers, we can check this guide on Docker networking.

Linking containers is very important when we face an “Unknown host” error in Docker. We can use Docker’s networking features to help our frontend talk to our backend services without issues.

Step 1: Create a Docker Network

First, we need to create a custom Docker network if we have not done it yet. This network will let containers talk to each other using their names as hostnames.

docker network create my_custom_network

Step 2: Start Your Backend Container

When we start our backend container, we must connect it to the network we just made. For example, if our backend service is a Node.js app, we can run:

docker run -d --name backend_service --network my_custom_network backend_image

Step 3: Start Your Frontend Container

Next, we start our frontend container and connect it to the same network. This helps the frontend find the backend service by its container name.

docker run -d --name frontend_service --network my_custom_network frontend_image

Step 4: Update API Endpoint in Frontend Code

In our frontend code, we should use the backend container’s name as the hostname for API calls. For example, if our backend service is called backend_service and runs on port 3000, our API calls should look like this:

const API_URL = "http://backend_service:3000/api"; // Use container name as hostname

Step 5: Verify Connectivity

To check if the containers can talk to each other, we can use the docker exec command to enter the frontend container and ping the backend container:

docker exec -it frontend_service ping backend_service

If we set everything up right, we should get replies from the backend service. This means the containers are linked properly.

Additional Tips

  • For more advanced setups, we can use Docker Compose. It makes managing multi-container apps easier and takes care of networking by itself.
  • We should check that the ports our backend service uses are set correctly in our Dockerfile or Docker run command.

By linking our containers with Docker networking, we can fix the “Unknown host” error and help our frontend and backend services communicate smoothly.

Solution 6 - Update /etc/hosts for Local Development

When we develop apps with a containerized backend and a frontend, we sometimes see the “Unknown host” error. This happens because of hostname issues. A good way to fix this in local development is to update the /etc/hosts file.

The /etc/hosts file lets us link hostnames to IP addresses. This is helpful for local development when containers may not be in DNS. Here is how we can update our /etc/hosts file to fix the “Unknown host” error when calling a containerized backend from our frontend.

  1. Locate the Container’s IP Address: First, we need to find the IP address of our backend container. We can do this by running this command in our terminal:

    docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container_name_or_id>

    We replace <container_name_or_id> with the name or ID of our backend container. This command gives us the internal IP address of the container.

  2. Open the /etc/hosts file: Next, we need to edit the /etc/hosts file. We can open it using a text editor with root permissions. For example, we can use nano:

    sudo nano /etc/hosts
  3. Add a Mapping: In the /etc/hosts file, we add a new line that links a hostname to the IP address we got in step 1. For example:

    172.18.0.2 my-backend.local
    • We replace 172.18.0.2 with the IP address of our backend container.
    • We can choose my-backend.local or any hostname that makes sense for our app.
  4. Adjust Frontend API Calls: In our frontend code, we update the API endpoint to use the new hostname we just added. If we called:

    fetch("http://localhost:5000/api/data");

    We change it to:

    fetch("http://my-backend.local/api/data");
  5. Testing: After we edit the /etc/hosts file and update our frontend code, we restart our frontend app and test the API calls. The requests should work now without the “Unknown host” error.

By following these steps, we can manage hostname resolutions for our containerized applications in local development. This method is very useful when we work with many services that need to talk to each other in Docker. For more details on Docker networking, we can check out this article on Docker networking.

Conclusion

In this article, we looked at the common error “[SOLVED] ‘Unknown host’ error calling containerized backend from frontend - Docker”. We shared some ways to fix it.

First, we need to check the Docker network settings. Next, we can use Docker Compose. Finally, we should make sure that hostname resolution works correctly. By doing these things, we can help fix problems and improve how frontend and backend services talk to each other.

For more tips, we can check our guide on Docker networking and service discovery with Docker Compose.

Comments