This error occurs when a container tries to connect to host.docker.internal but the DNS name is not configured. On Linux, host.docker.internal requires explicit configuration unlike macOS and Windows where it works automatically.
When Docker containers need to communicate with services running on the host machine, they use the special DNS name `host.docker.internal`. This hostname is designed to resolve to an IP address that allows containers to reach the host network. On Docker Desktop for macOS and Windows, `host.docker.internal` is automatically configured and resolves correctly. However, on Linux systems running Docker Engine (not Docker Desktop), this DNS name is not available by default. The container's DNS resolver cannot find the hostname, resulting in the "no such host" error. This is a common source of confusion when developing locally with Docker. Code that works perfectly on macOS or Windows will fail on Linux CI/CD systems or production servers because the `host.docker.internal` resolution is not automatic. The solution involves explicitly mapping this hostname to the host's gateway IP address.
The most common solution for Linux systems is to add the extra_hosts configuration to your docker-compose.yml file:
services:
your-service:
image: your-image
extra_hosts:
- "host.docker.internal:host-gateway"The special value host-gateway tells Docker to replace it with the host's gateway IP address. This adds an entry to the container's /etc/hosts file.
Apply to all services that need host access:
services:
app:
image: node:18
extra_hosts:
- "host.docker.internal:host-gateway"
worker:
image: python:3.11
extra_hosts:
- "host.docker.internal:host-gateway"After making this change, restart your containers:
docker compose down
docker compose up -dWhen running containers with docker run instead of Docker Compose, use the --add-host flag:
docker run --add-host=host.docker.internal:host-gateway your-imageThis achieves the same effect as the docker-compose.yml configuration.
Example with additional options:
docker run -d \
--name my-app \
--add-host=host.docker.internal:host-gateway \
-p 3000:3000 \
my-app-imageVerify the host entry was added:
docker exec my-app cat /etc/hostsYou should see a line like:
172.17.0.1 host.docker.internalThe host-gateway special value requires Docker Engine version 20.10.0 or later (released December 2020).
Check your Docker version:
docker --versionIf you see "invalid IP address in add-host: host-gateway", you need to upgrade Docker.
Upgrade Docker on Ubuntu/Debian:
# Remove old version
sudo apt remove docker docker-engine docker.io containerd runc
# Install latest Docker
curl -fsSL https://get.docker.com | sudo sh
# Verify version
docker --versionUpgrade Docker on CentOS/RHEL/Fedora:
sudo yum remove docker docker-common docker-selinux docker-engine
curl -fsSL https://get.docker.com | sudo sh
docker --versionDocker Desktop for Linux includes host.docker.internal support out of the box, similar to macOS and Windows.
Install Docker Desktop on Ubuntu:
# Download the .deb package from Docker's website
# https://docs.docker.com/desktop/install/ubuntu/
sudo apt install ./docker-desktop-<version>-amd64.debEnable host.docker.internal in Docker Desktop:
1. Open Docker Desktop
2. Go to Settings (gear icon)
3. Navigate to Resources > Network
4. Ensure "Enable host.docker.internal" is checked
5. Click "Apply & Restart"
With Docker Desktop, host.docker.internal resolves automatically without extra configuration.
If you don't need network isolation, you can use host network mode where the container shares the host's network stack:
With docker-compose.yml:
services:
your-service:
image: your-image
network_mode: hostWith docker run:
docker run --network host your-imageImportant considerations:
- The container uses the host's IP address directly
- No port mapping needed (or possible) - ports bind directly to host
- Container can access localhost services on the host
- Reduces network isolation - use with caution in production
- May not work on macOS/Windows Docker Desktop (host networking is Linux-only)
This approach eliminates the need for host.docker.internal entirely because localhost in the container refers to the actual host.
If host-gateway is not available, you can manually specify the Docker bridge gateway IP:
Find the gateway IP:
docker network inspect bridge --format '{{range .IPAM.Config}}{{.Gateway}}{{end}}'This typically returns 172.17.0.1.
Use the IP in docker-compose.yml:
services:
your-service:
image: your-image
extra_hosts:
- "host.docker.internal:172.17.0.1"Or with docker run:
docker run --add-host=host.docker.internal:172.17.0.1 your-imageNote: The gateway IP can vary if you have multiple Docker networks. You may need to adjust it based on your network configuration.
Even with correct DNS resolution, firewall rules may block connections from containers to the host.
Allow Docker bridge network on Ubuntu (ufw):
# Allow from Docker bridge subnet
sudo ufw allow from 172.17.0.0/16
# Or more specifically, allow a port
sudo ufw allow from 172.17.0.0/16 to any port 5432Allow on CentOS/RHEL (firewalld):
# Add Docker zone
sudo firewall-cmd --permanent --zone=docker --add-source=172.17.0.0/16
sudo firewall-cmd --permanent --zone=docker --add-port=5432/tcp
sudo firewall-cmd --reloadTest connectivity from container:
docker run --rm --add-host=host.docker.internal:host-gateway alpine \
sh -c "apk add --no-cache curl && curl -v host.docker.internal:5432"Replace 5432 with the port of the service you're trying to reach.
Services on the host must listen on an interface accessible to containers, not just localhost.
Problem: Service only listens on 127.0.0.1
# This only accepts local connections
postgres -h 127.0.0.1 -p 5432Solution: Bind to 0.0.0.0 or the Docker bridge IP
# This accepts connections from any interface
postgres -h 0.0.0.0 -p 5432
# Or bind to the Docker bridge specifically
postgres -h 172.17.0.1 -p 5432For PostgreSQL (postgresql.conf):
listen_addresses = '*'For MySQL (my.cnf):
bind-address = 0.0.0.0For Node.js applications:
// Instead of
app.listen(3000, '127.0.0.1');
// Use
app.listen(3000, '0.0.0.0');Security note: When binding to 0.0.0.0, ensure your firewall only allows connections from trusted sources.
How host.docker.internal works internally:
On Docker Desktop (macOS/Windows), Docker runs inside a Linux VM. The host.docker.internal DNS name resolves to a special IP that routes traffic from the VM to the host machine. On native Linux, there's no VM layer, so this routing must be configured explicitly using the host gateway.
The host-gateway special value:
When you use host-gateway in --add-host or extra_hosts, Docker replaces it with the IP address of the default bridge gateway (typically 172.17.0.1). This IP is the host's interface on the Docker bridge network.
Cross-platform development tips:
For code that needs to work on all platforms:
1. Always include extra_hosts: ["host.docker.internal:host-gateway"] in docker-compose.yml
2. This is harmless on macOS/Windows and essential on Linux
3. Use environment variables for host references:
services:
app:
environment:
- DB_HOST=host.docker.internal
extra_hosts:
- "host.docker.internal:host-gateway"Troubleshooting DNS inside containers:
# Check if hostname resolves
docker run --rm --add-host=host.docker.internal:host-gateway alpine nslookup host.docker.internal
# Check /etc/hosts entry
docker run --rm --add-host=host.docker.internal:host-gateway alpine cat /etc/hosts
# Test TCP connectivity
docker run --rm --add-host=host.docker.internal:host-gateway alpine nc -zv host.docker.internal 5432Alternative: Use service names in compose:
If both services are in the same docker-compose file, use Docker's internal DNS instead of host.docker.internal:
services:
app:
depends_on:
- db
environment:
- DB_HOST=db # Use service name instead
db:
image: postgresDocker Engine vs Docker Desktop on Linux:
- Docker Engine: Requires explicit host-gateway configuration
- Docker Desktop for Linux: Includes automatic host.docker.internal support but uses more system resources
image operating system "linux" cannot be used on this platform
How to fix 'image operating system linux cannot be used on this platform' in Docker
manifest unknown: manifest unknown
How to fix 'manifest unknown' in Docker
cannot open '/etc/passwd': Permission denied
How to fix 'cannot open: Permission denied' in Docker
Error response from daemon: failed to create the ipvlan port
How to fix 'failed to create the ipvlan port' in Docker
toomanyrequests: Rate exceeded for anonymous users
How to fix 'Rate exceeded for anonymous users' in Docker Hub