Awesome
docker-vm
The easiest way to get started with Docker on Mac OS X (tested on OS X Yosemite 10.10.1) and Windows (tested on Windows 10 Pro Insider Preview. Build 10074).
Goals
- Transparency
- Everything (excluding base VM definition) is in a single, under 50 lines long
Vagrantfile
.
- Everything (excluding base VM definition) is in a single, under 50 lines long
- Configurability
- Changes are inevitable so it's better when the process is quick and painless. Vagrant makes switching to a different provider, changing base image (default one is Ubuntu 14.04 amd64 from phusion), etc. extremely easy.
- Performance
- NFS/SMB instead of vboxsf (a.k.a. VirtualBox Shared Folders) by default. rsync/unison when you need them.
- Utility
- VM is controlled by Vagrant, meaning that you get stuff like
vagrant share
,vagrant package
, etc. out of box.
- VM is controlled by Vagrant, meaning that you get stuff like
You are encouraged to fork and change this repo to suit your needs.
How does it work?
When you boot the VM Docker starts listening on port 2376. Each time you call docker
(or docker-compose
, ...) on the host
it sends a request (using the value of $DOCKER_HOST environment variable) to the guest OS. Together with /Users/USERNAME -> /Users/USERNAME
(on Mac OS X) and C:\Users\USERNAME -> /c/Users/USERNAME & /cygwin/c/Users/USERNAME
mapping it allows
to use Docker client the way you would on Linux (sort of).
Installation
Irrespective of whether you're going to go with "Automated" or "Manual" setup, please make sure you have Git, Docker client (grab it from here (latest - Mac OS X: x86_64 / Windows: i386/x86_64)) (tested on 1.6.1), Vagrant (tested on 1.7.2) & VirtualBox (tested on 4.3.26) installed.
Automated (Mac OS X only)
curl -o- https://raw.githubusercontent.com/shyiko/docker-vm/master/install.sh | bash
(reopen terminal/tab on completion)
NOTE that if you get something like "-bash: docker-vm: command not found" then it's probably because ~/.bashrc is not
sourced from ~/.bash_profile. In that case run echo 'if [ -f ~/.bashrc ]; then source ~/.bashrc; fi' >> ~/.bash_profile
and restart your terminal/tab.
The script clones the docker-vm repository to ~/.docker-vm and adds initialization
code to ~/.bashrc (or ~/.bash_profile, ~/.zshrc, ~/.profile, whichever it finds first).
It also appends 192.168.42.10 docker-vm
to the /etc/hosts so that you would be able to reference
VM by name and not just ip address (e.g. http://docker-vm:8000/
).
You can customize repository url, checkout directory and profile using the
DOCKER_VM_SOURCE, DOCKER_VM_DIR, and PROFILE variables (e.g.
curl ... | DOCKER_VM_SOURCE=http://github.com/YOUR_NAME/docker-vm.git bash
to
use your fork instead of this repo).
Manual
- Mac OS X
git clone https://github.com/shyiko/docker-vm.git ~/.docker-vm
# NOTE: unless you want to execute lines below every time you open up a new terminal/tab -
# consider adding them to the ~/.bash_profile (or whichever profile you use)
# (more on that here - http://ss64.com/osx/syntax-bashrc.html)
docker-vm() ( cd ~/.docker-vm && exec vagrant "$@" )
export DOCKER_HOST=tcp://192.168.42.10:2376
unset DOCKER_TLS_VERIFY # if boot2docker is installed
- Windows
MSYS/Cygwin users only: see installation instructions for Mac OS X.
(execute in cmd
)
git clone https://github.com/shyiko/docker-vm.git "%USERPROFILE%/.docker-vm"
(
echo @ECHO OFF
echo SETLOCAL
echo cd /D ^%USERPROFILE^%\.docker-vm
echo vagrant %*
echo ENDLOCAL
) > %SystemRoot%\system32\docker-vm.bat
set DOCKER_HOST=tcp://192.168.42.10:2376
unset DOCKER_TLS_VERIFY
Usage
docker-vm up # boot up the vm (check "docker-vm --help" for the list of available commands)
# verify that docker client is able to connect to the daemon running inside the vm
docker version
# start using docker *
docker run -v $(pwd):/usr/share/nginx/html -d -p 8080:80 nginx
echo "hello world" > index.html
open http://docker-vm:8080/ # **
* on Windows $(pwd)
needs to be replaced with /c/Users/USERNAME/... (unless you are using MSYS/Cygwin)
** if you don't have 192.168.42.10 docker-vm
in /etc/hosts
(or equivalent on Windows) -
replace http://docker-vm:8080/
with http://192.168.42.10:8080/
.
Note that
docker-vm
is basically just an alias forvagrant
which means that you can use all the commands supported by the latter (e.g.docker-vm suspend
,docker-vm status
, ...).
Getting things to work on Windows can be a little bit tricky (what a suprise, right). Check out the "Troubleshooting" section (further in the document) if you experience any problems with docker-vm up
.
A note on docker-compose
Right now docker-compose is available for Linux / Mac OS X only. Windows support is coming in docker/compose#1085. Until then, one way to get docker-compose on Windows is to:
-
Enter the VM with
docker-vm ssh
and install docker-compose by executingsudo sh -c "curl -L https://github.com/docker/compose/releases/download/1.3.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose"
. -
Create docker-compose alias. If you are using MSYS/Cygwin then it's a matter of adding
docker-compose() ( docker-vm ssh -c "cd $(pwd) && exec docker-compose $*" )
to ~/.bashrc, otherwise - execute (incmd
):( echo @ECHO OFF echo SETLOCAL echo SET pwd=^%cd^:\=/% echo docker-vm ssh -c ^"cd ^%pwd^:C:/=/c/% ^&^& exec docker-compose %*^" echo ENDLOCAL ) > %SystemRoot%\system32\docker-compose.bat
Advanced
Performance considerations
Sooner or later, chances are that you'll have to deal with a lot of small files. And the things is - neither vboxsf nor NFS/SMB
may be up to the task. Here are some numbers to visually demonstrate the issue (time taken to make a copy of
node_modules
containing 32k of files / 290mb in size on MacBook Pro (Retina, Mid 2012), obviously YMMV):
VirtualBox native | native | Network File System (NFS) | VirtualBox Shared Folders (vboxsf) |
---|---|---|---|
17.5s | 18.5s | 2m10s | 3m25s |
The good new is - you can continue using NFS/SMB or even vboxsf (as they are not that bad when you have fewer files) and switch to
rsync
/unison
only when necessary (more on that in a bit). The solution is to use mount -o bind
, which
allows to mount arbitrary directory over the other already mounted one (including subtree), like so:
docker-vm ssh -c "
SOURCE_DIR=/Users/USERNAME/Projects &&
MOUNT_ROOT=/home/vagrant/.mnt &&
mkdir -p $MOUNT_ROOT/$SOURCE_DIR &&
sudo mount -o bind $MOUNT_ROOT/$SOURCE_DIR $SOURCE_DIR"
After that just rsync
/unison
files to $MOUNT_ROOT/$SOURCE_DIR
.
Uni-directional syncing (using rsync)
Check out "vagrant rsync" and "vagrant rsync-auto".
For a one time sync you may find rsync -av SOURCE_DIR vagrant@192.168.42.10:TARGET_DIR
(password is vagrant
) to be more convenient, though.
Bi-directional syncing (using unison)
unison
must be installed both on host and guest OSs (make sure versions match).
On Mac OS X -brew install unison
(2.48.3 at the time of writing).
On Windows -choco install unison -version 2.48.3
(provided chocolatey is installed).
To install unison inside the VM:
sudo apt-get update && sudo apt-get install -y ocaml build-essential exuberant-ctags && curl http://www.seas.upenn.edu/~bcpierce/unison/download/releases/unison-2.48.3/unison-2.48.3.tar.gz | tar xz -C /tmp && (cd /tmp/unison-* && make UISTYLE=text && sudo cp unison /usr/local/bin/)
# start unison daemon
docker-vm ssh -c "unison -socket 5000"
# start syncing (see `unison -help` for more information)
unison SOURCE_DIR socket://192.168.42.10:5000/TARGET_DIRECTORY \
-terse -auto -prefer=SOURCE_DIR -batch -repeat 3
Mounting NFS volumes manually
(it might come in handy if you don't want your whole /Users/USER directory to be mounted inside the VM and
narrowing paths with multiple config.vm.synced_folder
feels too "static")
docker-vm ssh -c "mkdir -p SOURCE_DIRECTORY &&
mount -o 'vers=3,udp' 192.168.42.1:SOURCE_DIRECTORY SOURCE_DIRECTORY"
Don't forget to update /etc/fstab (in your guest OS) if you want to make this link persistent.
Troubleshooting
-
(issue #12182) C:>docker-vm up
VBoxManage.exe: error: Failed to create the host-only adapter ...WORKAROUND: Settings -> View Network Connections -> Ethernet N -> Details... -> select "Internet Protocol Version 4 (TCP/IPv4)" -> Properties -> set "IP address" to 192.168.42.1. Try vagrant up again.
-
C:>docker-vm up
The guest machine entered an invalid state while waiting for it to boot. Valid states are 'starting, running'. The machine is in the 'poweroff' state. Please verify everything is configured properly and try again.WORKAROUND: Start VirtualBox, select VM named docker-vm... and click 'Start'. If you get an error similar to 'Failed to open a session for the virtual machine docker-vm... . VT-x is not available. (VERR_VMX_NO_VMX).' then turn Hyper-V off.
-
(issue #3139) C:>docker-vm up
Clearing any previously set forwarded ports
... or similar and then it just hangs.SOLUTION: Either install PowerShell 3 or remove/comment out ", type: smb" in Vagrantfile. See related issue for more information.
-
C:>docker-vm ssh
ssh
executable not found in any directories in the %PATH% variable. Is an SSH client installed? Try installing Cygwin, MinGW or Git, all of which contain an SSH client. Or use your favorite SSH client with the following authentication information shown below: ...SOLUTION: Install Git for Windows (tested on 1.9.5) and make sure "C:\Program Files (x86)\Git\bin" is on the PATH.