Docker
Dockerfile
/etc/hosts
Containerization
DevOps

How to update /etc/hosts file in Docker image during docker build

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Trying to edit /etc/hosts during docker build usually means the real problem has not been separated into build-time and runtime concerns yet. Docker manages name resolution around container lifecycle, so a line appended inside a RUN step is often temporary, misleading, or the wrong place to express the dependency.

Understand What Happens During Build

Each RUN instruction executes inside an intermediate build container. That container has its own /etc/hosts, and Docker is free to manage that file. A Dockerfile like this can appear to work while the build is running:

dockerfile
1FROM alpine:3.20
2
3RUN echo "10.0.0.15 internal-api" >> /etc/hosts
4RUN grep internal-api /etc/hosts

The problem is that this does not describe the runtime container configuration clearly, and it is easy to mistake a build-layer workaround for a durable solution.

Use --add-host for Build-Time Resolution

If a build step must resolve a host name, the clean solution is usually Docker’s build-time host mapping support:

bash
docker build \
  --add-host internal-api:10.0.0.15 \
  -t my-image .

Now build commands can reach that host name without manually editing files:

dockerfile
1FROM alpine:3.20
2
3RUN apk add --no-cache curl
4RUN curl http://internal-api:8080/health

This keeps the Dockerfile focused on building the image while the host mapping stays in the build invocation where it belongs.

Configure Runtime Host Mapping Separately

If the running container also needs the same mapping, configure it at runtime instead of trying to bake it into the image.

Use docker run like this:

bash
docker run --add-host internal-api:10.0.0.15 my-image

Or, with Docker Compose:

yaml
1services:
2  app:
3    image: my-image
4    extra_hosts:
5      - "internal-api:10.0.0.15"

This approach keeps the image portable. You can deploy the same image in different environments and supply different host mappings without rebuilding it.

Prefer DNS or Service Discovery When Possible

Static host entries solve narrow problems, but they are rarely the best long-term design. In container environments, DNS-based discovery is easier to maintain than fixed IP addresses.

Examples:

  • In Docker Compose, containers on the same network can often resolve each other by service name.
  • In Kubernetes, a Service gives you a stable internal DNS name.
  • In managed infrastructure, private DNS records are usually better than manual host file entries.

If you can use one of those options, the image becomes more portable and less tied to one environment.

When Manual Editing Is a Temporary Workaround

There are edge cases where a build step truly needs a temporary line in /etc/hosts, for example when a legacy installer checks that file directly. In that case, you can still modify it inside the current layer:

dockerfile
1FROM ubuntu:24.04
2
3RUN printf '10.0.0.15 internal-api\n' >> /etc/hosts \
4 && grep internal-api /etc/hosts

Treat that as a workaround, not the default design. If runtime behavior depends on the same mapping, define that mapping at runtime too.

Common Pitfalls

The biggest mistake is trying to make the image permanently encode environment-specific network details. That forces rebuilds whenever an IP changes and makes the image less reusable.

Another issue is assuming that a successful echo into /etc/hosts during docker build guarantees the same result when the container starts. Build containers and runtime containers are different phases.

People also use static host entries when the real problem is service discovery. If the target should be reachable by service name or DNS, host file edits add unnecessary maintenance.

Finally, if a build step cannot reach a dependency, confirm that the problem is actually hostname resolution. Firewall rules, proxies, routing, and private network boundaries can produce the same symptom.

Summary

  • Editing /etc/hosts in a Dockerfile is usually a workaround, not the preferred design.
  • Use docker build --add-host when a build step needs custom hostname resolution.
  • Use docker run --add-host or Compose extra_hosts for runtime container mapping.
  • Prefer DNS or service discovery over fixed host entries whenever possible.
  • Keep build-time and runtime networking concerns separate.

Course illustration
Course illustration

All Rights Reserved.