29

Is there a way to force docker-machine to create the docker vm with a specific ip (assuming that ip is available)?

ashic
  • 6,367
  • 5
  • 33
  • 54

5 Answers5

32

That is actively requested in docker/machine issue 1709

I want to be able to specify the IP address of a VM (i.e. the value that's listed under "URL" in docker-machine ls) when I create it with docker-machine create.

I want this because I've been relying on boot2docker's default address of 192.168.59.103, but now it varies from machine to machine.

The current workaround:

My virtualbox has dhcp range 192.168.99.100 - 255 and I want to set an IP before 100.

I've found a simple trick to set a static IP: after create a machine, I run this command and restart the machine:

echo "ifconfig eth1 192.168.99.50 netmask 255.255.255.0 broadcast 192.168.99.255 up" | docker-machine ssh prova-discovery sudo tee /var/lib/boot2docker/bootsync.sh > /dev/null

This command create a file bootsync.sh that is searched by boot2docker startup scripts and executed.

Now during machine boot the command is executed and set static IP.

docker-machine ls
NAME              ACTIVE   DRIVER       STATE     URL                                      SWARM
test-1                      -        virtualbox     Running   tcp://192.168.99.50:2376      test-1 (master)

Michele Tedeschi (micheletedeschi) adds

I've updated the commands with:

echo "kill `more /var/run/udhcpc.eth1.pid`\nifconfig eth1 192.168.99.50 netmask 255.255.255.0 broadcast 192.168.99.255 up" | docker-machine ssh prova-discovery sudo tee /var/lib/boot2docker/bootsync.sh > /dev/null

then run command (only the first time)

docker-machine regenerate-certs prova-discovery

now the IP will not be changed by the DHCP

(replace prova-discovery by the name of your docker-machine)


Here is the (Windows) script (dmvbf.bat) I now use, based on what is above:

@echo off
setlocal enabledelayedexpansion
set machine=%1
if "%machine%" == "" (
    echo dmvbf expects a machine name
    exit /b 1
)
set ipx=%2
if "%ipx%" == "" (
    echo dmvbf x missing ^(for 192.168.x.y^)
    exit /b 2
)
set ipy=%3
if "%ipy%" == "" (
    echo dmvbf y missing ^(for 192.168.x.y^)
    exit /b 3
)

echo kill $(more /var/run/udhcpc.eth1.pid) | docker-machine ssh %machine% sudo tee /var/lib/boot2docker/bootsync.sh >NUL
echo ifconfig eth1 192.168.%ipx%.%ipy% netmask 255.255.255.0 broadcast 192.168.%ipx%.255 up | docker-machine ssh %machine% sudo tee -a /var/lib/boot2docker/bootsync.sh >NUL
echo route add default gw <gateway ip address here> | docker-machine ssh %machine% sudo tee -a /var/lib/boot2docker/bootsync.sh >NUL

docker-machine ssh %machine% "sudo cat /var/run/udhcpc.eth1.pid | xargs sudo kill"

docker-machine ssh %machine% "sudo ifconfig eth1 192.168.%ipx%.%ipy% netmask 255.255.255.0 broadcast 192.168.%ipx%.255 up"

(Note: on Windows 10, Monty Wild comments that it is udhcpc.eth0.pid, not udhcpc.eth1.pid)

I start the vm (docker-machine start <machine-name>), and then:

 dmvbf <machine-name> 99 101

I do that only once.

At the next docker-machine start <machine-name>, the IP will be 192.168.99.101.

Nick Udell
  • 2,420
  • 5
  • 44
  • 83
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 1
    I tried this - was really hoping it would work - with the default machine, Windows 10, with the default machine in VirtualBox VM. It invalidates the docker generated certificate. When you do docker-machine ls it states the certificate is valid for the old IP, not the new IP. – rmcsharry Mar 13 '16 at 15:30
  • 1
    @mcs that is expected: yo do a final docker-machine regenerate-certs and you are done. – VonC Mar 13 '16 at 15:58
  • @VonC appreciate the fast response. It works! You have no friggin idea how grateful I am to you for this script! Seriously, what a lifesaver. – rmcsharry Mar 13 '16 at 16:05
  • Sadly the script doesn't work for me: I use Windows 10, my docker-machine ist running, but when I execute your batch file (in win command line) it hangs forever. – Munchkin Jun 20 '16 at 10:57
  • @Mun That script is supposed to be executed in a CMS session, not in a docker-machine ssh session. – VonC Jun 20 '16 at 10:58
  • @Munchkin you could ask a new question describing your context (docker version, docker-machine version, OS -- I assume Windows, but which one), ... – VonC Jun 20 '16 at 13:02
  • 1
    second command gives error /null /var/run/udhcpc.eth1.pid: No such file or directory. – Dobler Sep 01 '16 at 22:18
  • 1
    @Dobler Are you using that script on Windows? Because it looks like a quote issue, and I have been using that script for ages without any problem. – VonC Sep 02 '16 at 06:49
  • no I'm using it in zsh. perhaps it only works in bash? – Dobler Sep 02 '16 at 20:08
  • @Dobler it is purely a bat Windows script, meant to run in a simple CMD session. You would need to adapt it to bash if you wanted to run it in a linux-like environment. – VonC Sep 02 '16 at 20:10
  • yes i understand, I'm using the command above the script. The one marked as updated. – Dobler Sep 02 '16 at 20:21
  • On Windows 10, it is udhcpc.eth0.pid, not udhcpc.eth1.pid. – Monty Wild Jan 24 '18 at 13:23
  • @MontyWild Thank you. I have included your comment in the answer ofr more visibility. – VonC Jan 24 '18 at 13:29
  • Also, once set up with the new IP address, and when cmd is pointing to the new docker-machine, a docker run fails due to lack of network connectivity to the internet. – Monty Wild Jan 24 '18 at 16:59
  • ...Apparently there is no default route set up. – Monty Wild Jan 24 '18 at 17:23
  • ...I have worked around that with `route add default gw
    `.
    – Monty Wild Jan 24 '18 at 17:41
  • @MontyWild OK. Can you edit the answer to show exactly the complete command to add to this sequence in order to make the new IP work? – VonC Jan 24 '18 at 21:50
  • 2
    I use windows 10, the scripts returns " | was unexpected at this time ". – Le Huu HoangGia Aug 20 '18 at 11:05
  • it is "dmvbf.bat default 1 7" – Le Huu HoangGia Aug 20 '18 at 13:34
  • @LeHuuHoangGia Try with `@echo on` at the beginning, to see exactly which line has the issue. – VonC Aug 20 '18 at 13:37
  • @VonC it is ```>echo ifconfig eth1 192.168.1.7 netmask 255.255.255.0 broadcast 192.168.1.255 up | docker-machine ssh default sudo tee -a /var/lib/boot2docker/bootsync.sh 1>NUL | was unexpected at this time.``` – Le Huu HoangGia Aug 20 '18 at 13:40
  • @LeHuuHoangGia Strange, considering the previous line has (presumably) worked. I don't have any immediate clue for now. – VonC Aug 20 '18 at 13:45
  • 1
    @VonC I had fixed some typo ```/bar/lib...``` should be ```/var/lib...```. Now it hang at ```docker-machine ssh default "sudo ifconfig eth0 192.168.1.7 netmask 255.255.255.0 broadcast 192.168.1.255 up"``` – Le Huu HoangGia Aug 20 '18 at 13:53
  • @LeHuuHoangGia well done, don't forget to edit the answer. – VonC Aug 20 '18 at 13:54
  • 1
    To be precise, here is what the script doing: 1. Precondition: I use "default" of a docker machine name, 192.168.1.7 as a static IP of a machine 2. Commands: ``` docker-machine ssh default $default> sudo vi /var/lib/boot2docker/bootsync.sh > enter below content: kill $(more /var/run/udhcpc.eth0.pid) ifconfig eth0 192.168.1.7 netmask 255.255.255.0 broadcast 192.168.1.255 up route add default gw 192.168.1.1 > exit vim ``` Now it works – Le Huu HoangGia Aug 20 '18 at 14:32
  • @LeHuuHoangGia Great! Please edit the answer with your version of that script: that will help others! – VonC Aug 20 '18 at 14:55
  • Solved the problem with "Error getting IP address: Could not find matching IP for MAC address ..." – pinei Jan 10 '19 at 15:03
  • Sorry VonC it does not work and I oppened a new question: https://stackoverflow.com/questions/55161047/how-can-i-run-the-command-to-force-docker-machine-to-create-a-vm-with-specific-a Thanks for your help – Jorge M. Nures Mar 14 '19 at 11:14
  • @VonC Nobody answers https://stackoverflow.com/questions/55161047/how-can-i-run-the-command-to-force-docker-machine-to-create-a-vm-with-specific-a. Is it too difficult or I did something wrong? Please, do not forget about me ;-) I need it! Thanks – Jorge M. Nures Mar 17 '19 at 19:24
  • @JorgeM.Nures I did not forget and was waiting for other specialists to chime in. Maybe a bounty might help... – VonC Mar 17 '19 at 19:42
  • @VonC. I've created a bounty with more than a quarter of all my points! “We are not rich by what we possess but by what we can do without.” I.K. ;-) – Jorge M. Nures Mar 18 '19 at 08:25
  • @JorgeM.Nures Yes, that is the issue with bounties... But if you add some answers of your own (to other questions), that will help people, and you will make back those 50 points in no time :) – VonC Mar 18 '19 at 09:25
  • @VonC I wish I would know as much as you do! I try, though. Earning points by doing questions is much harder, but they are well spent if I could help other with my questions. Thanks for you help – Jorge M. Nures Mar 18 '19 at 11:48
  • @VonC I've got a little problem, it looks like my default gateway is ignored when bootsync.sh is launch. I started a new question, could you please take a look https://stackoverflow.com/questions/56700076/boot2docker-bootsync-sh-ignores-my-default-gateway ? – Booster2ooo Jun 21 '19 at 08:58
  • I run into an error: tee: D:/Software/cmder/vendor/git-for-windows/var/lib/boot2docker/bootsync.sh: No such file or directory exit status 1. Then I add quotes arround "s udo tee /var/lib/boot2docker/bootsync.sh" and it works! – Frank Fang May 20 '20 at 15:48
  • @FrankFang Great! Don't hesitate to edit the answer to add the missing quotes. I will approve the edit. – VonC May 20 '20 at 15:50
