155

I mounted the container with this parameter:

-v /home/test/:/home/test

Inside /home/test in the host there is a symbolic link pointing to a /mnt/ folder.

But that link, although can be seen where is pointing to, seems broken inside the container:

root@f93f72b45013:/var/www/html# cd /home/test/ 
root@f93f72b45013:/home/test# ls -lrt 
total 11956 
lrwxrwxrwx. 1 root root 40 Jul 20 15:55 file -> /mnt/mountedfile/
root@f93f72b45013:/home/test# ls -lrt file/*
ls: cannot access file/*: No such file or directory

Is that even possible to be done in docker? I am not sure if is there a way to do it.

I know I can just directly mount where the symbolic link is pointing at but I was just wondering if this is possibe.

lapinkoira
  • 7,530
  • 7
  • 42
  • 80
  • I've heard of issues mapping to a `/mnt` endpoint, which may be host-specific -- the safest thing would be to avoid it if you can. – ldg Jul 20 '16 at 16:13
  • [Not an answer] One possible way to get rid of the symbolic link mess is to use `mount --bind` or `bind -t overlay`. These are native linux kernel features and works perfectly inside containers. https://unix.stackexchange.com/a/198591/423231 If you do not have plans for merging two directories, go for the bind mounts. – pPanda_beta Apr 10 '22 at 16:37

5 Answers5

201

Symlinks are a big challenge inside docker. In your case you can mount both directories:

-v /home/test/:/home/test -v /mnt/mountedfile:/mnt/mountedfile

For symbolic links to work both inside and outside the container, they have to be absolute paths and use exactly the same names.

In general, symlinks do not work inside docker. I found this the hard way.

Eric Tsai
  • 15
  • 7
Kemin Zhou
  • 5,271
  • 1
  • 37
  • 51
  • What to do if I have a symbolic link made in windows. The path may be c:\ (with a drive letter, semicolon and a backslash)? – Eitan Dec 10 '18 at 12:03
  • 4
    @Eitan Leave windows and embrace linux/unix systems when you wanna work with docker – Nam G VU Feb 12 '19 at 17:46
  • Yes. I have relized that Windows works wit CIF, and NFS is only on Windows Server versions (Why that basic is only on windows servers - only because that it costs, and Microsoft wants you to pay). – Eitan Feb 12 '19 at 18:18
  • 1
    Struggled a whole day with this trying to get the Laravel storage symlink working. For `docker-compose` configuration would be like this. `volumes: [./:/var/www, ./public/storage:/var/www/public/storage]`. Here, `public/storage` is a symlink to `./storage/app/public`. Thank you for the solution! – Yan Ivanov Feb 26 '19 at 22:47
  • I am able to use symbolic links with relative paths with docker 4.2.0 and windows 10. However, symbolic links with absolute paths do not work – J.Vo Jan 18 '22 at 02:15
27

One solution is to make Docker mount the original file, but use readlink -f which prints the file's actual location. This way, you can still reference the symlink location in your command, e.g.

docker run -it -v $(readlink -f /home/test/):/home/test/ ...

user2640621
  • 377
  • 4
  • 7
  • Not working - this results in the same missing symlinks – Ami Mahloof Nov 30 '17 at 19:51
  • On macOS: `perl -MCwd -le 'print Cwd::abs_path(shift)' "$path"` (from https://stackoverflow.com/questions/7665/how-to-resolve-symbolic-links-in-a-shell-script) – akauppi Feb 22 '19 at 20:45
  • 12
    I haven't tested it in Docker, but from playing around with readlink, it appears that this will work of /home/test/ **is** a symlink, but not if /home/test/ **contains** a symlink. – Justin Donnelly Nov 03 '19 at 19:40
  • how to put this variable into docker-compose file? – Ömer An Aug 02 '21 at 12:48
2

Hello thanks for your help In my case I was struggling activating https on my angular nginx app

docker run -p 80:80 -p 443:443 \
   --name test \
   -v /etc/letsencrypt/live/exemple.com:/etc/nginx/certs \
   -v /home/admin/nginx-default.conf:/etc/nginx/conf.d/default.conf:ro test

Does not mount links cert.pem and privkey.pem inside docker

But if I use all file path explicitly like that

docker run -p 80:80 -p 443:443 \
   --name test \
   -v /etc/letsencrypt/live/example.com/cert.pem:/etc/nginx/certs/cert.pem \
   -v /etc/letsencrypt/live/example.com/privkey.pem:/etc/nginx/certs/privkey.pem \
   -v /home/admin/nginx-default.conf:/etc/nginx/conf.d/default.conf:ro test

Everything worked I suppose you could do it exactly the same thing with docker-compose

Pavel Niedoba
  • 1,577
  • 2
  • 18
  • 34
ScorprocS
  • 175
  • 11
0

I can´t reply the previows answer but on a similar scenario where I need to get a linked file, setting up complete file path as you suggested on compose file worked out for me:

  - /opt/cert/ssl/live/example.com/cert.pem:/certs/cert.pem
  - /opt/cert/ssl/live/example.com/privkey.pem:/certs/privkey.pem

Files cert.pem and privkey.pem under example.com are both links to the files where certbot locates them.

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 22 '22 at 02:34
0

I think a good method to this issue.

In docker container, a symlink mounted from host cannot work properly. But a symlink created inside docker container work just fine. So, it is a good idea to mount the root (with absolute path) of interest into container first and then create symlink inside container with structures that satisfies ones' need. In this way, you are good to go.

Hope this helps.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 28 '22 at 11:38