I am conducting all my current development using docker containers, and if under Linux this approach does not cause any problems, then under OS X some moments can take an incredible amount of time and effort.
I want to tell about one of these moments.
In my case, the development using docker looks like this: all the software I need is raised on the container. Folders with a working project are transferred from the host system to the container. In the container for the autobid, either
grunt with
grunt-contrib-watch , or
watchify is configured , or sometimes the scriptor just hangs using
inotify-tools .
In the case of web development, the cycle is simple: I manage the project files on the Mac, watch utilities start the build, livereload updates the web page. But with this approach, a problem immediately arises - the vboxsf file system included in Virtualbox Guest Additions is incredibly slow, from here:
')
- watch utilities begin to load the system by 200 percent;
- even a small build — for example, a simple file concatenation begins to take tens of seconds.
This is unacceptable.
Fast googling showed that
nfs works many times faster than vboxfs. Setting up an nfs server under OSX is quick and easy.
Then you need to transfer the host's OSX address to the docker ip so that you can hook up the file system:
In the container, you need to roll the nfs client and download the necessary folders:
And indeed, two problems go away:
- CPU load near zero;
- build now goes very fast.
But a new problem appears - inotify events of the file system nfs, 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 sideHang the 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 bash web server hanging on port 3080, for each request it executes the date and touch commands of the watchhelper.tmp file, which must be placed outside the sources of your project, which must be added to watch.
Below I will explain why outside the source code of the project .
- The touch command “touching” a file causes an inotify event leading to an assembly;
- The date command is convenient for testing, its output is the answer of this server.
You can check what works by:
And, hooray - in the browser we see the time, and in the container - the instantaneous triggering of watch utilities.
OSX sideInstall fswatch:
brew install fswatch
Run:
fswatch-run /Users/user/my_web_project/src "curl http://`boot2docker ip 2>&1 | sed -n 2,2p | awk -F' ' '{print $9}'`:3080"
Now, if you change any file in the / Users / user / my_web_project / src folder, the server in the container will be called up, which “touches” the file, which in turn will cause a build.
The watchhelper.tmp file must be placed outside the project source, for the reason that nfs still skips inotify events and the source file will cause an eternal loop of curl touch touch events.
I regularly add various issues of setting up a container docker for a makos to the project on the
istarkov / docker gitkhab .
If the topic will cause a response - I will write a few more noteworthy things when using docker containers when developing on OS X.
PS:
I was informed about a small problem with this approach.
If the editor sublime text 3 and the length of the file after making changes remained the same, then the changes do not fall into the client's nfs, i.e. in docker.
You can cure it in the sublime settings, in the Preferences.sublime-settings file, change the {"atomic_save": true} to {{atomic_save ": false} and all will work as it should
PPS:
In the comments,
descentspb gave a simpler solution to this problem, I recommend using its approach.