Docker containers for web developer under OS X

I conduct all my current development using docker containers, and if under Linux this approach does not cause any problems, under OS X some moments can take an incredible amount of time and effort.

I want to talk about one of these moments.

In my case, development using docker looks like this: all the software I need is raised on the container. Folders with the working project are mapped from the host system to the container. In the container for autobuild, either grunt is configured with grunt-contrib-watch , or watchify , or sometimes a script using inotify-tools just hangs .

In the case of web development, the cycle is simple: I edit the project files on the poppy, watch utilities start the build, livereload updates the web page. But with this approach, the problem immediately arises - the vboxsf file system included in Virtualbox Guest Additions is incredibly slow, hence:

  • watch utilities start loading the system of percent by 200;
  • even a small assembly - for example, a simple concatenation of files starts to take tens of seconds.

This is unacceptable.

A quick google showed that nfs is several times faster than vboxfs. Setting up an nfs server under OSX is quick and easy.

#включить nfs сервер
sudo nfsd enable
#отредактировать файл с папками для шаринга
sudo vi /etc/exports
# добавить папки которые надо сделать доступными например  /Users/user/my_web_project -mapall=ice
#проверить что нет ошибок
sudo nfsd checkexports
#проверить что папки подцпились
showmount -e

Next, you need to transfer the host OSX address to docker ip so that you can pick up the file system:

#получить ip хоста висящего на интерфейсе virtual box
HOST_IP=`ifconfig vboxnet0 | tail -1 | awk '{print $2}'`
#передать в контейнер
docker run --name smap -p 3080:3080 -e HOST_IP="$HOST_IP" -d -t sentimeta/node_scikit_image

In the container, you need to roll nfs of the client and mount the necessary folders:

#накатить клиента
sudo apt-get update
sudo apt-get install nfs-common
#замаунтить nfs osx папку
sudo mount -o nolock "$HOST_IP":/Users/user/my_web_project ~/my_web_project

And indeed, two problems go away:

  • CPU load near zero;
  • build is now very fast.

But a new problem appears - inotify events of the nfs file system, on which all watch utilities sit, pass, but with delays of 10-20 seconds.

This is unacceptable.

Therefore, it was decided to start catching inotify events on the host machine and transfer information to the docker container.

To solve the problem, I used the following utilities:

Docker side We hang http web server on port 3080:

watch -n0 'printf "HTTP/1.1 200 OK\n\n$(date && touch /home/user/my_web_project/watchhelper.tmp)\n" | nc -l -p 3080 >/dev/null && date'

This is a real web server on bash hanging on port 3080, for each request it executes the date and touch command of the watchhelper.tmp file, which must be put outside the sources of your project, which must be added to watch. Below I will explain why it is outside the source code of the project .

  • touch the command “touching” the file causes an inotify event leading to the assembly;
  • date command is convenient for testing, its output is the answer of this server.

Check that it works, you can do this:

  • On OSX, we get the boot2docker address of the virtual machine:

    boot2docker ip 2>&1 | sed -n 2,2p | awk -F' ' '{print $9}'

And, hooray - in the browser we see the time, and in the container - instant operation of the watch utilities.

OSX side
Install fswatch:

brew install fswatch 

We launch:

fswatch-run /Users/user/my_web_project/src "curl http://`boot2docker ip 2>&1 | sed -n 2,2p | awk -F' ' '{print $9}'`:3080"

Now, when changing any file in the / Users / user / my_web_project / src folder, the web server raised in the container will be called up, which will “touch” the file, which in turn will cause the build.

The watchhelper.tmp file must be located outside the project sources because nfs nevertheless skips inotify events and the file lying in the sources will cause an eternal loop of curl touch touch events.

Various issues of configuring docker containers for macos I occasionally add to the project on the istarkov / docker github .

If the topic elicits a response, I will write a few more things to note when using docker containers when developing on OS X.

I was informed about a small problem with this approach.
If the editor is sublime text 3 and the file length after making the changes remains the same, then the changes do not fall into the nfs client, i.e. in docker.

You can cure it like this - in the sublime settings, in the Preferences.sublime-settings file change the goose {{atomic_save ": true} to {" atomic_save ": false} and everything will work as it should.

In the comments descentspb gave a simpler solution to this problem, I recommend using his approach.

Also popular now: