我面临着使用容器共享主机上文件夹中数据的需求。应当在主机上读取或修改在容器内部创建的数据,反之亦然。
我决定为此使用Docker Run -v arg。 我受到这个项目的启发。 https://github.com/itzg/docker-minecraft-server。我对您描述的原理也在那里实现。
docker run -d -v /path/on/host:/data \
-e TYPE=PAPER -e FORCE_REDOWNLOAD=true \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
所有数据将在/path/on/host
中的主机上可用。可以在主机上修改文件,所有更改都将转移到容器中,反之亦然。 /path/on/host
和/data
文件夹会不断链接。
因此,我决定在我的项目中执行此操作-一个nodejs机器人。但是没有结果,因为文件不会从容器复制到主机。只能从主机访问容器访问文件。现在,我想知道如何将文件从容器复制到主机。
如何与上面的示例相同或如何以不同的方式实现它,以方便地在一行中从终端启动共享文件夹中的实例?
其他指南对我没有帮助。我想与-v一起使用。
将在WORKDIR中创建文件
docker run --name app node-app
WORKDIR将为空或包含/ tmp / node-app中的任何文件
docker run -v /tmp/node-app:/app --name app node-app
Dockerfile
FROM node:lts
VOLUME /app/
COPY ./repo/package.json /app/package.json
WORKDIR /app/
RUN npm install --production
COPY ./repo /app/
CMD npm start
答案 0 :(得分:0)
rsync是在系统之间共享文件的绝佳方法。在您的内部Docker网络中找到机器的IP地址,然后
rsync -rav <src-directory> <username>@<dest-ip>:<dest-directory> -o
答案 1 :(得分:0)
几个潜在的问题:
On macOS: Docker -> Preferences -> Resources -> FILE SHARING
您还需要小心安装。当您使用上面的“ -v”选项运行容器时,它将在容器内部绑定安装主机目录。如果将目录绑定绑定到“ / app”目录的顶部,则绑定绑定之前将看不到/ app中的内容。您应该选择一个空目录或不存在目录来执行绑定安装。
当您在Dockerfile中运行“ COPY”时,即从构建上下文中永久且静态地在容器内部复制资产。如果您需要动态资产,请跳过该步骤,然后在运行时进行绑定安装。
答案 2 :(得分:0)
选项1:如果无法更改映像,则可以使用命名卷进行绑定安装。这将为您提供通常在命名卷中看到的常规初始化功能,但会提供您选择的路径。请注意,只有在命名卷为空时才对其进行初始化,一旦命名卷中存在文件,以后的容器启动将不会从容器文件系统复制(例如,如果映像已更新)。这里有3种不同的方式可以完成:
# create the volume in advance
$ docker volume create --driver local \
--opt type=none \
--opt device=/home/user/test \
--opt o=bind \
test_vol
# create on the fly with --mount
$ docker run -it --rm \
--mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=none,volume-opt=o=bind,volume-opt=device=/home/user/test \
foo
# inside a docker-compose file
...
volumes:
bind-test:
driver: local
driver_opts:
type: none
o: bind
device: /home/user/test
...
选项2:如果要在多个主机上易于使用,可以在映像中配置一个入口点,以将文件从容器路径复制到卷中。为此,您需要将文件存储在映像中与卷装载不同的位置,然后包括一个运行复制,rsync或类似操作的脚本。我的base image repo的save-volume
和load-volume
脚本中就是一个例子。其他在docker hub上使用主机卷的映像中也使用了类似的技术,特别是我在考虑jenkins映像。
答案 3 :(得分:0)
这可能不是最好的解决方案,但我仍然按照自己的意愿做。事实证明,我只是从表面上了解docker的工作原理。为了更专业地使用docker,我将考虑以上所有评论。谢谢你离开他们。
最终,我添加了ENTRYPOINT指令来运行一个Shell脚本,该脚本无需覆盖就可以复制文件,并通过npm运行该程序。
Dockerfile
FROM node:12-alpine
VOLUME ["/data"]
...
# Copy script
COPY start.sh /home/docker-start.sh
ENTRYPOINT ["/bin/sh", "/home/docker-start.sh"]
start.sh
#!/bin/sh
mv -n /app/* /data
rm /app -r
cd /data
npm start
现在该程序只需一行即可部署
docker run -v /opt/appname/ow:/data --name ow homosanians/appname