Skip to content

Instantly share code, notes, and snippets.

@mattes
Last active December 4, 2023 12:07
Show Gist options
  • Star 33 You must be signed in to star a gist
  • Fork 13 You must be signed in to fork a gist
  • Save mattes/4d7f435d759ca2581347 to your computer and use it in GitHub Desktop.
Save mattes/4d7f435d759ca2581347 to your computer and use it in GitHub Desktop.
docker-machine/ boot2docker with NFS instead of vboxsf
#!/usr/bin/env ruby
# Usage
# $ docker-machine create my-machine123 -d virtualbox
# $ ruby <(curl -L https://git.io/vvvco) my-machine123
# https://gist.github.com/mattes/4d7f435d759ca2581347
require 'erb'
bootlocalsh = %Q(#/bin/bash
sudo umount /Users
sudo /usr/local/etc/init.d/nfs-client start
sudo mount -t nfs -o noacl,async <%= vboxnet_ip %>:/Users /Users
)
if ARGV.length != 1
puts "usage: #{__FILE__} machine-name"
exit 1
end
machine_name = ARGV[0]
print "Get vboxnet ip addres ..."
# get host only adapter
vboxnet_name = `VBoxManage showvminfo #{machine_name} --machinereadable | grep hostonlyadapter`
vboxnet_name = vboxnet_name.scan(/"(.*)"/).flatten.first.chomp
if vboxnet_name == ''
puts "error: unable to find name of vboxnet"
exit 1
end
# get ip addr for vboxnet
vboxnet_ip = ''
vboxnets = `VBoxManage list hostonlyifs`.split("\n\n")
vboxnets.each do |vboxnet|
if vboxnet.scan(/Name: *(.+?)\n/).flatten.first.chomp == vboxnet_name
vboxnet_ip = vboxnet.scan(/IPAddress: *(.*)\n/).flatten.first.chomp
break
end
end
if vboxnet_ip == ''
puts "error: unable to find ip of vboxnet #{vboxnet_name}"
exit 1
end
print " #{vboxnet_ip}\n"
# create record in local /etc/exports and restart nsfd
machine_ip = `docker-machine ip #{machine_name}`.chomp
puts "Update /etc/exports ..."
`echo '\n/Users #{machine_ip} -alldirs -maproot=root\n' | sudo tee -a /etc/exports`
`awk '!a[$0]++' /etc/exports | sudo tee /etc/exports` # removes duplicate lines
`sudo nfsd restart`; sleep 2
puts `sudo nfsd checkexports`
# render bootlocal.sh and copy bootlocal.sh over to boot2docker
# (this will override an existing /var/lib/boot2docker/bootlocal.sh)
puts "Update boot2docker virtual machine ..."
bootlocalsh_rendered = ERB.new(bootlocalsh).result()
first = true
bootlocalsh_rendered.split("\n").each do |l|
`docker-machine ssh #{machine_name} 'echo "#{l}" | sudo tee #{first ? '' : '-a'} /var/lib/boot2docker/bootlocal.sh'`
first = false
end
`docker-machine ssh #{machine_name} 'sudo chmod +x /var/lib/boot2docker/bootlocal.sh'`
puts "Restart #{machine_name} ..."
`docker-machine restart #{machine_name}`
puts "Done."
puts
puts "Run `docker-machine ssh #{machine_name} df` to check if NFS is mounted."
puts "Output should include something like this: '#{vboxnet_ip}:/Users [...] /Users'"
@tonivdv
Copy link

tonivdv commented May 8, 2015

Hello @mattes,

Thanks for this gist. I tried to use and it "works" in the way that the mounting is being done etc. However I don't have the same performance as with my own "vagrant+docker" setup (which I'd like to remove).

So it seems that the vagrant+nfs share is much more performant.

Any ideas?

@dduportal
Copy link

Maybe trying the same mount command than the one that vagrant tries ? I suspect this just NFS mount options (perfs can vary a lot), since both vagrant and boot2docker are using the same underlying systems...

@tonivdv
Copy link

tonivdv commented May 11, 2015

I found the reason 😄 . Docker-machine configures virtualbox with "Network > Advanced > Adapter Type" to "paravirtualized network". When I changed that to my Mac Book adapter (Intel PRO/1000 MT Desktop (82540EM) I got the same high speed performance.

Not sure though if that can be scripted ?!

@tonivdv
Copy link

tonivdv commented May 11, 2015

Actually by looking at the virtualbox documentation it has nothing todo with a mac adapter (I was mislead with the INTEL PRO stuff).

From https://www.virtualbox.org/manual/ch06.html#nichardware

For each card, you can individually select what kind of hardware will be presented to the virtual machine. VirtualBox can virtualize the following six types of networking hardware:

AMD PCNet PCI II (Am79C970A);

AMD PCNet FAST III (Am79C973, the default);

Intel PRO/1000 MT Desktop (82540EM);

Intel PRO/1000 T Server (82543GC);

Intel PRO/1000 MT Server (82545EM);

Paravirtualized network adapter (virtio-net).

The PCNet FAST III is the default because it is supported by nearly all operating systems out of the box, as well as the GNU GRUB boot manager. As an exception, the Intel PRO/1000 family adapters are chosen for some guest operating system types that no longer ship with drivers for the PCNet card, such as Windows Vista.

The Intel PRO/1000 MT Desktop type works with Windows Vista and later versions. The T Server variant of the Intel PRO/1000 card is recognized by Windows XP guests without additional driver installation. The MT Server variant facilitates OVF imports from other platforms.

The "Paravirtualized network adapter (virtio-net)" is special. If you select this, then VirtualBox does not virtualize common networking hardware (that is supported by common guest operating systems out of the box). Instead, VirtualBox then expects a special software interface for virtualized environments to be provided by the guest, thus avoiding the complexity of emulating networking hardware and improving network performance. Starting with version 3.1, VirtualBox provides support for the industry-standard "virtio" networking drivers, which are part of the open-source KVM project.

Anyway this is all out of scope of this gist. Sorry @mattes for spamming here.

@nathanleclaire
Copy link

Hi @mattes @tonivdv - You should loop me in on conversations like these, they're relevant to my interests 😉

@nathanleclaire
Copy link

@tonivdv Are you referencing the network settings for NAT or for the Host Only Network in your comments?

@tonivdv
Copy link

tonivdv commented May 17, 2015

@nathanleclaire Sorry that I didn't respond sooner (mentions in gist don't work/notify). I set it for both NAT and Host Only Network. Not sure if one of the two is good enough. I should play with it to really know.

@tonivdv
Copy link

tonivdv commented May 18, 2015

@nathanleclaire I made the test, and only the "Host only adapter" should be changed to PCnet-FAST III to have high performance :)

@tomdavidson
Copy link

Thanks, why -maproot=root and not -mapall=USER:GROUP ?

@tonivdv
Copy link

tonivdv commented Jun 23, 2015

@tomdavidson, it's better USER:GROUP indeed!

@tomdavidson
Copy link

I dont know whats better or not, just that I can not manage to get the right permissions of the host volumes for a database with the user & group of mysql to be able to write to the share. What would be the implications of -mapall=USER, with no group?

https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man5/exports.5.html

@ianlintner-wf
Copy link

Currently I have switched mine to use -mapall=uid:gid and that seems to work well for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment