一.Docker安装
Docker 是一个开源的商业产品,有两个版本:社区版(Community Edition,缩写为 CE)和企业版(Enterprise Edition,缩写为 EE)。企业版包含了一些收费服务,个人开发者一般用不到。下面的介绍都针对社区版。
这里centos使用yum安装即可yum -y install docker
安装完成后,运行下面的命令,验证是否安装成功docker version
Docker 是服务器----客户端架构。命令行运行docker命令的时候,需要本机有Docker服务。如果这项服务没有启动,可以用下面的命令启动service docker start
二.image 文件
Docker把应用程序及其依赖,打包在image文件里面。只有通过这个文件,才能生成Docker容器。image文件可以看作是容器的模板。Docker根据image文件生成容器的实例。同一个image文件,可以生成多个同时运行的容器实例。
image是二进制文件。实际开发中,一个image文件往往通过继承另一个image文件,加上一些个性化设置而生成。举例来说,你可以在Ubuntu的image基础上,往里面加入Apache服务器,形成你的image。
列出本机的所有image文件。docker images
删除image文件docker image rm [imageName]
image文件是通用的,一台机器的image文件拷贝到另一台机器照样可以使用。一般来说为了节省时间,我们应该尽量使用别人制作好的image文件,而不是自己制作。即使要定制,也应该基于别人的image文件进行加工,而不是从零开始制作。
为了方便共享,image文件制作完成后,可以上传到网上的仓库。Docker的官方仓库Docker Hub是最重要、最常用的image仓库。此外,出售自己制作的image文件也是可以的。
三.实例hello world
1.下面,我们通过最简单的 image 文件"hello world",感受一下Docker。
需要说明的是,国内连接 Docker 的官方仓库很慢,还会断线,需要将默认仓库改成国内的镜像网站。echo 'DOCKER_OPTS="--registry-mirror=https://registry.docker-cn.com"' >> /etc/default/docker
service docker restart
2.首先,运行下面的命令,将 image文件从仓库抓取到本地。docker image pull library/hello-world
上面代码中,docker image pull是抓取image文件的命令。library/hello-world是image文件在仓库里面的位置,其中library是image文件所在的组,hello-world是image文件的名字。
3.由于Docker官方提供的image文件,都放在library组里面,所以它的是默认组可以省略。因此上面的命令可以写成下面这样。docker image pull hello-world
4.抓取成功以后,就可以在本机看到这个 image 文件了。docker image ls
5.现在,运行这个 image 文件。docker container run hello-world
docker container run命令会从image文件,生成一个正在运行的容器实例。
注意docker container run命令具有自动抓取 image 文件的功能。如果发现本地没有指定的image文件,就会从仓库自动抓取。因此前面的docker image pull命令并不是必需的步骤。
如果运行成功,你会在屏幕上读到下面的输出。
Hello from Docker!
This message shows that your installation appears to be working correctly.
... ...
6.输出这段提示以后,hello world就会停止运行,容器自动终止。
有些容器不会自动终止,因为提供的是服务。比如安装运行Ubuntu的image,就可以在命令行体验Ubuntu系统。docker container run -it ubuntu bash
对于那些不会自动终止的容器,必须使用docker container kill 命令手动终止。docker container kill [containID]
四.容器文件
image文件生成的容器实例,本身也是一个文件,称为容器文件。也就是说一旦容器生成,就会同时存在两个文件: image文件和容器文件。而且关闭容器并不会删除容器文件,只是容器停止运行而已。
列出本机正在运行的容器docker container ls
列出本机所有容器,包括终止运行的容器docker container ls --all
上面命令的输出结果之中,包括容器的ID。很多地方都需要提供这个ID,比如上一节终止容器运行的docker container kill命令。
终止运行的容器文件,依然会占据硬盘空间,可以使用docker container rm命令删除。docker container rm [containerID]
运行上面的命令之后,再使用docker container ls --all命令,就会发现被删除的容器文件已经消失了。
五.Dockerfile 文件
学会使用image文件以后,接下来的问题就是如何可以生成image文件?如果你要推广自己的软件,势必要自己制作 image 文件。
这就需要用到Dockerfile文件。它是一个文本文件用来配置 image。Docker根据该文件生成二进制的image 文件。
1.下面我以koa-demos项目为例,介绍怎么写 Dockerfile文件,实现让用户在Docker容器里面运行 Koa 框架,作为准备工作请先下载源码。git clone https://github.com/ruanyf/koa-demos.git
cd koa-demos
2.编写Dockerfile文件,首先在项目的根目录下,新建一个文本文件.dockerignore,写入下面的内容。
代码表示这三个路径要排除,不要打包进入image文件。如果你没有路径要排除,这个文件可以不新建。vim .dockerignore
.git
node_modules
npm-debug.log
3.然后,在项目的根目录下,新建一个文本文件 Dockerfile,写入下面的内容。vim Dockerfile
FROM node:8.4
COPY . /app
WORKDIR /app
RUN npm install --registry=https://registry.npm.taobao.org
EXPOSE 3000
上面代码一共五行,含义如下
FROM node:8.4:该 image 文件继承官方的 node image,冒号表示标签,这里标签是8.4,即8.4版本的 node。
COPY . /app:将当前目录下的所有文件(除了.dockerignore排除的路径),都拷贝进入 image 文件的/app目录。
WORKDIR /app:指定接下来的工作路径为/app。
RUN npm install:在/app目录下,运行npm install命令安装依赖。注意,安装后所有的依赖,都将打包进入 image 文件。
EXPOSE 3000:将容器 3000 端口暴露出来, 允许外部连接这个端口。
4.创建image文件
有了Dockerfile文件以后,就可以使用docker image build命令创建image文件了。docker image build -t koa-demo .
上面代码中,-t参数用来指定image文件的名字,后面还可以用冒号指定标签。如果不指定,默认的标签就是latest。最后的那个点表示Dockerfile文件所在的路径,上例是当前路径,所以是一个点。
如果运行成功,就可以看到新生成的image文件koa-demo了。docker image ls
5.生成容器
docker container run命令会从 image 文件生成容器docker container run -p 8000:3000 -it koa-demo /bin/bash
上面命令的各个参数含义如下:
-p参数:容器的 3000 端口映射到本机的 8000 端口。
-it参数:容器的 Shell 映射到当前的 Shell,然后你在本机窗口输入的命令,就会传入容器
koa-demo:0.0.1:image 文件的名字(如果有标签,还需要提供标签,默认是 latest 标签)
/bin/bash:容器启动以后,内部第一个执行的命令。这里是启动 Bash,保证用户可以使用 Shell
如果一切正常,运行上面的命令以后,就会返回一个命令行提示符root@66d80f4aaf1e:/app#
这表示你已经在容器里面了,返回的提示符就是容器内部的 Shell 提示符。执行下面的命令。root@66d80f4aaf1e:/app# node demos/01.js
6.这时,Koa 框架已经运行起来了。打开本机的浏览器,访问 http://127.0.0.1:8000,网页显示"Not Found",这是因为这个demo没有写路由。
这个例子中,Node进程运行在Docker容器的虚拟环境里面,进程接触到的文件系统和网络接口都是虚拟的,与本机的文件系统和网络接口是隔离的,因此需要定义容器与物理机的端口映射(map)。
现在,在容器的命令行,按下Ctrl + c停止Node 进程,然后按下Ctrl + d(或者输入 exit)退出容器。此外,也可以用docker container kill终止容器运行。
在本机的另一个终端窗口,查出容器的 IDdocker container ls
停止指定的容器运行docker container kill [containerID]
7.容器停止运行之后,并不会消失,用下面的命令删除容器文件
查出容器的IDdocker container ls --all
删除指定的容器文件docker container rm [containerID]
也可以使用docker container run命令的--rm参数,在容器终止运行后自动删除容器文件。docker container run --rm -p 8000:3000 -it koa-demo /bin/bash
六.CMD命令
容器启动以后需要手动输入命令node demos/01.js。我们可以把这个命令写在 Dockerfile 里面,这样容器启动以后,这个命令就已经执行了,不用再手动输入了。
FROM node:8.4
COPY . /app
WORKDIR /app
RUN npm install --registry=https://registry.npm.taobao.org
EXPOSE 3000
CMD node demos/01.js
上面的 Dockerfile里面,多了最后一行CMD node demos/01.js,它表示容器启动后自动执行node demos/01.js。
你可能会问,RUN命令与CMD命令的区别在哪里?简单说,RUN命令在image文件的构建阶段执行,执行结果都会打包进入image文件;CMD命令则是在容器启动后执行。另外,一 Dockerfile可以包含多个RUN命令,但是只能有一个CMD命令。
注意,指定了CMD命令以后,docker container run命令就不能附加命令了(比如前面的/bin/bash),否则它会覆盖CMD命令。现在启动容器可以使用下面的命令。docker container run --rm -p 8000:3000 -it koa-demo:0.0.1
七.发布image文件
容器运行成功后,就确认了image文件的有效性。这时,我们就可以考虑把image文件分享到网上,让其他人使用。
首先,去hub.docker.com或cloud.docker.com注册一个账户。然后用下面的命令登录。docker login
接着为本地的image标注用户名和版本。docker image tag [imageName] [username]/[repository]:[tag]
实例docker image tag koa-demos:0.0.1 ruanyf/koa-demos:0.0.1
也可以不标注用户名,重新构建一下 image 文件。docker image build -t [username]/[repository]:[tag] .
最后发布 image 文件docker image push [username]/[repository]:[tag]
发布成功以后,登录 hub.docker.com,就可以看到已经发布的 image 文件。
八.其他有用的命令
1.docker container start
前面的docker container run命令是新建容器,每运行一次就会新建一个容器。同样的命令运行两次,就会生成两个一模一样的容器文件。如果希望重复使用容器,就要使用docker container start命令,它用来启动已经生成、已经停止运行的容器文件。docker container start [containerID]
2.docker container stop
前面的docker container kill命令终止容器运行,相当于向容器里面的主进程发出SIGKILL信号。而docker container stop命令也是用来终止容器运行,相当于向容器里面的主进程发出SIGTERM信号,然后过一段时间再发出SIGKILL信号。bash container stop [containerID]
这两个信号的差别是,应用程序收到SIGTERM信号以后,可以自行进行收尾清理工作,但也可以不理会这个信号。如果收到SIGKILL 号,就会强行立即终止,那些正在进行中的操作会全部丢失。
3.docker container logs
docker container logs命令用来查看docker容器的输出,即容器里面Shell的标准输出。如果docker run命令运行容器的时候,没有使用-it参数,就要用这个命令查看输出。docker container logs [containerID]
4.docker container exec
docker container exec命令用于进入一个正在运行的 docker 容器。如果docker run命令运行容器的时候,没有使用-it参数,就要用这个命令进入容器。一旦进入了容器就可以在容器的Shell执行命令了。docker container exec -it [containerID] /bin/bash
5.docker container cp
docker container cp命令用于从正在运行的Docker容器里面,将文件拷贝到本机。下面是拷贝到当前目录的写法。docker container cp [containID]:[/path/to/file] .