Reputation: 8998
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.
Upvotes: 222
Views: 188996
Reputation: 3194
It's doable but you must "think container" if you have symlinks to random files in random locations, then it's actually may not be worth it.
But consider this working worth scenario:
You have 2 folders, one with real files, and one with symlinks to real:
/static-data/
|_ data-file1.dat
|_ data-file2.dat
|
|__index/
|_a.txt
|_b.txt
/other/
|_ data-file1.dat -> /static-data/data-file1.dat
|_ data-file2.dat -> /static-data/data-file2.dat
|
|__index/
|_a.txt
|_b.txt
Now if you mount /other:/data
for a container when you ls -lah /data
you'll see broken links because /static-data
doesn't exist in the container. The solution is to create broken links in the Host, assuming /other
is not directly important to host to be broken
so your new structure would be:
/other/
|_ data-file1.dat -> /mirror/data-file1.dat
|_ data-file2.dat -> /mirror/data-file2.dat
|
|__index/
|_a.txt
|_b.txt
You then need 2 mount records
/other:/data
/static-data:/mirror
Now when you run a container, the symlinks that are broken for Host, are not broken in the container so /data/data-file1.dat -> /mirror/data-file1.dat
and container has mounted /mirror
thus the symlink is pointing to /static-data/data-file1.dat
from the host
If you don't want broken symlinks in the host then you could mount both directories as
/other:/data
/static-data:/static-data
Now the links can be valid in Host and the container. As you can see this is possible, I tested that and it works, but it's worth only for obvious clusters of files. If it's all random, the you would end-up mounting a lot of dirs or maybe single files, to reflect Host structure in the container
Upvotes: 8
Reputation: 11
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.
Upvotes: 0
Reputation: 31
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.
Upvotes: 3
Reputation: 377
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
Upvotes: 12
Reputation: 6891
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.
Upvotes: 280
Reputation: 467
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/ ...
Upvotes: 36