How to update /etc/hosts file in Docker image during "docker build"
Asked Answered
J

11

200

I want to update my /etc/hosts file during "docker build".

I added below line in Dockerfile but it's neither updating /etc/hosts file nor giving any error.

RUN echo "192.168.33.11    mynginx" >> /etc/hosts

I need to update /etc/hosts. Can anyone suggest on this?

Jacintajacinth answered 11/7, 2016 at 8:57 Comment(5)
Are you using boot2docker to execute your docker build?Ajit
No, I am using Linux version of docker 1.8.Jacintajacinth
And when you are running your image as a container, its /etc/hosts is unchanged? Or were you referring your Linux host /etc/hosts?Ajit
During docker build image is built successfully.but when i run a container using same image and i checked /etc/hosts file,Changes were not there.Jacintajacinth
If there is no way of adding hosts during build time, then using docker run --add-host as documented by Asad in https://mcmap.net/q/101386/-how-to-update-etc-hosts-file-in-docker-image-during-quot-docker-build-quot is next best solution 100%. Using docker build --add-host will NOT solve the problem.Tripos
A
260

With a more recent version of docker, this could be done with docker-compose and its extra_hosts directive

Add hostname mappings.
Use the same values as the docker run client --add-host parameter (which should already be available for docker 1.8).

extra_hosts:
  - "somehost:162.242.195.82"
  - "otherhost:50.31.209.229"

In short: modify /etc/hosts of your container when running it, instead of when building it.


With Docker 17.x+, you have a docker build --add-host mentioned below, but, as commented in issue 34078 and in this answer:

The --add-host feature during build is designed to allow overriding a host during build, but not to persist that configuration in the image.

Those links point to strategies for dealing with the problem at hand:

  • Run an internal DNS; you can set the default DNS server to use in the daemon; that way every container started will automatically use the configured DNS by default
  • Use docker compose and provide a docker-compose.yml to your developers.
    The docker compose file allows you to specify all the options that should be used when starting a container, so developers could just docker compose up to start the container with all the options they need to set.

These solutions can take advantage of using of the docker-compose method that was suggested earlier in the answer, with its extra_hosts directive.

Ajit answered 11/7, 2016 at 12:13 Comment(10)
i want to change /etc/hosts in the docker image.Jacintajacinth
@PrakashSingh I agree, but that doesn't seem to be easy to do.Ajit
@PrakashSingh You can open a bash instance on the machine via the docket exec -it <container name> /bin/bash, then update the docker's container host under /ect/host with your preferred command line editor (vim, emacs, nano, echo '' . >>/>).Revoke
@PrakashSingh Yes we can(sounds familiar...). But it just looks like kind of hack for Docker when we change hosts entry by building an image, not running a container. Docker network design is application driven(from docker.com). Since hosts entry is part of docker network, we’d better define it when running a container from image. If you really need to add some hosts entry, you don’t add them by building image every-time, you add them to base image once. That is the best practice.Donte
To solve a problem with rocker/shiny install.packages during docker build --add-host:cran.rstudio.com:<IPaddress> solved the issue for me.Irresolution
how about an already created container? cause when I modify /etc/hosts, after restarting container, it will change back to last oneMiddlebreaker
@Omid created? This page is about creating a new image, during docker build. For created containers, ... maybe the answer below: https://mcmap.net/q/101386/-how-to-update-etc-hosts-file-in-docker-image-during-quot-docker-build-quot (but yes, that will not persist)Ajit
The working link to the documents for extra_hostsMisdoubt
The solutions mentioned do refer the docker-compose I was suggesting above What does this mean?Eth
@Eth I agree, that was not very clear. I have edited the answer and rephrased the second part.Ajit
N
40

You can not modify the host file in the image using echo in RUN step because docker daemon will maintain the file(/etc/hosts) and its content(hosts entry) when you start a container from the image.

However following can be used to achieve the same:

ENTRYPOINT ["/bin/sh", "-c" , "echo 192.168.254.10   database-server >> /etc/hosts && echo 192.168.239.62   redis-ms-server >> /etc/hosts && exec java -jar ./botblocker.jar " ]

Key to notice here is the use of exec command as docker documentation suggests. Use of exec will make the java command as PID 1 for the container. Docker interrupts will only respond to that.

See https://docs.docker.com/engine/reference/builder/#entrypoint

