Docker
假如你写好了一个Web应用,并且本地调试都没有任何问题,这时候你想部署到远程的云服务器上,那么首先你需要配置相同的环境,这显然很麻烦,而且你配置好后也不一定能运行起来,因为使用的可能是完全不同的操作系统。
为了模拟完全相同的环境,我们自然会想到使用虚拟机,但是虚拟机需要模拟硬件,来运行整个操作系统,不但体积臃肿内存占用高,程序的性能也会受到影响。这是我们就可以使用到Docker。
Docker基本概念
什么是Docker?
Docker 翻译为“码头工人”,其是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化。
Docker的使用机制
Docker并不需要创建完整的虚拟操作系统,但还是会创建独立的环境,这个环境就是容器Container。
Docker不会去模拟底层的硬件,只为每一个应用提供完全隔离的运行环境,你可以在环境中配置不同的工具软件,并且不同环境之前相互不影响,这个环境在Docker也被称作 Container/容器。
容器之间共用主机的内核,但不是直接访问内核,而是通过Docker引擎来访问。
虚拟机是硬件的虚拟化,而Docker容器是操作系统的虚拟化。
两者的差距:
什么是容器?镜像?
- 镜像(Image)和容器(Container)的关系,就像是面向对象编程中的类和实例。镜像是静态的定义,而容器是镜像运行的实体,容器是可以被创建、启动、停止、删除和暂停的
- 每一个镜像(Image)的形成都需要特定的步骤,如指明用什么操作系统、应用版本等,这些都写在镜像定义文件(Dockerfile)中。
- 镜像(Image)可以分享到远程仓库(DockerHub)中,也可以从远程仓库中获取。
Docker初体验
配置docker
在演示之前我们先进行环境的配置
创建项目
演示项目准备
- 创建一个文件夹,名为 dockerTest
- 在dockerTest中执行初始化命令
npm init -y
(-y yes,这样后面就不用敲回车),执行完毕后生成package.json - 导入所需的模块
npm install express
,这里使用express模块搭建一个网页进行演示 - 编写代码:
这里可以使用 node app.js
进行测试下项目的可运行性。
编写Dockerfile
直接命名 Dockerfile,无需后缀。
- FROM 引用镜像
- WOEKDIR 设置工作目录
- COPY 复制文件
- RUN 容器创建时执行的命令
- CMD 容器运行时执行的命令
编写.dockerignore 对文件进行忽略
启动项目
- -t tag,命名 .表示在当前目录寻找Dockerfile
- -p 将容器上的某一端口映射到你的本地主机上,这样才能从主机*问容器中的web应用
- -d detached的意思,让容器在后台运行
Docker命令
镜像管理
创建镜像:docker build <dockerfile路径>
删除镜像:docker rmi <镜像的名称>
命名镜像:docker tag <镜像id> <用户名/镜像名:版本>
查看所有镜像:docker images
创建
删除
命名
若在创建镜像时没有给镜像取名字,可以使用下面的指令对镜像进行命名
远程管理
我们创建好镜像后,可以推送到dockerhub上,但在推送前需要先登录;除了推送自己的镜像,我们还可以从仓库中拉取别人的镜像直接使用。
-
docker login
-
docker push <用户名/镜像名:版本>
-
docker pull <镜像名称>
容器管理
镜像要变为容器才能进行使用,我们对镜像执行docker run
指令,将其变为容器,这样获得的容器是开启状态的;
若是只想创建一个容器而不开启它,可以使用docker create
指令。
创建并启动容器:docker run <镜像名称>
(-d 后台运行、--name 给容器命名)
创建容器(不启动):docker create <镜像名称>
查看容器:docker ps
(-a 显示所有,包括暂停运行的容器)
关闭容器:docker stop <容器ID>
重启容器:docker restart <容器ID>
删除容器:docker rm <容器ID>
(-f 强制移除在运行的容器)
端口映射:本地的端口号 和 容器的端口号 是不一样的,Dockerfile 中的 EXPOSE 只是用于告知Docker中的其他容器可以使用这个端口号。此时我们要进行端口映射,让主机也能使用到 EXPOSE 中的端口号。
docker run -p <主机端口>:<容器端口>
访问容器:进入到容器里与容器中的文件进行交互,此时进行交互的目录就是Dockerfile设置的WorkDir工作目录
docker exec -it <容器ID> /bin/sh
execute -i interactive(交互) -t pseudo-TTY虚拟终端
/bin/sh 表示执行一个新的bash shell,用这个shell进行交互
若是对容器中的文件进行了修改,需要重启容器才能得到看到更新的效果
数据卷
一个容器被删除后,之前所做的修改将全部丢失。如果希望保留容器中的数据,我们可以使用Docker提供的数据卷Volume
数据卷可以认为是一个在本地主机和不同容器*享的文件夹
如果你在某个容器中修改了某一个volume的数据,它会同时反映在其他的容器上。
创建数据卷:docker volumn create
挂载数据卷:在容器启动时将数据卷挂载到容器的某一路径(指定)docker run -v <本地文件夹路径>:<容器文件夹路径>
同步中的ignore
容器里的一些内容是不能动的,如node_modules,若是本地删除了,那么容器中的也会被删除,我们可以声明不动这些文件。
由于同步是双向的,若容器中有新增内容出现,本地也会出现新内容,此时我们可以把本地变为readonly,在 -v 本地文件夹路径:容器文件夹路径
后加上 :ro
即可。
删除volume
由于使用了 -v
,所以当我们不使用这个容器时,需要使用将对应的volume删除掉,不然volume会越来越多。
容器组合
每次启动容器都要写一长串命令,太费劲啦,此时我们可以使用docker-compose
一、先创建一个docker-compose.yml文件,也就是需要用YAML语言来编写
二、编写完毕后,在命令行端口执行 docker-compose up
,如果想在后台运行,可以加上 -d
除此之外,我们还可以加上 --build,如果镜像有修改,docker-compose就会重建,不加上 --build的话下次就会使用之前的缓存。
停止并删除所有容器 docker-compose down
(-v 表示清除对应的volume)