问题描述
- 1.尝试使用一个node:8-alpine创建一个容器
- 2.在docker-compose.yml文件中使用volumes指令映射node.js代码
- 3.在docker-compose.yml文件中使用command指令执行cd 到项目根目录下,并且执行npm start
-----> 一旦启动docker-compose up -d启动容器立刻报出Error:cd指令不存在
解决思路
- Q:以前使用过这种在node容器中运行这些指令,而且影响比较深在容器中经常使用诸如
cd
和npm
这样的指令,那么现在为什么不行?
A: 1.我想使用docker exec -it node_service bash
企图进入容器。但是首先需要容器能启动并且可以一直hold住,因此我将command改成了ping www.baidu.com
重新启动容器。2.容器终于hold住,我采用docker exec -it node_service bash
进入容器,却又出现了新的错误说没有bash指令。 - Q:以前的容器都可以bash为什么唯独这个容器不行呢?是否说明镜像有问题?
A: 经过查看镜像我真的使用了和以往不同的alpine镜像,我把镜像换了之后,倒是可以bash进入容器了并且在容器中可以使用bash,但是command中使用cd任然报出以前的错误。 - Q:那么为什么两种镜像会出现这样的不同?
A: 到docker hub上专门查询了使用的alpine镜像,文档上明确说明了此镜像是简化版镜像,因此不存在bash命令,仅仅存在sh命令,因此使用docker exec -it service /bin/sh
就可以进入容器,由此说明一般的镜像能够支持bash命令,而alpine只能支持sh -
Q:那么什么是bash什么又是sh 他们之间又有什么区别呢?
A:他们都是用来对CLI进行调用的shell命令只不过包含命令的多少不同功能大小不同而已
- Q:那么经常会看到的
/bin/bash
和bash
又有什么区别呢?
A:他们都是一样的,那么前者使用which bash得出的值,后者是bash,都可以用来执行command
常用的bash -c “command”
用来将command流向bash让他执行对应指令
- Q:那么
docker exec -it **** bash
的意思到底是什么呢?
A:现在才清楚:docker exec
其实就是ssh到一个container中,并且使用-I -t参数 进行输入并且开启一个终端,使用bash进行命令行输入。你也可以替换成docker exec -it *** /bin/sh
使用这种方式就可以对alpine容器进行操作 - Q:那么docker-compose.yml文件的command之后所跟的命令是不是就没有针对任何shell?
A:由于我们bash进入容器可以执行cd,但是在command之后输入cd却是无效的,那么说明command之后的指令并没有使用到bash或者sh,因此为了让command之后的指令能执行 那么使用
command: /bin/sh -c "cd ***"
解决办法
仍然使用alpine镜像,但是command之后的指令做修改
反思
- 使用alpine镜像的时候没有认真阅读文档思考其和别的镜像有什么不同,文档中会清楚的告诉你使用的注意点,这样就可避过很多坑,尤其文档中的范例要认真看懂。
以后使用新的技术之前,必须强迫自己耐心读完那些英文,注意关键词(比如警告。。) - 使用的指令只关注他能完成什么功能了,但是没有去查一下,他的作用以及各个参数的意义(比如
docker exec -it bash
)。
以后使用的指令必须不断反问自己他的作用是什么,这些参数是否必须存在,换成别的行不行。 - 对Linux的基础只是了解太少,看完持续集成之后一定要花时间好好补一下