[Docker] Communicating Between Containers Using Host Ports Without Network Sharing (host.docker.internal)



Tags: Docker, DevOps, Network, host.docker.internal

1. Problem Situation

It's common to manage multiple services using Docker in a development environment.

  • App-A (e.g., DRF) is on network-A.

  • App-B (e.g., Nextcloud) is on network-B.

  • Both containers are running on the same host machine.

  • App-B is bound to the host's 8080 port. (e.g., docker run -p 8080:80 ...)

App-A needs to call App-B via API. I don't want to bother with bridging the two networks. Can't I just call the host's 8080 port directly?

If calling localhost:8080 or 127.0.0.1:8080 from inside the container, it refers to the container itself, not the host machine.

2. Solution: host.docker.internal

The simplest solution is to use the special DNS name host.docker.internal.

host.docker.internal: A special hostname that resolves to the host machine's IP address from within the container.

When calling Nextcloud from the code in App-A (DRF), set the URL as follows.

# Code inside DRF (App-A)
import requests

# Use 'host.docker.internal' instead of 'localhost'.
NEXTCLOUD_URL = "http://host.docker.internal:8080"

try:
    response = requests.get(NEXTCLOUD_URL)
    print(f"Nextcloud connection successful: {response.status_code}")
except requests.exceptions.ConnectionError:
    print("Nextcloud connection failed")

The same goes for testing with curl from inside the container.

# Run inside the App-A container
curl http://host.docker.internal:8080

3. ⚠️ Important: Linux Host Environment Setup

For Docker Desktop (macOS, Windows) users, host.docker.internal works by default.

However, for Linux hosts, you need to add this setting manually. You can map the host IP using a special keyword host-gateway.

Method 1: When Using docker run

Add the --add-host flag.

docker run \
  --add-host=host.docker.internal:host-gateway \
  --network network-A \
  my-drf-app-image

Method 2: When Using docker-compose.yml

Add extra_hosts to the App-A (DRF) service.

services:
  drf-app:
    image: my-drf-app-image
    networks:
      - network-A
    extra_hosts:
      # Maps host.docker.internal to the host machine IP (host-gateway)
      - "host.docker.internal:host-gateway"

# ... (network-A definition) ...

4. Summary

When communicating between separate Docker networks, there's no need to complicate the connections.

  1. Bind the target container (Nextcloud) to the host port (8080).

  2. Send a request from the calling container (DRF) to http://host.docker.internal:8080.

  3. If the host is Linux, remember to add the extra_hosts setting (host.docker.internal:host-gateway) to the calling container.