4

The script below uses default as name of the machine and 10.100.1.100 as the static IP address.

cat << EOF | docker-machine ssh default sudo tee /var/lib/boot2docker/bootsync.sh > /dev/null
ifconfig eth1 10.100.1.100 netmask 255.255.255.0 broadcast 10.100.1.255 up
ip route add default via 10.100.1.1
EOF

Restart the machine:

docker-machine restart default

Regenerate the certificates:

docker-machine regenerate-certs default -f

Finally, show the environment variables:

docker-machine env default
Bruno Wego
  • 2,099
  • 3
  • 21
  • 38
2

I changed the DHCP range of VirtualBox. Made both upperbound and lowerbound to 192.168.99.100 and restarted the docker machine. To change the range go to VirtualBox->Files->host network manager->chose the appropriate adapter->change the upperbound.

humbleCoder
  • 667
  • 14
  • 27
2

Yes, there is an option to create with specific ip. All you need to do is specify ip/ip-range with --virtualbox-hostonly-cidr option.

For example:

  • when you want to assign specific ip, let say you want to assign 10.15.1.24, then appropriate config will be (the most important thing is the mask that we are using here. For specific ip you need to set subnet mask to 32) :

    docker-machine create --driver virtualbox --virtualbox-hostonly-cidr "10.15.1.24/32" dev

  • if you want to pick an ip from specific ip range, then you need to use appropriate subnet mask.

Nigel
  • 95
  • 1
  • 10
0

My workaround was to watch what VBoxNet the docker machine was attached to and then I went into VirtualBox to reset the DHCP range to deliver only the IP I wanted the machine to have.

Thaddeus Aid
  • 169
  • 1
  • 1
  • 17