docker sync on Windows

partyka1 edited this page Jun 3, 2018 · 38 revisions

Windows support is still to be considered BETA, - do not get too crazy if there are some bugs!

This guide provides detailed instructions on getting docker-sync running on Windows Subsystem for Linux.

As the time goes by these instructions may not be updated, so please also check out the repo's issues if you have any 'unknown' problem that is not treated in this guide.

Still the procedure is pretty straightforward and should help set you up and running without too much hassle.

My Setup (for reference)

  • Windows 10 Pro 1709

    Pro version required for using Docker for Windows (Hyper-V), also update your system to the latest available version from MS

  • Docker for Windows CE 18.03.0-ce-rc3-win56 (16433) edge

    (stable version should also work fine)

Let's go!

1. Enable WSL

Open the Windows Control Panel, Programs and Features, click on the left on Turn Windows features on or off and check Windows Subsystem for Linux near the bottom.

2. Install a distro

Open the Microsoft Store and search for 'linux'.

You will be then able to choose and install Debian, SUSE, openSUSE, Ubuntu, etc..

In this guide I am using Debian GNU/Linux. Direct link for Debian GNU/Linux

3. Launch and update

The distro you choose is now an 'app' on your system.

Open the start menu and launch it, then follow the on screen instructions in order to complete the installation.

When you have a fully working shell, update the system.

sudo apt update

sudo apt upgrade

4. Install Docker

Follow the official documentation for installing Docker on Linux: (the following is for Debian)

https://docs.docker.com/install/linux/docker-ce/debian/#install-docker-ce

Note that the Docker Server doesn't work on the subsystem - we will then expose Docker for Windows to WSL later

with Windows 10 >= 1803 you can place a symlink to the Windows binary

sudo ln -s "/mnt/c/Program Files/Docker/Docker/resources/bin/docker.exe" /usr/local/bin/docker

5. Install Docker Compose

sudo apt install docker-compose

Or if that does not work, follow the official documentation: https://docs.docker.com/compose/install/

with Windows 10 >= 1803 you can place a symlink to the Windows binary

sudo ln -s "/mnt/c/Program Files/Docker/Docker/resources/bin/docker-compose.exe" /usr/local/bin/docker-compose

6. Install Ruby and Ruby-dev

sudo apt-get install ruby ruby-dev

7. Install docker-sync

sudo gem install docker-sync

8. Set your Docker for Windows host as an ENV variable

Open the Docker for Windows settings and check Expose daemon on tcp://localhost:2375 without TLS

Then type the following command in your WSL shell.

echo "export DOCKER_HOST=tcp://127.0.0.1:2375" >> ~/.bashrc

9. Compile and install OCaml

Before doing this please check out first the Unison release changelog and ensure that the OCaml version that you are going to install is compatible. (https://github.com/bcpierce00/unison/releases)

Install build script

sudo apt-get install build-essential

As for now the procedure is as follows:

sudo apt-get install make
wget http://caml.inria.fr/pub/distrib/ocaml-4.06/ocaml-4.06.0.tar.gz
tar xvf ocaml-4.06.0.tar.gz
cd ocaml-4.06.0
./configure
make world
make opt
umask 022
sudo make install
sudo make clean

10. Compile and install Unison

Look up the latest Unison release (https://github.com/bcpierce00/unison/releases), download the source code, compile and install.

As for now the procedure is as follows:

wget https://github.com/bcpierce00/unison/archive/v2.51.2.tar.gz
tar xvf v2.51.2.tar.gz
cd unison-2.51.2
make UISTYLE=text
sudo cp src/unison /usr/local/bin/unison
sudo cp src/unison-fsmonitor /usr/local/bin/unison-fsmonitor

11. Set Timezone if not done already

Check if /etc/localtime is a symlink. If not run dpkg-reconfigure tzdata and set your correct timezone.

12. (bonus!) Bind custom mount points to fix Docker for Windows and WSL differences (thanks to @nickjanetakis)

You might encounter various strange problems with volumes while starting up Docker containers from WSL.

If so, as a workaround you have to set up a special mountpoint inside /etc/fstab and start your container from there.

sudo mkdir /c
sudo mount --bind /mnt/c /c
echo "sudo mount --bind /mnt/c /c" >> ~/.bashrc && source ~/.bashrc

In order to automatically mount the volume without asking any password you can add a rule into your sudoers file.

sudo visudo 

Add the following at the bottom of the file, replacing "username" with your WSL username.

username ALL=(root) NOPASSWD: /bin/mount

12. Laradock? No problem!

If, as an example, you are using Laradock, you just need to follow the official documentation changing the sync strategy to 'unison' and adding the docker-compose.sync.yml in your .env file.

...
COMPOSE_PATH_SEPARATOR=;
COMPOSE_FILE=docker-compose.yml:docker-compose.dev.yml:docker-compose.sync.yml
...
DOCKER_SYNC_STRATEGY=unison

Then you need to add the following 'sync_args' line in the laradock/docker-sync.yml file, as follows:

...
sync_strategy: '${DOCKER_SYNC_STRATEGY}' # for osx use 'native_osx', for windows use 'unison'

sync_args: ['-perms=0'] #required for two way sync ie generators, etc
...

This will allow proper synchronization between the Linux containers and your Windows host that manages permissions in a different way.

Now you can start syncing using sync.sh provided with Laradock.

./sync.sh up nginx mysql phpmyadmin

Done!

You should now have a working version of docker-sync via the Unison strategy.

In your home directory in WSL you can link your projects from Windows and run docker-sync or docker-sync-stack.

The rest of your workflow should be the same as before in either Command Prompt, PowerShell, or some other Windows terminal.

FYI - An example of a docker-sync.yml file

version: "2"
options:
    verbose: true
syncs:
    app-unison-sync: # tip: add -sync and you keep consistent names als a convention
        sync_args: ['-perms=0'] #required for two way sync ie generators, etc
        sync_strategy: 'unison' 
        sync_host_ip: '127.0.0.1' #host ip isn't properly inferred
        sync_excludes: ['.gitignore', '.idea/*','.git/*', '*.coffee', '*.scss', '*.sass','*.log']
        src: './'