Modifying /etc/hosts in Docker Images for Fun and Profit
Update: Read my newer post that talks about Docker’s add-host
option.
Did you know that Docker doesn’t let you (easily) modify /etc/hosts
? You
can’t programmatically add aliases for localhost or new hostname-to-ip
mappings. In short, Docker treats /etc/hosts
like a static resource.
No problem. This will just take a quick Unix script to solve.
Attempt 1, the slate is wiped clean
No big deal, right? We simply write ourselves a little sed
script to alias
localhost and add a couple additional hostname mappings. We can run the sed
script from our Dockerfile.
Well if you tried this at home, you’d quickly find out that it doesn’t work.
Each RUN
command in a Dockerfile does another commit to the image. Ordinarily,
that’s just a space problem but Docker treats /etc/hosts
special. It will
overwrite it whenever it wants without any regard for your modifications. In a
nutshell I wasn’t able to persist any changes made during the Dockerfile.
Attempt 2, mount up
Okay, so we simply run our sed
script when we run our container. Docker run
will execute our startup script, running our sed
script, updating /etc/hosts
and finally running our server.
sed: cannot rename /etc/sedl8ySxL: Device or resource busy
Unfortunately, that doesn’t work either. The way sed -i
works is to read
from the original file, write to a temp file and then move the temp file over
the original file. This doesn’t work in this case because /etc/hosts
is
a mount point.
root@07734c969aa6:/usr/local/src# df -h
Filesystem Size Used Avail Use% Mounted on
rootfs 19G 3.9G 14G 23% /
none 19G 3.9G 14G 23% /
tmpfs 1005M 0 1005M 0% /dev
shm 64M 0 64M 0% /dev/shm
/dev/sda1 19G 3.9G 14G 23% /etc/hosts <----
none 1.1T 159G 881G 16% /code
tmpfs 1005M 0 1005M 0% /proc/kcore
Alternatives
How are other people solving this problem today? Some people seem to be using
dnsmasq
as a way of bypassing the problem of /etc/hosts
. Running another
dns server process as a workaround seems excessive, but I’m not sure I
blame them. Doing a search of issues in the Docker Github repo found 125 issues
which mentioned /etc/hosts
.
On Stackoverflow there is the realization that /etc/hosts
is now writable,
but doesn’t persist changes in running container.
Even so, I hadn’t seen anyone provide a programmatic way to address the issue.
Attempt 3, Mungehosts is born
I took a step back and decided to write my own utility, Mungehosts. It solves my major pain points:
- Programmatic interface
- Can add aliases for localhost (ipv4 and ipv6)
- Can add hostname-to-ip mappings
- Works with Docker
- Compiled executable (Linux binary in releases)
- No dependencies except C runtime
- Small size (167 KB)
Check it out and provide feedback. I know that the smart Docker folks will eventually get all of the features into the main application. When that happens Mungehosts will retire to pasture, but it will be a good workaround until then.