Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
How does native_osx work with OSXFS and is still native speed fast?
First, take a look at this diagram:
There are some important keypoints to notice here:
- we use OSXFS to mount your local host folder into the sync-container.
- we do not mount this in the app-container directly, since this would lead to infamously horrible performance.
- instead of directly mounting
/host_syncin the app-container we setup a 2-way-sync inside the sync-container using Unison. This ensures that the actual READ/WRITE performance on the
/app_syncfolder is native-speed fast.
- this makes all operations on
/app_syncbe asynchronous with
/host_sync, since writing and reading on
/app_syncdoes not rely on any OSXFS operation directly, but shortly delayed and asynchronous.
- we mount
/app_syncto your app_container - since this happens in hyperkit, it's a Docker LINUX-based native mount, thus running at native-speed.
- Your application now runs like there was no sync at all.
Why use OSXFS in the first place (instead of
unison as in the unison strategy) to sync from the host to the sync-container
There are several reasons, one of the most important being the performance. Since MacOS/OSX has very bad filesystem events support on HFS/APFS, watching the file-system for changes using
fswatch was causing a heavy CPU load. This CPU load is very significant, even on modern high-end CPUs (like a i7 4770k / 3.5GHz).
The second issue was dependencies. With native_osx you do not need to install anything on your host OS except the docker-sync gem. So no need to compile unox or install unison manually, deploy with brew and fail along the way - just keeping you system clean.
Is this strategy absolutely bullet proof?
No, it is not. But it has been pretty battle proven already - the main issue is https://github.com/EugenMayer/docker-sync/issues/410 - so sometimes OSXFS just stops triggering FS events in Hyperkit, thus in the sync-container. This leads to an issue with our sync, since the
unison daemon inside the app-sync container relies on those events to sync the changes (it does not have the ability to poll, which would be disastrous performance-wise, anyway).