mineshaftgap / d4m-nfs

Docker for Mac with NFS for performance improvements over osxfs
296 stars 26 forks source link

Cannot docker-compose up on laradock: Mounts denied #42

Closed voldedore closed 7 years ago

voldedore commented 7 years ago

Hello, I followed laradock's doc to build up my dev environment.

On docker-machine, everything worked just fine. That means that the docker-compose.yml does not have any error or misconfiguration (afaik at least)

But when I run it on Mac, the following error occurs:

$ docker-compose up -d nginx mysql
laradock_mysql_1 is up-to-date
Starting laradock_applications_1

ERROR: for applications  Cannot start service applications: Mounts denied: r more info.
.
 /Users/thevinh/docker_laradock/magento/www
is not shared from OS X and is not known to Docker.
You can configure shared paths from Docker -> Preferences... -> File Sharing.
See https://docs.docker.com/docker-for-mac/osxfs/#namespaces fo
ERROR: Encountered errors while bringing up the project.
  1. My D4M Settings:

Imgur

  1. d4m-nfs/etc/d4m-nfs-mounts.txt content:
/Users:/Users:504:20
/Volumes:/Volumes
/private:/private
  1. /tmp/d4m-mount-nfs.sh content:
ln -nsf /tmp/d4m-apk-cache /etc/apk/cache
apk update
apk add nfs-utils sntpc
rpcbind -s > /dev/null 2>&1

DEFGW=$(ip route|awk '/default/{print $3}')
FSTAB="\n\n# d4m-nfs mounts\n"

if true && ! $(grep ':/mnt' /tmp/d4m-nfs-mounts.txt > /dev/null 2>&1); then
  mkdir -p /mnt

  FSTAB="${FSTAB}${DEFGW}:/Users/thevinh /mnt nfs nolock,local_lock=all 0 0"
fi

if [ -e /tmp/d4m-nfs-mounts.txt ]; then
  while read MOUNT; do
    DSTDIR=$(echo "$MOUNT" | cut -d: -f2)
    mkdir -p ${DSTDIR}
    FSTAB="${FSTAB}\n${DEFGW}:$(echo "$MOUNT" | cut -d: -f1) ${DSTDIR} nfs nolock,local_lock=all 0 0"
  done < /tmp/d4m-nfs-mounts.txt
fi

if ! $(grep "d4m-nfs mounts" /etc/fstab > /dev/null 2>&1); then
    echo adding d4m nfs config to /etc/fstab:
    echo -e $FSTAB | tee /etc/fstab
else
    echo d4m nfs mounts already exist in /etc/fstab
fi

sntpc -i 10 ${DEFGW} &

sleep .5
mount -a
touch /tmp/d4m-done
  1. /tmp/d4m-nfs-mounts.txt content
/Users:/Users:504:20
/Volumes:/Volumes
/private:/private
  1. /etc/exports content
# VAGRANT-BEGIN: 504 115ebe2e-e327-401a-b203-c9c57be985e0
#"/Users/thevinh/www" 192.168.10.10 -alldirs -mapall=504:20
# VAGRANT-END: 504 115ebe2e-e327-401a-b203-c9c57be985e0
# docker-machine-nfs-begin default #
#/Users 192.168.99.100 -alldirs -mapall=504:20
# docker-machine-nfs-end default #

# d4m-nfs exports

"/Users" -alldirs -mapall=504:20 localhost
"/Volumes" -alldirs -mapall=504:20 localhost

Running d4m-nfs.sh on bash (not zsh which is my default sh prog) returns:

bash-3.2$ ./d4m-nfs.sh
[d4m-nfs] You will need to provide your Mac password in order to setup NFS.
Password:
# d4m-nfs exports

"/Users" -alldirs -mapall=504:20 localhost
"/Volumes" -alldirs -mapall=504:20 localhost

[d4m-nfs] Copy the Moby VM APK Cache back.
[d4m-nfs] Create the script for Moby VM.
[d4m-nfs] Start and restop nfsd, for some reason restart is not as kind.
Stopping the nfsd service (use 'disable' to make permanent)
/System/Library/LaunchDaemons/com.apple.nfsd.plist: Operation not permitted while System Integrity Protection is engaged
The nfsd service is already running.
[d4m-nfs] Wait until NFS is setup.
[d4m-nfs] Wait until D4M is running.
[d4m-nfs] Copy back the APK cache.

