我怎样才能使从 docker linux 容器内部创建的符号链接可以从 windows 主机看到(如果需要,可能涉及 samba)
How can I make symlinks made from inside docker linux containers to be seen from a windows host (maybe involving samba, if needed)
问题
如何从 windows 主机中查看 docker linux 容器的符号链接? (即使我必须放置一个中间 linux 机器通过 NFS 或 Samba 公开文件系统)
上下文
在 DEVEL 环境中,我在办公室的 Linux 中的某个远程文件系统中有这个结构:
/files/repos/app-1
/files/repos/app-2
/files/repos/lib-x
/files/repos/lib-y
app-1
和 app-2
都使用像这样出售和符号链接的库:
/files/repos/app-1/vendor/my-company/lib-x => /files/repos/lib-x
/files/repos/app-1/vendor/my-company/lib-y => /files/repos/lib-y
/files/repos/app-2/vendor/my-company/lib-x => /files/repos/lib-x
/files/repos/app-2/vendor/my-company/lib-y => /files/repos/lib-y
开发人员需要在 Windows.
因此开发人员将他们的 IDE 指向某个已安装的单元,例如 Z:\ 他们可以在其中看到所有的存储库和项目。
这使我们能够:
- 从它自己的文件夹编辑任何项目,并运行该项目的单元测试,包括运行宁
lib-x
和 lib-y
。
- 开发任何库并在依赖的应用程序中更新它们(注意我说我在开发中,而不是 PRE 或 PROD)。
- 从IDE,指向看到"complete structure"的任何应用程序(例如
app-1
)也看到类的lib-x
和 lib-y
所以自动完成等工作完美。
这已经这样工作了将近十年并且完美无缺。
问题
开发人员需要连接到服务器才能进行开发,我们希望转变为本地 dockers,这样我们就可以让开发人员在家工作。
要去docker
我们现在决定不再使用办公室服务器,我们将在 docker 个容器中设置所有开发。
什么才是真正有效的
我们刚刚在 Windows 中安装了 docker 桌面,并将主机中的 C:\repos 共享到 docker 中。
我们现在有一些开发机器 FROM ubuntu:xxx
和 运行 它们正在安装卷。
我们从 linux 容器中将 app-1
和 app-2
中的符号链接指向 lib-x
和 lib-y
。
如果我们 运行 本地 dockers
中的应用程序,这确实工作得很好,而且存储库工作得很好
linux 容器和 windows 主机中的符号链接有问题
现在的问题是 IDE:当它读取 C:\repos\app-1 中的文件时,在 linux 容器中创建的符号链接无法从主持人。
这使得 IDE 无法跟随 C:\repos\app-1\vendor\lib-x 并且所有代码完成助手都被破坏了。
我已经知道 Windows 不支持与 linux 符号链接兼容的符号链接。
这迫使我们寻找替代解决方案。
我们使用 Samba 的解决方案
最初我认为与旧拓扑一样,linux 服务器只是通过 samba 共享文件系统,windows 可以读取符号链接内容,因为它们在服务器端被解映射并且不是客户端,我认为我可以 运行 另一台带有 samba 服务器的 docker 机器只是为了再次在本地共享 "things seen from the linux" 到 Windows 主机。
为此,我设置了这个 docker-compose:
version: "3.7"
services:
samba:
container_name: samba
hostname: samba
image: dperson/samba
volumes:
- //c/Users/xavi/Documents/repos/test_samba:/mount
ports:
- "139:139"
- "445:445"
command: samba.sh -s "test_samba;/mnt/repos/test_samba;yes;no;yes;all"
restart: always
但这会产生冲突,因为 445 已在本地使用。
如果我关闭本地 SMB,那么在下次重新启动时,docker 无法将 C:\ 共享到 docker(我没有意识到它通过 SMB 进行共享,可以它会变成 NFS 左右吗?)
如果我映射到另一个端口,比如 10445:445 那么客户端将无法访问它,因为 windows 中的客户端 samba 端口似乎不可配置。
映射 IP
所以我尝试映射一个IP:
version: "3.7"
services:
samba:
container_name: samba
hostname: samba
image: dperson/samba
volumes:
- //c/Users/xavi/Documents/repos/test_samba:/mount
ports:
- "139:139"
- "192.168.4.83:445:445"
command: samba.sh -s "test_samba;/mnt/repos/test_samba;yes;no;yes;all"
restart: always
networks:
samba:
ipv4_address: 192.168.4.83
networks:
samba:
ipam:
driver: default
config:
- subnet: "192.168.4.0/16"
但似乎这仍然会产生问题:
- 似乎 IP 仅用于内部 docker 网络,但从主机看不到
- 看来原来的服务还是不听127.0.0.1:445而是听0.0.0.0:445所以还是"blocking"附件听192.168.4.83:445
所以问题
如何让 windows 主机看到 "demapped contents of symlinks" 让 IDE 看到从 docker [=142= 内部链接的销售内容] 集装箱?
我在设置时遇到了类似的问题:在 Windows 10 上开发(IDE 和 Docker 都是 运行),并且网站 运行 容器内 (Linux).
我曾经在网站需要的库上工作,同时处理两个项目。为此,库目录在供应商路径中被符号链接(在 host/Windows 中)。
类似于:
+ my-website
↪ vendor
↪ company
↪ my-package (->symlink here)
↪ ...
↪ docker-compose.yml
+ external-packages
↪ company
↪ my-package (real files here)
但是对于 Docker,该设置不再有效。
所以诀窍是在 docker-compose 中安装一个卷,如下所示:
volumes:
- ./:/my-app
- ../external-packages/company:/my-app/vendor/company
因此 vendor
中的文件是 Web 服务器(在容器内)'seen',我们可以保留 [=12] 之间的符号链接(在 windows 中创建) =] 文件夹,所以 IDE 也能看到它们。
希望对您有所帮助。
TL;DR
- 运行 git-bash 作为管理员。
- 在 git-bash 中发布
export MSYS=winsymlinks:nativestrict
。
- 从那时起,
ls -s
在 windows 工作。
- 从 docker.
内部可以看到链接
详情
我们将完成这些步骤:
- 准备:准备一个临时目录,其中包含
abc
目录中的一些文件。
- 看到它失败了:我们将尝试制作一个 symlink 并看到它失败。
- Create symlink: 我们将在 windows 中创建 symlink 并查看它。我们将
xyz
指向 abc
。
- 运行 docker: 然后我们将 运行 docker 和
ubuntu
更改内容xyz
.
- 签入 ubuntu 容器: 我们也会在 docker.[=210= 中看到
abc
中的更改]
- 签入 windows 主机: 那么从容器外检查
abc
和 xyz
。
1。准备
- 在 git-bash 中转到
/c
并创建一个临时目录 tmp
。
- 在其中创建一个
abc
目录并在其中添加一些内容。
cd /c
mkdir tmp
cd tmp/
mkdir abc
cd abc/
echo 1111 > old_1
echo 2222 > old_2
echo 3333 > old_3
这是一个示例会话:
2。看到它失败
首先让我们尝试“正常”方式,看看它是否失败。
- 在 git-bash 中,导航至
/c/tmp
- 然后做一个 symlink 让
xyz
指向 abc
: ln -s abc xyz
- 看到它失败了,通过ls-ing
tmp
并且看到xyz
是一个普通的目录。
- 可以肯定的是,在
xyz
中创建新内容并在 abc
中看到 而不是 。
尝试创建 link(不起作用)
cd /c/tmp/
ln -s abc xyz
在xyz
中创建new_bad
并且不要在abc
中看到它。
cd xyz/
touch new_bad
cd ../abc/
ls -l
清除错误xyz
rm -Rf xyz/
这是一个示例会话:
3。创建 symlink
真正的东西来了。灵感来自@Slayvin 在这里的回答,以及这里 Git Bash Shell fails to create symbolic links and the official git-for-windows repo here https://github.com/git-for-windows/git/pull/156
- 首先在管理员模式下打开一个新的git-bash。原因是只有管理员可以在 windows.
中创建 links
- 成为 CLI 管理员后,导航至目标并设置此环境变量:
export MSYS=winsymlinks:nativestrict
这将告诉 git-bash 的 运行time 子系统实际使用 symlinks 功能。因为我们是管理员,所以我们会成功。
- 如您所料,只是“正常符号links”:
ls -s abc xyz
有效!!!现在下一步是在 docker!
内进行测试
注意:根据塞巴斯蒂安在这里的回答,您不需要成为管理员才能在git-bash中创建symlinks如果您启用了开发人员工具。在 search-bar 中写入 for developers
并启用它:
4。 运行 docker + 5.签到docker
- 不再需要具有管理员权限的 bash 。所以我们将关闭它并 re-instantiate 一个“正常” bash.
- 其中,运行 一个 ubuntu 容器 docker。使用
-it
与 ubuntu 的 bash 互动。使用 winpty
允许 -it
工作。
- Bind-mount
/c/tmp
目录,因此 abc
和 xyz
都可以访问。我选择挂载到 /files
.
- 从内部看,
cd /files
看到 xyz
实际上是一个符号 link。
- 在
xyz
中创建一些新内容
运行 并查看:
winpty docker run -it --rm --mount type=bind,source="c:\tmp",target=/files --name ubuntu-link ubuntu
cd /files/
ls -l
创建内容:
cd xyz
echo "yeaaahh" > new_good
通过转到 abc
:
来检查它是否真的是一个符号link
cd ..
cd abc/
cat new_good
示例会话:
6.签入 windows 主机
- 走出docker。留在git-bash.
- 再次声明:此 git-bash 不需要 特权。我们必须成为管理员的唯一时刻是在 windows.
中“创建”symlink
- 从无权限的 bash 中,探索
abc
和 xyz
并看到我们从 docker 中创建的内容,出现在原始文件中目录和 symlink.
示例会话:
最终检查
我们终于可以去经典的CMD
看看它长什么样了。我们可以看到它清楚地表明它是一个目录的 symlink,我们也在那里看到了目标:
点金术
如果您如上所述激活了“开发者工具”,唯一缺少的就是 ENV VAR。
我们可以通过编辑您 windows 家的 .bashrc
来设置:
通过这样做,我们可以完全正常地使用 git-bash 并开始从 windows 创建 symlinks 而无需任何重载。
注意
以这种方式创建的 symlinks 从 windows 和一个从内部看到的 e docker。但不是相反。如果您在容器内创建 symlinks,它们不会在 windows.
中创建
因此,在安装的卷中,始终从 git-bash 设置 symlinks 并从容器中使用它们。如果您从容器中创建它们,它们仍然 可以从容器中使用。但是从 windows.
开始将不可用
结论
可以通过 git-bash 从 linux 风味命令完全完成。只是您需要成为管理员才能创建 link 并告知 git-bash 运行 使用该功能的时间。 link 需要从 windows 完成,而不是从 ubuntu.
内部完成
问题
如何从 windows 主机中查看 docker linux 容器的符号链接? (即使我必须放置一个中间 linux 机器通过 NFS 或 Samba 公开文件系统)
上下文
在 DEVEL 环境中,我在办公室的 Linux 中的某个远程文件系统中有这个结构:
/files/repos/app-1
/files/repos/app-2
/files/repos/lib-x
/files/repos/lib-y
app-1
和 app-2
都使用像这样出售和符号链接的库:
/files/repos/app-1/vendor/my-company/lib-x => /files/repos/lib-x
/files/repos/app-1/vendor/my-company/lib-y => /files/repos/lib-y
/files/repos/app-2/vendor/my-company/lib-x => /files/repos/lib-x
/files/repos/app-2/vendor/my-company/lib-y => /files/repos/lib-y
开发人员需要在 Windows.
因此开发人员将他们的 IDE 指向某个已安装的单元,例如 Z:\ 他们可以在其中看到所有的存储库和项目。
这使我们能够:
- 从它自己的文件夹编辑任何项目,并运行该项目的单元测试,包括运行宁
lib-x
和lib-y
。 - 开发任何库并在依赖的应用程序中更新它们(注意我说我在开发中,而不是 PRE 或 PROD)。
- 从IDE,指向看到"complete structure"的任何应用程序(例如
app-1
)也看到类的lib-x
和lib-y
所以自动完成等工作完美。
这已经这样工作了将近十年并且完美无缺。
问题
开发人员需要连接到服务器才能进行开发,我们希望转变为本地 dockers,这样我们就可以让开发人员在家工作。
要去docker
我们现在决定不再使用办公室服务器,我们将在 docker 个容器中设置所有开发。
什么才是真正有效的
我们刚刚在 Windows 中安装了 docker 桌面,并将主机中的 C:\repos 共享到 docker 中。
我们现在有一些开发机器 FROM ubuntu:xxx
和 运行 它们正在安装卷。
我们从 linux 容器中将 app-1
和 app-2
中的符号链接指向 lib-x
和 lib-y
。
如果我们 运行 本地 dockers
中的应用程序,这确实工作得很好,而且存储库工作得很好linux 容器和 windows 主机中的符号链接有问题
现在的问题是 IDE:当它读取 C:\repos\app-1 中的文件时,在 linux 容器中创建的符号链接无法从主持人。
这使得 IDE 无法跟随 C:\repos\app-1\vendor\lib-x 并且所有代码完成助手都被破坏了。
我已经知道 Windows 不支持与 linux 符号链接兼容的符号链接。
这迫使我们寻找替代解决方案。
我们使用 Samba 的解决方案
最初我认为与旧拓扑一样,linux 服务器只是通过 samba 共享文件系统,windows 可以读取符号链接内容,因为它们在服务器端被解映射并且不是客户端,我认为我可以 运行 另一台带有 samba 服务器的 docker 机器只是为了再次在本地共享 "things seen from the linux" 到 Windows 主机。
为此,我设置了这个 docker-compose:
version: "3.7"
services:
samba:
container_name: samba
hostname: samba
image: dperson/samba
volumes:
- //c/Users/xavi/Documents/repos/test_samba:/mount
ports:
- "139:139"
- "445:445"
command: samba.sh -s "test_samba;/mnt/repos/test_samba;yes;no;yes;all"
restart: always
但这会产生冲突,因为 445 已在本地使用。
如果我关闭本地 SMB,那么在下次重新启动时,docker 无法将 C:\ 共享到 docker(我没有意识到它通过 SMB 进行共享,可以它会变成 NFS 左右吗?)
如果我映射到另一个端口,比如 10445:445 那么客户端将无法访问它,因为 windows 中的客户端 samba 端口似乎不可配置。
映射 IP
所以我尝试映射一个IP:
version: "3.7"
services:
samba:
container_name: samba
hostname: samba
image: dperson/samba
volumes:
- //c/Users/xavi/Documents/repos/test_samba:/mount
ports:
- "139:139"
- "192.168.4.83:445:445"
command: samba.sh -s "test_samba;/mnt/repos/test_samba;yes;no;yes;all"
restart: always
networks:
samba:
ipv4_address: 192.168.4.83
networks:
samba:
ipam:
driver: default
config:
- subnet: "192.168.4.0/16"
但似乎这仍然会产生问题:
- 似乎 IP 仅用于内部 docker 网络,但从主机看不到
- 看来原来的服务还是不听127.0.0.1:445而是听0.0.0.0:445所以还是"blocking"附件听192.168.4.83:445
所以问题
如何让 windows 主机看到 "demapped contents of symlinks" 让 IDE 看到从 docker [=142= 内部链接的销售内容] 集装箱?
我在设置时遇到了类似的问题:在 Windows 10 上开发(IDE 和 Docker 都是 运行),并且网站 运行 容器内 (Linux).
我曾经在网站需要的库上工作,同时处理两个项目。为此,库目录在供应商路径中被符号链接(在 host/Windows 中)。
类似于:
+ my-website ↪ vendor ↪ company ↪ my-package (->symlink here) ↪ ... ↪ docker-compose.yml + external-packages ↪ company ↪ my-package (real files here)
但是对于 Docker,该设置不再有效。 所以诀窍是在 docker-compose 中安装一个卷,如下所示:
volumes:
- ./:/my-app
- ../external-packages/company:/my-app/vendor/company
因此 vendor
中的文件是 Web 服务器(在容器内)'seen',我们可以保留 [=12] 之间的符号链接(在 windows 中创建) =] 文件夹,所以 IDE 也能看到它们。
希望对您有所帮助。
TL;DR
- 运行 git-bash 作为管理员。
- 在 git-bash 中发布
export MSYS=winsymlinks:nativestrict
。 - 从那时起,
ls -s
在 windows 工作。 - 从 docker. 内部可以看到链接
详情
我们将完成这些步骤:
- 准备:准备一个临时目录,其中包含
abc
目录中的一些文件。 - 看到它失败了:我们将尝试制作一个 symlink 并看到它失败。
- Create symlink: 我们将在 windows 中创建 symlink 并查看它。我们将
xyz
指向abc
。 - 运行 docker: 然后我们将 运行 docker 和
ubuntu
更改内容xyz
. - 签入 ubuntu 容器: 我们也会在 docker.[=210= 中看到
abc
中的更改] - 签入 windows 主机: 那么从容器外检查
abc
和xyz
。
1。准备
- 在 git-bash 中转到
/c
并创建一个临时目录tmp
。 - 在其中创建一个
abc
目录并在其中添加一些内容。
cd /c
mkdir tmp
cd tmp/
mkdir abc
cd abc/
echo 1111 > old_1
echo 2222 > old_2
echo 3333 > old_3
这是一个示例会话:
2。看到它失败
首先让我们尝试“正常”方式,看看它是否失败。
- 在 git-bash 中,导航至
/c/tmp
- 然后做一个 symlink 让
xyz
指向abc
:ln -s abc xyz
- 看到它失败了,通过ls-ing
tmp
并且看到xyz
是一个普通的目录。 - 可以肯定的是,在
xyz
中创建新内容并在abc
中看到 而不是 。
尝试创建 link(不起作用)
cd /c/tmp/
ln -s abc xyz
在xyz
中创建new_bad
并且不要在abc
中看到它。
cd xyz/
touch new_bad
cd ../abc/
ls -l
清除错误xyz
rm -Rf xyz/
这是一个示例会话:
3。创建 symlink
真正的东西来了。灵感来自@Slayvin 在这里的回答,以及这里 Git Bash Shell fails to create symbolic links and the official git-for-windows repo here https://github.com/git-for-windows/git/pull/156
- 首先在管理员模式下打开一个新的git-bash。原因是只有管理员可以在 windows. 中创建 links
- 成为 CLI 管理员后,导航至目标并设置此环境变量:
export MSYS=winsymlinks:nativestrict
这将告诉 git-bash 的 运行time 子系统实际使用 symlinks 功能。因为我们是管理员,所以我们会成功。
- 如您所料,只是“正常符号links”:
ls -s abc xyz
有效!!!现在下一步是在 docker!
内进行测试注意:根据塞巴斯蒂安在这里的回答,您不需要成为管理员才能在git-bash中创建symlinks如果您启用了开发人员工具。在 search-bar 中写入 for developers
并启用它:
4。 运行 docker + 5.签到docker
- 不再需要具有管理员权限的 bash 。所以我们将关闭它并 re-instantiate 一个“正常” bash.
- 其中,运行 一个 ubuntu 容器 docker。使用
-it
与 ubuntu 的 bash 互动。使用winpty
允许-it
工作。 - Bind-mount
/c/tmp
目录,因此abc
和xyz
都可以访问。我选择挂载到/files
. - 从内部看,
cd /files
看到xyz
实际上是一个符号 link。 - 在
xyz
中创建一些新内容
运行 并查看:
winpty docker run -it --rm --mount type=bind,source="c:\tmp",target=/files --name ubuntu-link ubuntu
cd /files/
ls -l
创建内容:
cd xyz
echo "yeaaahh" > new_good
通过转到 abc
:
cd ..
cd abc/
cat new_good
示例会话:
6.签入 windows 主机
- 走出docker。留在git-bash.
- 再次声明:此 git-bash 不需要 特权。我们必须成为管理员的唯一时刻是在 windows. 中“创建”symlink
- 从无权限的 bash 中,探索
abc
和xyz
并看到我们从 docker 中创建的内容,出现在原始文件中目录和 symlink.
示例会话:
最终检查
我们终于可以去经典的CMD
看看它长什么样了。我们可以看到它清楚地表明它是一个目录的 symlink,我们也在那里看到了目标:
点金术
如果您如上所述激活了“开发者工具”,唯一缺少的就是 ENV VAR。
我们可以通过编辑您 windows 家的 .bashrc
来设置:
通过这样做,我们可以完全正常地使用 git-bash 并开始从 windows 创建 symlinks 而无需任何重载。
注意
以这种方式创建的 symlinks 从 windows 和一个从内部看到的 e docker。但不是相反。如果您在容器内创建 symlinks,它们不会在 windows.
中创建因此,在安装的卷中,始终从 git-bash 设置 symlinks 并从容器中使用它们。如果您从容器中创建它们,它们仍然 可以从容器中使用。但是从 windows.
开始将不可用结论
可以通过 git-bash 从 linux 风味命令完全完成。只是您需要成为管理员才能创建 link 并告知 git-bash 运行 使用该功能的时间。 link 需要从 windows 完成,而不是从 ubuntu.
内部完成