docker / for-linux

Docker Engine for Linux
https://docs.docker.com/engine/installation/
756 stars 85 forks source link

Docker(-compose) not working with fuse #1090

Open wickeduk opened 4 years ago

wickeduk commented 4 years ago

Expected behavior

Docker-compose to start container

Actual behavior

ERROR: for mq Cannot start service mq: error while creating mount source path '/home/dav/work/dec/code/...[client and project obscured]': mkdir /home/dav/work/dec: file exists

Nonsense error - it shouldn't be trying to create a directory here, this is a base directory for the fuse encfs mountpoint for decrypted data

See other reports on win: https://github.com/docker/for-win/issues/5516 for similar incorrect outputs of this error

The error message doesn't make sense and probably should also be fixed to output the real problem

Probable duplicate (fuse being the common denominator): https://github.com/docker/for-linux/issues/936

This hasn't been looked at or commented on 6 months after it was raised, hence the need to raise a more general bug.

It's likely docker and fuse are not playing nicely. This is important as I wish to keep my client's code on an encrypted area of the disk in case of theft, and at the moment when docker-compose is run I need to move it outside that area.

Steps to reproduce the behavior

Cannot use my example (starting mq) as it belongs to a client, but can reuse example in:

https://github.com/docker/for-linux/issues/936

Behaviour of demo Container doesn't start while inside (either project/cwd or both?) encfs mountpoint, move it outside it's happy, move it back inside it fails again.

dec is a an encfs created mountpoint (decrypted directory) - create with encfs

e.g. encfs /home/dav/work/enc /home/dav/work/dec

enter then enter password twice

dav@linux-tddj:~/work/dec> mkdir test
dav@linux-tddj:~/work/dec> cd test
dav@linux-tddj:~/work/dec/test> cat << EOF > docker-compose.yml
> version: '3'
> services:
>   web:
>     image: yiisoftware/yii2-php:7.2-apache
>     volumes:
>       - .:/app
>     ports:
>       - 80:80
>     environment:
>       YII_ENV: debug
>       PHP_USER_ID: 1000
> EOF
dav@linux-tddj:~/work/dec/test> cat docker-compose.yml 
version: '3'
services:
  web:
    image: yiisoftware/yii2-php:7.2-apache
    volumes:
      - .:/app
    ports:
      - 80:80
    environment:
      YII_ENV: debug
      PHP_USER_ID: 1000
dav@linux-tddj:~/work/dec/test> docker-compose up
Creating network "test_default" with the default driver
Pulling web (yiisoftware/yii2-php:7.2-apache)...
7.2-apache: Pulling from yiisoftware/yii2-php
bf5952930446: Pull complete
a409b57eb464: Pull complete
3192e6c84ad0: Pull complete
43553740162b: Pull complete
d8b8bba42dea: Pull complete
eb10907c0110: Pull complete
10568906f34e: Pull complete
7a8a58d5365a: Pull complete
0d7d944c357e: Pull complete
c523214ebbcb: Pull complete
09a7e2a894fa: Pull complete
0a5b0b189842: Pull complete
5a971be0edbf: Pull complete
41998deb7b34: Pull complete
2ddd5faa7048: Pull complete
979040d61492: Pull complete
d95b89e53118: Pull complete
4e720d828f11: Pull complete
39469e07f6e6: Pull complete
db08b6f93b90: Pull complete
95a91f499b7d: Pull complete
edda56d91453: Pull complete
013d45402ceb: Pull complete
a799cadf5f4d: Pull complete
Digest: sha256:b704f660f70edf5fcccfffec0c5a650fe576f316f36e2c8badb6cad42fecf80e
Status: Downloaded newer image for yiisoftware/yii2-php:7.2-apache
Creating test_web_1 ... error

ERROR: for test_web_1  Cannot start service web: error while creating mount source path '/home/dav/work/dec/test': mkdir /home/dav/work/dec: file exists

ERROR: for web  Cannot start service web: error while creating mount source path '/home/dav/work/dec/test': mkdir /home/dav/work/dec: file exists
ERROR: Encountered errors while bringing up the project.
dav@linux-tddj:~/work/dec/test> cd ..
dav@linux-tddj:~/work/dec> mv test ..
dav@linux-tddj:~/work/dec> cd ../test
dav@linux-tddj:~/work/test> docker-compose up
Recreating test_web_1 ... done
Attaching to test_web_1
web_1  | AH00112: Warning: DocumentRoot [/app/web] does not exist
web_1  | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.20.0.2. Set the 'ServerName' directive globally to suppress this message
web_1  | AH00112: Warning: DocumentRoot [/app/web] does not exist
web_1  | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.20.0.2. Set the 'ServerName' directive globally to suppress this message
web_1  | [Sat Aug 22 08:15:23.658845 2020] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.38 (Debian) configured -- resuming normal operations
web_1  | [Sat Aug 22 08:15:23.658966 2020] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
^CGracefully stopping... (press Ctrl+C again to force)
Stopping test_web_1   ... 
Killing test_web_1    ... error

