Docker卷映射无法正常工作

时间:2018-06-11 20:55:31

标签: node.js docker directory volume docker-volume

我在Dockerizing a Node.js web app示例中工作,试图从第一原则中理解Docker。我已将server.js重新命名为index.js,将其上传到repl.it(由于repl.it强制存在index.js的错误/功能),这里是链接:

项目:https://repl.it/repls/BurlyAncientTrust

现场演示:https://BurlyAncientTrust--five-nine.repl.co

下载:https://repl.it/repls/BurlyAncientTrust.zip

我还整理了一些核心操作,这些操作以功能/声明的方式从图像中获取容器,而不是使用名称(令人惊讶的是,这些没有中心来源):

# commands to start, list, login and remove containers/images associated with current directory's image
# build and run docker image (if it was removed with "docker rmi -f <image>" then this restores IMAGE in "docker ps")
(image=<image_name> && docker build -t $image . && docker run --rm -p <host_port>:<container_port> -d $image)
# list container id for image name
(image=<image_name> && docker ps -a -q --filter=ancestor=$image)
(image=<image_name> && docker ps -a | awk '{print $1,$2}' | grep -w $image | awk '{print $1}')
# run/exec bash inside container (similar to "vagrant ssh")
(image=<image_name> && docker exec -it $(docker ps -a -q -n=1 --filter=ancestor=$image) bash)
# remove containers for image name
(image=<image_name> && docker ps -a -q --filter=ancestor=$image | xargs docker rm -f)
# remove containers and specified image
(image=<image_name> && docker ps -a -q --filter=ancestor=$image | xargs docker rm -f && docker rmi $image)

构建并运行示例:

下载并解压缩BurlyAncientTrust.zip

cd <path_to>/BurlyAncientTrust

然后:

(image=node-web-app && docker build -t $image . && docker run --rm -p 49160:8080 -d $image)

访问:

http://localhost:49160/

您应该看到:

Hello world

问题是我无法使用-v选项进行卷映射(目录同步):

(image=node-web-app && docker ps -a -q --filter=ancestor=$image | xargs docker rm -f && docker rmi $image)
(image=node-web-app && docker build -t $image . && docker run --rm -v "$(pwd)":/usr/src/app -p 49160:8080 -d $image)

我明白了:

This site can’t be reached

docker ps不再显示容器。我在Mac OS X High Sierra上,所以"$(pwd)"部分可能在其他平台上有所不同。您可以使用当前工作目录的绝对路径替换它。这是完整的输出:

Zacks-Macbook:hello-system zackmorris$ (image=node-web-app && docker ps -a -q --filter=ancestor=$image | xargs docker rm -f && docker rmi $image)
Untagged: node-web-app:latest
Deleted: sha256:117288d6b7424798766b288518e741725f8a6cba657d51cd5f3157ff5cc9b784
Deleted: sha256:e2fb2f92c1fd4697c1d217957dc048583a14ebc4ebfc73ef36e54cddc0eefe06
Deleted: sha256:d274f86b6093a8e44afe1720040403e3fb5793f5fe6b9f0cf2c12c42ae6476aa
Deleted: sha256:9116e43368aba02f06eb1751e6912e4063326ce93ca1724fead8a8c1e1c6c56b
Deleted: sha256:902d4d1718530f6c7a50dd11331ee9ea85a04464557d699377115625da571b61
Deleted: sha256:261c92dc9ba95e2447e0250ea435717c855c6b184184fa050fc15fc78b1447f8
Deleted: sha256:559b16060e30ea3875772aae28a2c47508dfebda35529e87e7ff46f035669798
Deleted: sha256:4316607ec7e64e54ad59c3e46288a9fb03d9ec149b428a8f70862da3daeed4e5
Zacks-Macbook:hello-system zackmorris$ (image=node-web-app && docker build -t $image . && docker run --rm -v "$(pwd)":/usr/src/app -p 49160:8080 -d $image)
Sending build context to Docker daemon  57.34kB
Step 1/7 : FROM node:carbon
 ---> baf6417c4cac