cp: /tmp/d4m-apk-cache/*: No such file or directory

# d4m-nfs

I don't think the Docker native for Mac recognizes what we have in the NFS settings, it just read what it has in the File Sharing settings.

Is that mac's System Integrity Protection causing this issue ?

My other info:

if-kenn commented 7 years ago

@voldedore is there any reason for you to be mounting /Volumes and /private?

The location /Volumes on a Mac is actually just a symlink to /, and it is never good to export a symlink. On top of that, with NFS, you can not export child directories which are on the same file system, and since you are both /Users and /private this could cause problems. If not, then I would suggest to change your d4m-nfs/etc/d4m-nfs-mounts.txt file to this:

/Users/thevinh:/Users/thevinh:504:20

You probably will also have to clean up your /etc/exports to remove all the lines from # d4m-nfs exports down.

if-kenn commented 7 years ago

@voldedore it appears as though you are having the same problem as others, please review this from the README.md:

https://github.com/IFSight/d4m-nfs/commit/45f1628be62f91c5c7aaff9a97de931f5b5679fb

voldedore commented 7 years ago

@if-kenn Thanks for your quick reply and sorry for this late response, I had a day off yesterday.

You're right, I don't really need /Volumes and /private to be mounted for my dev env. So I removed /private and /Volumes from the d4m-nfs/etc/d4m-nfs-mounts.txt

Things seem not to work, yet.

  1. My D4M settings has not changed.

  2. What my d4m-nfs/etc/d4m-nfs-mounts.txt has now is:

/Users:/Users:504:20
  1. My /tmp/d4m-mount-nfs.sh
ln -nsf /tmp/d4m-apk-cache /etc/apk/cache
apk update
apk add nfs-utils sntpc
rpcbind -s > /dev/null 2>&1

DEFGW=$(ip route|awk '/default/{print $3}')
FSTAB="\n\n# d4m-nfs mounts\n"

if true && ! $(grep ':/mnt' /tmp/d4m-nfs-mounts.txt > /dev/null 2>&1); then
  mkdir -p /mnt

  FSTAB="${FSTAB}${DEFGW}:/Users/root /mnt nfs nolock,local_lock=all 0 0"
fi

if [ -e /tmp/d4m-nfs-mounts.txt ]; then
  while read MOUNT; do
    DSTDIR=$(echo "$MOUNT" | cut -d: -f2)
    mkdir -p ${DSTDIR}
    FSTAB="${FSTAB}\n${DEFGW}:$(echo "$MOUNT" | cut -d: -f1) ${DSTDIR} nfs nolock,local_lock=all 0 0"
  done < /tmp/d4m-nfs-mounts.txt
fi

if ! $(grep "d4m-nfs mounts" /etc/fstab > /dev/null 2>&1); then
    echo adding d4m nfs config to /etc/fstab:
    echo -e $FSTAB | tee /etc/fstab
else
    echo d4m nfs mounts already exist in /etc/fstab
fi

sntpc -i 10 ${DEFGW} &

sleep .5
mount -a
touch /tmp/d4m-done
  1. My /tmp/d4m-nfs-mounts.txt:
/Users:/Users:504:20
  1. My /etc/exports
# VAGRANT-BEGIN: 504 115ebe2e-e327-401a-b203-c9c57be985e0
#"/Users/thevinh/www" 192.168.10.10 -alldirs -mapall=504:20
# VAGRANT-END: 504 115ebe2e-e327-401a-b203-c9c57be985e0
# docker-machine-nfs-begin default #
#/Users 192.168.99.100 -alldirs -mapall=504:20
# docker-machine-nfs-end default #

# d4m-nfs exports

"/Users" -alldirs -mapall=504:20 localhost
ERROR: for applications  Cannot start service applications: Mounts denied: r more info.
.
 /Users/thevinh/docker_laradock/magento/www
is not shared from OS X and is not known to Docker.
You can configure shared paths from Docker -> Preferences... -> File Sharing.
See https://docs.docker.com/docker-for-mac/osxfs/#namespaces fo
ERROR: Encountered errors while bringing up the project.

Quick edit: I tried also what you suggested: Changing d4m-nfs/etc/d4m-nfs-mounts.txt to

/Users/thevinh:/Users/thevinh:504:20

The very same error occurs.

if-kenn commented 7 years ago

Please be sure to restart Docker since d4m-nfs does not restart it for you if it is already running.

voldedore commented 7 years ago

@if-kenn Restarting Docker doesn't change anything either.

The d4m-nfs.sh script returns :

bash-3.2$ ./d4m-nfs.sh
[d4m-nfs] You will need to provide your Mac password in order to setup NFS.
Password:
# d4m-nfs exports

"/Users/thevinh" -alldirs -mapall=504:20 localhost

[d4m-nfs] Copy the Moby VM APK Cache back.
rm: /tmp/d4m-apk-cache/.gitignore: Permission denied
rm: /tmp/d4m-apk-cache: Permission denied
cp: /tmp/d4m-apk-cache/.gitignore: Permission denied
[d4m-nfs] Create the script for Moby VM.
[d4m-nfs] Start and restop nfsd, for some reason restart is not as kind.
Stopping the nfsd service (use 'disable' to make permanent)
/System/Library/LaunchDaemons/com.apple.nfsd.plist: Operation not permitted while System Integrity Protection is engaged
The nfsd service is already running.
[d4m-nfs] Wait until NFS is setup.
[d4m-nfs] Wait until D4M is running.
[d4m-nfs] Setup 'screen' to work properly with the D4M tty, while at it name it 'd4m'.
[d4m-nfs] Run Moby VM d4m-nfs setup script.
[d4m-nfs] Waiting until d4m-nfs setup is done.
[d4m-nfs] Copy back the APK cache.

cp: /tmp/d4m-apk-cache/*: No such file or directory

# d4m-nfs

With the Docker for Mac's (D4M) current implementation of osxfs, depending on how read and write heavy containers are on mounted volumes, performance can be abismal.

d4m-nfs blantently steals from the way that DockerRoot/xhyve used NFS mounts to get around i/o performance issues. With this implementation D4M appears to even outperform DockerRoot/xhyve under a full Drupal stack (mariadb/redis/php-fpm/nginx/varnish/haproxy), including persistent MySQL databases.

The advantage of this over a file sync strategy is simpler, less overhead and not having to duplicate files.

In order to make use of NFS, you will want to run ./d4m-nfs.sh before bringing up your containers, **please note this must be run via the bash shell and not the sh shell**. You will either need to change your volume paths to use /mnt, or configure the mounts in etc/d4m-nfs-mounts.txt. Look at the example directory for docker or docker-compose simple examples and an example d4m-nfs-mounts.txt.

By default, if the script doesn't find any other volumes bound to /mnt in your etc/d4m-nfs-mounts.txt, it will mount your home directory (eg. /Users/username) on /mnt to be exposed for the container. If you'd like to disable this, you may set the environment variable AUTO_MOUNT_HOME to false.

Alpine Linux NFS packages are now cached so that d4m-nfs can be used when not online. In order for this to work, you must of run it once before while online.

You can now specify what mounts you want in the d4m-nfs-mounts.txt file. Note that if you do this, you need to make sure that it does not conflict with D4M settings, in other words if you want to have /Users be served by NFS instead of osxfs you will need to remove it from the D4M Preferences -> File Sharing. The /tmp share must stay since that is how d4m-nfs exchanges information with the D4M Moby VM.

This is the default file sharing:
![D4M Default File Sharing](/examples/img/d4m-default-file-sharing.png?raw=true "D4M Default File Sharing")

Please make sure that /tmp is still shared:
![D4M Minimal File Sharing](/examples/img/d4m-min-file-sharing.png?raw=true "D4M Minimal File Sharing")

Please note:
* To connect to the D4M moby linux VM use: screen -r d4m
* To disconnect from the D4M moby linux VM tty screen session use Ctrl-a d.
* To run d4m-nfs faster and/or offline, leave the files in d4m-apk-cache and the hello-world image.
* If you switch between D4M stable and beta, you might need to remove files in d4m-apk-cache and the hello-world image.

# Opening Github Issues
**Please keep in mind that everyone's environment is quite unique and this make helping people much harder. In that spirit when opening an issue, please provide the following:**

1. Please ensure you have looked at the "examples" directory in the root of this site.
2. screenshot of Docker for Mac's Preferences -> File Sharing
3. attachment of d4m-nfs/etc/d4m-nfs-mounts.txt
4. attachment of /tmp/d4m-mount-nfs.sh
5. attachment of /tmp/d4m-nfs-mounts.txt
6. attachment of /etc/exports

# Use Stable Docker for Mac channel
Currently d4m-nfs is known to work on the stable channel of 'Docker for Mac' both versions 1.12 and 1.13, we cannot guarantee how it will work on the beta channel of 'Docker for Mac'.  Please use the stable channel of Docker for Mac https://docs.docker.com/docker-for-mac/

# Integration with text editors

## Sublime Text

If you use Sublime, please checkout the plugin by Yves to help with auto reloads on file changes - https://github.com/yvess/sublime_d4m

## Atom

The easiest way to enable auto reloading is to install [on-save](https://atom.io/packages/on-save) package and set it up with this config:

```json
[
  {
    "srcDir": ".",
    "files": "**/**",
    "command": "screen -S d4m -p 0 -X stuff \"touch `pwd`/${srcFile}\"\r"
  }
]