Note answered 21/11, 2016 at 14:1 Comment(2)
In case you are looking for kubenetes solution you can use hostAliases. kubernetes.io/docs/concepts/services-networking/… just like docker compose extra_hosts.Note
More precisely, ENTRYPOINT is not a instruction for image. It only mark an entry point when we run a container from this image, which means the hosts entry exists only after container is running. I do not think the requirement is essential. There must be some misunderstanding .Donte
G
29

I think docker recently added the --add-host flag to docker build which is really great.

[Edit] So this feature was updated on 17.04.0-ce

For more detail on how to use docker build with the --add-host flag please visit: https://docs.docker.com/edge/engine/reference/commandline/build/

Grandaunt answered 15/9, 2017 at 14:27 Comment(2)
The --add-host feature is available on Docker 12 on CentOS.Diarmuid
I want to emphasize that "the host that's added with this flag is only used during the build; it deliberately should not persist in the image" github.com/moby/moby/issues/34078Conjunction
R
15

Since this still comes up as a first answer in Google I'll contribute possible solution.

Command taken from here suprisingly worked for me (Docker 1.13.1, Ubuntu 16.04) :

docker exec -u 0 <container-name> /bin/sh -c "echo '<ip> <name>' >> /etc/hosts"
Retake answered 9/5, 2018 at 12:35 Comment(2)
Not relevant but still valuable. Thx.Donte
When you restart the container this is overwritten with the original one!!!Skeg
A
12

You can do with the following command at the time of running docker

docker run [OPTIONS] --add-host example.com:127.0.0.1 <your-image-name>:<your tag>

Here I am mapping example.com to localhost 127.0.0.1 and its working.

Avast answered 12/4, 2019 at 16:33 Comment(1)
If there is no way of adding hosts during build time, then this is next best solution 100%.Tripos
M
5

If this is useful for anyone, the HOSTALIASES env variable worked for me:

echo "fakehost realhost" > /etc/host.aliases
export HOSTALIASES=/etc/host.aliases
Momentum answered 18/12, 2018 at 9:58 Comment(2)
aren't you confusing docker with kubernetes ? I don't see any HOSTALIASES variable in docker documentationRetrorse
HOSTALIASES is an underlying glibc environment variable, so you can use it with "anything" (it does not work with setuid executables unless you are root, and it does not work with IP addresses unless you install dnsmasq)Marra
C
4

You can use the --add-host option during docker run.

For your case use: docker run --add-host mynginx:192.168.33.11 [image_name]:[tag]

This will update your /etc/hosts

you can check it by using following commands:

  • docker exec -it [container_id] sh

if sh doesnt work for you ,then you can try bash or /bin/sh or /bin/bash

  • cat /etc/hosts
Collyer answered 30/6, 2020 at 7:43 Comment(0)
H
0

I just created a sh script and run it on start docker.

In this script I start all the services and update the hosts file:

on Dockerfile:

CMD /tmp/init_commands.sh & sleep infinity 

init_comands.sh

any other commands...
echo "192.168.11.5    XXXXXXX" >> /etc/hosts
echo "192.168.11.6    XXXXXXY" >> /etc/hosts
echo "192.168.11.7    XXXXXXZ" >> /etc/hosts
Haletta answered 4/1, 2022 at 21:9 Comment(0)
L
-2

Following worked for me by mounting the file during docker run instead of docker build

docker service create --name <name>  --mount type=bind,source=/etc/hosts,dst=/etc/hosts   <image>
Londonderry answered 12/8, 2016 at 14:17 Comment(1)
adding a file using volume creates additional complexity and every host has to have the file.Note
U
-2
Tis is me Dockefile
FROM XXXXX
ENV DNS_1="10.0.0.1 TEST1.COM"
ENV DNS_1="10.0.0.1 TEST2.COM" 
CMD ["bash","change_hosts.sh"]`

#cat change_hosts.sh
su - root -c "env | grep DNS | akw -F "=" '{print $2}' >> /etc/hosts"
  • info
  • user must su
Ungrudging answered 15/5, 2019 at 3:8 Comment(0)
A
-18

Just a quick answer to run your container using:

docker exec -it <container name> /bin/bash

once the container is open:

cd ..

then

`cd etc`

and then you can

cat hosts

or:

apt-get update
apt-get vim

or any editor you like and open it in vim, here you can modify say your startup ip to 0.0.0.0

Aweinspiring answered 6/7, 2017 at 5:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.