在Docker容器中装载包含符号链接的主机目录

fslejnso  于 2023-01-12  发布在  Docker
关注(0)|答案(6)|浏览(175)

我使用以下参数挂载容器:
-v /主页/测试/:/主页/测试
在主机的/home/test中有一个指向/mnt/文件夹的符号链接。
但是,尽管可以看到所指向的位置,但在容器内部,这种联系似乎已断开:

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

这在docker中有可能实现吗?我不确定是否有办法实现。
我知道我可以直接挂载符号链接指向的地方,但我只是想知道这是否可能。

6fe3ivhb

6fe3ivhb1#

在Docker中,符号链接是一个很大的挑战。在您的情况下,您可以同时挂载两个目录:

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

要使符号链接在容器内部和外部都能工作,它们必须是绝对路径并使用完全相同的名称。
一般来说,符号链接在Docker中不起作用,我发现这是一条很难的路。

eqoofvh9

eqoofvh92#

一个解决方案是让Docker挂载原始文件,但使用readlink -f打印文件的实际位置。这样,您仍然可以在命令中引用符号链接位置,例如:
docker run -it -v $(readlink -f /home/test/):/home/test/ ...

5kgi1eie

5kgi1eie3#

你好,谢谢你的帮助,在我的情况下,我很难激活https对我的角nginx应用程序

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

未在Docker内安装链接证书pem和私钥pem
但如果我像这样显式使用所有文件路径

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

一切正常,我想你可以用docker-compose做同样的事情

5fjcxozz

5fjcxozz4#

我不能回答previows的答案,但在类似的情况下,我需要得到一个链接文件,设置完整的文件路径,因为你建议的组成文件为我工作:

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

example.com下的文件cert.pemprivkey.pem都是指向certbot所在文件的链接。

lnvxswe2

lnvxswe25#

这是可行的,但你必须“思考容器”,如果你有符号链接到随机位置的随机文件,那么它实际上可能不值得。
但考虑一下这个工作价值场景:
您有2个文件夹,一个包含真实的文件,另一个包含指向实际文件的符号链接:

/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

现在,如果您装载/other:/data
对于一个容器,当你ls -lah /data时,你会看到断开的链接,因为/static-data不存在于容器中。解决方案是在主机中创建断开的链接,假设/other对主机断开并不直接重要,那么你的新结构将是:

/other/
|_ data-file1.dat -> /mirror/data-file1.dat 
|_ data-file2.dat -> /mirror/data-file2.dat 
|
|__index/
   |_a.txt
   |_b.txt

然后,您需要2个装载记录

/other:/data
/static-data:/mirror

现在,当您运行容器时,针对主机断开的符号链接在容器中不会断开,因此/data/data-file1.dat -> /mirror/data-file1.dat和容器已装载/mirror,因此符号链接从主机指向/static-data/data-file1.dat

如果您不希望主机中的符号链接断开,则可以将这两个目录装载为

/other:/data
/static-data:/static-data

现在,链接在主机和容器中都是有效的。正如你所看到的,这是可能的,我测试了它,它工作正常,但它只对明显的文件簇有价值。如果它都是随机的,你最终会挂载很多目录或单个文件,以反映容器中的主机结构

izj3ouym

izj3ouym6#

我想一个很好的方法来解决这个问题。
在Docker容器中,从主机挂载的符号链接无法正常工作。但是在Docker容器中创建的符号链接工作正常。因此,首先将感兴趣的根(带有绝对路径)挂载到容器中,然后在容器中创建满足需要的结构的符号链接是一个好主意。这样,你就可以很好地去做了。
希望这个有用。

相关问题