Do I need to stop the nfsd before running the script ?
if-kenn commented 7 years ago

@voldedore you are using /Users, I would suggest using /Users/thevinh and then follow the advice previously.

if-kenn commented 7 years ago

@voldedore I think I also saw you make a post on the net about Mac and nfsd restart problem, if it was related to df4-nfs, it is now fixed via https://github.com/IFSight/d4m-nfs/commit/f1dbc6e157776b5d122782b372b04946c22f53a1

voldedore commented 7 years ago

@if-kenn Yes, I'm the author of that post. I think it was related to the nfsd of my Mac because we have used nfs for folder sharing in another vagrant-related project.

After giving enough time to read what we have in the d4m-nfs bash scripts, I just don't know why the script (d4m nfs) didn't success to restart the nfsd service. And I'm afraid it causes this issue.

I will try to update your fix this Monday and feedback very soon then. (The Mac is in my workplace)

PS: I edited my post above about the /Users/thevinh, but FYI, it remains the same with /Users

if-kenn commented 7 years ago

While d4m-nfs might of thrown the same error as you posted elsewhere, it is not the root cause it is a Mac OS update, this explains it much more: https://clburlison.com/10.12.4-locationd/

voldedore commented 7 years ago

@if-kenn After pulling your fix. The script (d4m-nfs.sh) doesn't throw any error anymore. That's really a good news.

