A simple and transparent alternative to boot2docker (backed by Vagrant)
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
Vagrantfile
install.sh
readme.md

readme.md

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.
  • 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.

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 for vagrant 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:

  1. Enter the VM with docker-vm ssh and install docker-compose by executing sudo 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".

  2. 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 (in cmd):

    (
    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.