html
When you modify /etc/hosts
or directly edit the hostname file in /var/lib/docker/containers/[ID]/hostname
, Docker overwrites these changes on container restart because it's designed to maintain immutable infrastructure principles. The files you found are runtime artifacts, not configuration points.
Option 1: Recreate with --hostname flag
# For new containers
docker run -d --hostname my-new-hostname nginx
# For existing containers (requires recreation)
docker rm -f old-container
docker run -d --name new-container --hostname my-new-hostname nginx
Option 2: Use docker-compose hostname directive
version: '3'
services:
webserver:
image: nginx
hostname: custom-hostname
container_name: custom-container
Option 3: Override through entrypoint (advanced)
# In your Dockerfile
FROM ubuntu
COPY set_hostname.sh /set_hostname.sh
ENTRYPOINT ["/set_hostname.sh"]
# set_hostname.sh content:
#!/bin/bash
echo "custom-hostname" > /etc/hostname
exec "$@"
Docker manages /etc/hosts
dynamically to maintain service discovery and networking functionality. The file is regenerated whenever the container starts to reflect:
- Current container IP address
- Linked container hostnames
- Docker DNS resolution
For containers that can't be recreated, use nsenter
to modify the UTS namespace:
# Get container PID
CONTAINER_PID=$(docker inspect --format '{{.State.Pid}}' container-name)
# Modify hostname
sudo nsenter -t $CONTAINER_PID -u hostname new-hostname
# Persist across restarts (requires custom entrypoint)
docker exec container-name sh -c "echo new-hostname > /etc/hostname"
Check effective hostname with:
docker exec -it container-name hostname
docker exec -it container-name cat /etc/hostname
Many developers coming from VM backgrounds expect Docker containers to behave like full virtual machines when it comes to hostname configuration. The key misunderstanding here is that Docker containers are designed to be ephemeral by nature, and certain configurations (like hostnames) are meant to be set at creation time.
When you manually edit /etc/hosts
inside a running container, Docker will overwrite these changes during container restart because:
- The hostname is managed by Docker's runtime
- Container networking is reinitialized on start
- The
hostname
file in/var/lib/docker/containers/[ID]/
takes precedence
Here are the proper ways to handle hostnames in Docker:
1. Using docker run (Preferred Method)
# For new containers
docker run --hostname my-custom-hostname -d my-image
2. Modifying Existing Containers
For containers already running where you can't use --hostname
:
# Step 1: Create custom entrypoint script
echo '#!/bin/sh
echo "my-custom-hostname" > /etc/hostname
hostname -F /etc/hostname
exec "$@"' > /custom-entrypoint.sh
# Step 2: Rebuild your image
FROM original-image
COPY custom-entrypoint.sh /
RUN chmod +x /custom-entrypoint.sh
ENTRYPOINT ["/custom-entrypoint.sh"]
CMD ["your", "original", "command"]
3. Using Docker Compose
version: '3'
services:
my-service:
image: my-image
hostname: my-custom-hostname
container_name: my-custom-name
For systems using systemd to manage Docker containers:
[Service]
Environment="HOSTNAME=my-custom-hostname"
ExecStartPre=/usr/bin/docker run --rm --hostname ${HOSTNAME} ...
- Don't edit
/etc/hosts
directly - it will be regenerated - Avoid modifying files in
/var/lib/docker/
directly - Remember that
docker rename
only changes the container name, not hostname
The proper Docker way is to treat hostnames as immutable after container creation. For persistent changes, you should either rebuild your image with the proper configuration or use infrastructure-as-code tools to manage container deployment.