Docker的基本概念
名词 | 描述 |
---|---|
Docker 镜像(Images) | Docker 镜像是用于创建 Docker 容器的模板。类似于类(class) |
Docker 容器(Container) | 容器是独立运行的一个或一组应用。类似于实例(object) |
Docker 客户端(Client) | Docker 客户端通过命令行或者其他工具使用 Docker API (https://docs.docker.com/reference/api/docker_remote_api) 与 Docker 的守护进程通信。 |
Docker 主机(Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
Docker 仓库(Registry) | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。 |
Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。 |
一份简单的Dockerfile解析
这里是一个nuxt示例项目,打包的思路就是把项目代码和node环境都打包在一起,每次修改代码之后重新打包。
# 设置基于哪个镜像文件,这里依赖node-alpine版本(一个基于alpine系统的node版本,体积小)
FROM node:8.11.3-alpine
# 复制当前文件夹下文件到容器的/usr/nuxt-init目录
COPY . /usr/nuxt-init
# 设置执行命令的工作目录(这里是运行npm的路径)
WORKDIR /usr/nuxt-init
# RUN用于执行初始化命令
RUN npm install cnpm && ./node_modules/cnpm/bin/cnpm i
# 设置环境变量(根据项目环境来设置,可选项)
ENV HOST 0.0.0.0
# 暴露3000端口给外面
EXPOSE 3000
# 启动时执行的命令,全文只能有一个,有多个时以最后一个为准
# 这里的npm start是npm run start的简写
CMD [ "npm", "start" ]
Dockerfile文件要放在项目根目录下,而且名称不可更改。
根据Dockerfile生成docker镜像
# 进入Dockerfile所在目录
docker build -t deploy:1.0 .
-t是给镜像加上标签便于区分,格式为:<name>:<tag>;
最后的.(点)代表了对当前文件夹下所有文件进行打包 ;
过滤不打包的文件 —— .dockerignore文件
有时会有一些文件不想打包到镜像里面,这时候可以添加.dockerignore文件。用法和.gitignore一样。
# Example
.DS_Store
npm-debug.log*
selenium-debug.log
.nuxt/
/package-lock.json
*.tar
*.md
# Editor directories and files
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
查看构建完成的镜像文件
docker images
该命令可以查看自己构建的镜像和从网上下载的镜像文件
查看镜像的信息
# Example
# 查看nginx镜像的信息
docker inspect nginx
运行镜像
首先明确一个概念:容器,就是以某个镜像运行起来的实例,就跟new了一个实例对象一样。
就以上面的nuxt项目来模拟一个情景:用服务器的3001端口映射容器中nuxt项目的端口(nuxt的项目服务默认开启的是3000端口,因为此时3000端口是指容器本身暴露了3000端口,不代表服务器也暴露了3000端口,所以我们需要给服务器和容器做一个映射);
docker run -d -p 3001:3000 --name mynuxt deloy:1.0
-p 用于映射服务器端口和容器端口,格式为:<服务器端口>: <容器端口>(还有其他写法,具体查文档)
-d 表示让进行在后台运行,如果不加的话运行信息就会在当前终端上显示了,当前终端关闭项目也会停掉。
--name代表这个容器实例的别名,后续可以通过该别名获取容器ID等其他信息,实例别名不能重复。
最后的deloy:1.0就是镜像名称加上标签号了。
这里还有一个知识点,上面说了镜像就像一个模板,可以以一个镜像跑多个容器,每个容器之间是相互独立的,你还可以用服务器的3002、3003接口去映射多个容器的3000接口。
运行上面的命令之后,你可以通过logs命令来查看容器内项目的运行情况了。
docker logs <containerId>
containerId是指容器ID。
通过容器ID你就可以查看日志情况了,这时候又有一个问题了,怎么去查容器的容器ID呢,通过docker ps命令就可以了。
docker ps -a
直接使用docker ps的话可以查出当前运行的docker实例,加上-a可以获取到全部实例,包括运行中的和没运行的,然后就可以根据实例名称获取到容器ID了。
操作实例
实例的启动,重启和关闭
docker (start | restart | stop) <containerId>
实例也和其他服务一样,可以进行关闭、启动等操作,关闭之后的实例还存在于docker ps -a列表中。
删除实例
docker rm [-f] <containerId>
运行中的实例不能进行删除,如果要删除的话,可以加上-f参数删除运行中的实例。
查看运行中的容器内情况
通过exec命令可以查看运行中的实例内部信息。
docker exec -it 43148e2301b9 ls /usr/nuxt-init
-t:在新容器内指定一个伪终端或终端。
-i:允许你对容器内的标准输入 (STDIN) 进行交互。
一般这两个都是成对使用的。
43148e2301b9为运行中的容器ID,可通过docker ps获取。
最后的ls /usr/nuxt-int可以替换成当前镜像支持的shell命令。
映射服务器中的目录到容器内的指定目录。
举一个运行nginx镜像的例子:
docker run -p 80:80 --name mynginx -v $PWD/www:/www -v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf -v $PWD/logs:/wwwlogs -d nginx
命令说明:
- -p 80:80:将容器的80端口映射到主机的80端口
- --name mynginx:将容器命名为mynginx
- -v $PWD/www:/www:将主机中当前目录下的www挂载到容器的/www
- -v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf:将主机中当前目录下的nginx.conf挂载到容器的/etc/nginx/nginx.conf
- -v $PWD/logs:/wwwlogs:将主机中当前目录下的logs挂载到容器的/wwwlogs
特别说明一下:
- 如果映射的目录原本存在着关键文件,你在映射的目录中也应该存在该文件,就比如你映射了nginx的配置文件目录,你也应该把默认配置文件复制一份到你的映射目录中,不然nginx跑不起来。
- 映射的过程中数据流是单向的,即映射的目录中,容器内目录会同步服务器目录的文件,服务器目录新增文件,容器内对应目录也会新增文件;但反过来不行,容器内不允许向映射目录进行写文件操作。