ERROR: for test_web_1  Cannot kill container: 2d8d5fb89b2af816ed47cc1a2f75ef3a3f45cf8bb47fac7202cb961dd2bdddf8: Container 2d8d5fb89b2af816ed47cc1a2f75ef3a3f45cf8bb47fac7202cb961dd2bdddf8 is not running
dav@linux-tddj:~/work/test> cd ..
dav@linux-tddj:~/work> mv test dec/
dav@linux-tddj:~/work> cd dec/
dav@linux-tddj:~/work/dec> cd test
dav@linux-tddj:~/work/dec/test> docker-compose up
Recreating test_web_1 ... error

ERROR: for test_web_1  Cannot start service web: error while creating mount source path '/home/dav/work/dec/test': mkdir /home/dav/work/dec: file exists

ERROR: for web  Cannot start service web: error while creating mount source path '/home/dav/work/dec/test': mkdir /home/dav/work/dec: file exists
ERROR: Encountered errors while bringing up the project.
dav@linux-tddj:~/work/dec/test> 

Output of docker version:

Client:
 Version:           19.03.11
 API version:       1.40
 Go version:        go1.14.2
 Git commit:        42e35e61f352
 Built:             Tue Jun  2 12:00:00 2020
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          19.03.11
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.14.2
  Git commit:       42e35e61f352
  Built:            Tue Jun  2 12:00:00 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.1.3_catatonit
  GitCommit:  

Output of docker info:

Client:
 Debug Mode: false

Server:
 Containers: 2
  Running: 0
  Paused: 0
  Stopped: 2
 Images: 3
 Server Version: 19.03.11
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: oci runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
 init version: 
 Security Options:
  apparmor
  seccomp
   Profile: default
 Kernel Version: 5.3.18-lp152.36-default
 Operating System: openSUSE Leap 15.2
 OSType: linux
 Architecture: x86_64
 CPUs: 8
 Total Memory: 15.45GiB
 Name: linux-tddj
 ID: JUC4:X3EK:PRYM:3SBZ:NVD2:BYQT:6IGX:MNH2:LGYA:MWPK:UUPK:X3ZJ
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

WARNING: No swap limit support

Additional environment details (AWS, VirtualBox, physical, etc.)

wickeduk commented 4 years ago

Additional:

docker-compose version docker-compose version 1.25.1, build a82fef0 docker-py version: 4.2.0 CPython version: 3.6.10 OpenSSL version: OpenSSL 1.1.1d 10 Sep 2019

thaJeztah commented 4 years ago

Not sure if this can be resolved. If I understand the problem correctly, the reason this is failing is that the encfs filesystem is only accessible by the current user, and not accessible by other users.

When you bind-mount a directory (-v <host-path>:<container-path>), that bind-mount is handled on the daemon side (and from the host on which the daemon runs); the daemon runs as another user (root most likely), and probably doesn't have access to the files in that mount.

The reason docker is attempting to create the path, is that the short-hand -v <host-path>:<container-path> notation for bind-mounts will attempt to create the host-path if it's missing (I suspect in this case it may get an error that it interprets as the path doesn't exist because it has no access).

You can try using the long-form (--mount src=/host/path,dest=/container-path) notation (or the equivalent in compose: https://docs.docker.com/compose/compose-file/#volumes, which is available on compose-file version 3.2 and up), which won't attempt to create the host-path, but I suspect it would still fail if it doesn't have access to the decrypted files.

thaJeztah commented 4 years ago

Perhaps it works if you try using the --public for the encfs; https://unix.stackexchange.com/a/249318

wickeduk commented 4 years ago

Yes --public solves it.

There is also the comment on the encfs man page: Warning: In order for this to work, encfs must be run as root -- otherwise it will not have the ability to change ownership of files. I recommend that you instead investigate if the fuse allow_other option can be used to do what you want before considering the use of --public.

I'm not sure if that's --allow_other or something else but I'll give that a try as well.

wickeduk commented 4 years ago

Informed the user on the related issue to look to see if there is something similar for unionfs.

I guess it would be worth documenting the issue with user only mounted filesystems in a FAQ somewhere so others don't raise issues.

Other than that I think this is resolved now so can be closed.