Step 2/7 : WORKDIR /usr/src/app
 ---> Using cache
 ---> 00b2b9912592
Step 3/7 : COPY package*.json ./
 ---> f39ed074815e
Step 4/7 : RUN npm install
 ---> Running in b1d9bf79d502
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN docker_web_app@1.0.0 No repository field.
npm WARN docker_web_app@1.0.0 No license field.

added 50 packages in 4.449s
Removing intermediate container b1d9bf79d502
 ---> cf2a5fce981c
Step 5/7 : COPY . .
 ---> 46d46102772b
Step 6/7 : EXPOSE 8080
 ---> Running in cd92fbacacf1
Removing intermediate container cd92fbacacf1
 ---> ac13f4eda9a2
Step 7/7 : CMD [ "npm", "start" ]
 ---> Running in b6cd6811b0ce
Removing intermediate container b6cd6811b0ce
 ---> 06f887984da8
Successfully built 06f887984da8
Successfully tagged node-web-app:latest
effc653267558c80fbcf017d4c10db3e46a7c944997c7e5a5fe5d8682c5c9dad

Docker文件共享:

enter image description here

$ pwd
/Users/zackmorris/Desktop/hello-system

我知道像卷映射那样关键任务必须有效。

更新:我为此打开了issue,看起来可能无法实现(这可能是Docker早期历史中的错误/功能) )。 best answer so far是Dockerfile在RUN npm install挂载"$(pwd)"之前调用/usr/src/app(替换内容),因此/usr/src/app/node_modules目录被替换为空,导致Node.js崩溃,因为它无法找到导致容器退出的express模块。

所以我正在寻找能够解决这个问题的答案,并使这个目录映射在一般意义上成为可能,没有任何奇怪的陷阱,比如必须重新排列图像的内容。

1 个答案:

答案 0 :(得分:0)

我进一步挖掘了Docker构建时和运行时之间的区别,特别是关于Docker Compose,并偶然发现:

https://blog.codeship.com/using-docker-compose-for-nodejs-development/

他能够通过将node_modules映射为docker-compose.yml中的附加音量来使其发挥作用(请注意,我的路径为/usr/src/app而他的/usr/app/volumes: - .:/usr/app/ - /usr/app/node_modules 所以不要&# 39; t copypaste this):

node_modules

我认为这是有效的,因为它使-v /usr/src/app/node_modules成为一个重叠的卷,它会保留其中的所有文件而不是覆盖它们。

我尝试将其作为原始Docker命令node_modules并且它有效!这是一个新的独立示例,与BurlyAncientTrust完全相同,但添加了cd <path_to>/RoundedImpishStructures 目录:

项目:https://repl.it/repls/RoundedImpishStructures

现场演示:https://RoundedImpishStructures--five-nine.repl.co

下载:https://repl.it/repls/RoundedImpishStructures.zip

构建并运行示例:

下载并解压缩RoundedImpishStructures.zip:

(image=node-web-app && docker ps -a -q --filter=ancestor=$image | xargs docker rm -f && docker rmi $image)

如果您正在使用它们,请删除旧容器和图像:

(image=node-web-app && docker build -t $image . && docker run --rm -v "$(pwd)":/usr/src/app -v /usr/src/app/node_modules -p 49160:8080 -d $image)

运行新示例:

Hello world

您应该看到:

     <Menu HorizontalAlignment="Left">
        <Menu.ItemsPanel>
            <ItemsPanelTemplate >
                <DockPanel VerticalAlignment="Stretch" LastChildFill="False"/>
            </ItemsPanelTemplate>
        </Menu.ItemsPanel>
        <MenuItem Header="Option A" DockPanel.Dock="Top"/>
        <MenuItem Header="Option B" DockPanel.Dock="Top"/>
        <MenuItem Header="Option C" DockPanel.Dock="Top"/>
        <MenuItem Header="Settings" DockPanel.Dock="Bottom"/>
        <MenuItem Header="Logout" DockPanel.Dock="Bottom"/>
    </Menu>

请不要赞成这个答案,因为我不相信这是一个普遍的解决方案。希望它可以帮助某人。