But the docker-compose up still throws

ERROR: for applications  Cannot start service applications: Mounts denied: r more info.
.
 /Users/thevinh/docker_laradock/magento/www
is not shared from OS X and is not known to Docker.
voldedore commented 7 years ago

@if-kenn I finally found the reason of this issue and how to fix it.

Reason:

Although all settings are ok (as instruction which was well constructed too), it conflicts with docker-machine-nfs tool.

I imagine 1 folder could not be shared to 2 destinations (1 for D4M, and another for docker machine). But when I re-run the docker-machine-nfs script, it throws

exports:11: /Users conflicts with existing export /Users/thevinh

How to fix (for those have used both docker-machine-nfs and d4m-nfs)

  1. Change docker-machine-nfs shared folder to another than what we have in the etc/d4m-nfs-mounts.txt:
docker-machine-nfs <machine-name> -f --nfs-config="-alldirs -mapall=<uid:gid>" --shared-folder=/other/than/what/d4m-nfs-mounts.txt/has
  1. etc/d4m-nfs-mounts.txt:
/your/shared/folder/path:/your/shared/folder/path
  1. Then re-run d4m-nfs.sh (maybe we should clear some d4m-nfs settings in the /etc/exports before this step)

  2. docker-compose of docker run as normal

This is finally not an issue of d4m-nfs (except the restart nfsd command with 10.12.4). I think we can close it here. Thank @if-kenn for your quick supports.


I think it would be clearer and I would suggest to add that conflict with another nfs tool (in my case: docker-machine-nfs) in the README.md for anyone who has the similar issue.

if-kenn commented 7 years ago

@voldedore I am glad you got it working, I will close this issue.

From the large number of people using this repo, I have not hear any trying to run both docker-machine and Docker for Mac, since you would generally use one or the other, because of this, at this time I don't think it warrants information in the README.

voldedore commented 7 years ago

You're right. I was using docker-machine because the slow performance of d4m traditional osxfs.

Now with d4m-nfs, there will be no reason to stick with docker-machine anymore (nor the docker-machine-nfs)