基础知识
什么是docker
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。Docker 可以将应用以集装箱的方式进行打包,通过镜像的方式可以实现在不同的环境下进行快速部署,在团队中还可实现一次打包,多次共享。我们在本地将编译测试通过的程序打包成镜像,可以快速的在服务器环境中进行部署,有时也能解决不同的开发环境造成的问题。
镜像
镜像是一个可执行包,Docker 会把应用程序及依赖打包进镜像(Images)里,提供了容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等),通过这个镜像文件可生成 Docker 容器。镜像有两种:基础镜像和个人镜像。基础镜像由各大厂商提供,比如ubuntu镜像,node镜像。个人镜像则是由个人开发者构建上传。有个docker仓库:hub.docker.com/search?q=&t…
容器
容器是镜像的可运行实例,在默认情况下,容器与其它容器及其主机是隔离的,拥有自己的独立进程空间、网络配置。容器直接运行到宿主机上,没有自己的内核。
docker和虚拟机区别
虚拟机是相当于整个操作系统,在这个操作系统上安装和运行软件,资源占用大,开机启动慢。而docker只有需要用到的资源,并不是一个完整的操作系统。容器直接运行到宿主机上,没有自己的内核,没有虚拟硬件。每个容器内都有一个属于自己的文件系统,互不影响。
数据卷
-v 宿主机文件位置:容器内文件位置 (类似-p) 绝对路径,相对路径会报错
测试1 /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。
测试2
具名和匿名挂载 只写一个是 容器内的位置
数据卷共享是拷贝的,所以一个容器被删除了,其他容易的数据还会在。
常用命令
抓取 image 文件到本地,去docker官方提供的镜像库去抓取。
docker image pull hello-world
查看 image 文件列表
docker image ls
运行 image 文件,
docker container run hello-world
执行 docker container run 命令会生成一个正在运行的容器实例,另外 docker container run 发现本地没有指定的 image 文件,其自身还有自动抓取 image 文件功能,就是上面讲解的 docker image pull 命令.
查看正在运行的容器列表
docker ps
或者
docker container ls
查看所有创建过的容器(运行或者关闭)
docker ps -a
初识DockerFile
//docker build 构造镜像,-f 路径名 通过什么文件来构造,-t 构造的镜像名, .生成在当前目录下
// 通过这个命令就可以生成自己的可运行的镜像。(生成了自己的centos镜像)
docker build -f dockerfile1 -t /liping/centos .
这个每个命令都是镜像的一层
匿名挂载的卷,找到宿主机的位置: docker inspect 容器id
Dockerfile 的编写命令
注:CMD 在docker run 时运行。RUN 是在 docker build。
镜像搜索
docker search nginx
镜像拉取
docker pull nginx
发布镜像实现共享
1、登陆 Docker,已登陆的可以忽略这一步
docker login
2、为本地镜像打标签,tag 不写默认为 latest
docker image tag [imageName] [username]/[repository]:[tag]
3、发布镜像文件
docker image push [username]/[repository]:[tag]
docker构建nodejs镜像
新建hello-docker目录,新建app.js
const http = require('http')
const PORT = 3000
const server = http.createServer((req,res) => {
res.end('hello docker')
})
server.listen(PORT,() =>{
console.log('running---',PORT)
})
同级新建 package.json
{
"name":"hello-docker",
"version":"1.0.0",
"description":"",
"author": "May",
"main":"app.js",
"scripts": {
"start": "node app.js"
},
"dependencies":{}
}
同级新建Dockerfile
#基础镜像
FROM node:10.0
# 定位到容器的工作目录
RUN mkdir -p /usr/src/nodejs
# 在容器中创建一个目录
WORKDIR /usr/src/nodejs
#Dockerfile 中的每条指令都会创建一个镜像层,Dockerfile 指令或复制的项目文件在没有修改变动的情况下,每个镜像层是可以被复用和缓存的。
# RUN/COPY 是分层的,package.json 提前,只要没修改,就不会重新安装包
COPY package.json /usr/src/nodejs/package.json
RUN cd /usr/src/nodejs/
RUN npm i
# 把当前目录下的所有文件拷贝到 Image 的 /usr/src/nodejs/ 目录下
COPY . /usr/src/nodejs/
EXPOSE 3000
CMD npm start
上面如果按照下面这么写,那么每一次重新构建镜像,都需要下载一次npm包!要充分利用docker缓存
COPY . /usr/src/nodejs/
RUN npm i
构建hello-docker镜像,执行命令docker image build -t hello-docker .
-t 参数用来指定镜像的文件名称,最后一个 . 也不要省略,表示 Dockerfile 文件的所在目录,镜像跑起来的时候会逐一往下执行Dockerfile文件里面的命令
执行以上命令之后,我们来查看下新生成的镜像文件 hello-docker。 使用命令docker image 或者在docker桌面应用程序中就可以看到新生成的镜像文件 hello-docker
运行容器
镜像构建成功之后通过 docker container run 命令来生成一个容器,让镜像跑起来,
docker container run -d -p 3001:3000 hello-docker
-d:表明容器的运行模式在后台,守护式运行(没有交互式会话,长期运行,适合运行应用程序和服务)
-it 交互式运行。只有输入exit才退出终端,退出终端后,容器仍然在后台运行。
-p:端口映射,将本机的 3000 端口映射到容器的 3001 端口,这样在外网就可通过 30001 端口访问到我们的服务。为什么要映射端口?因为Docker里每个容器都是相对独立的,拥有自己的内部ip。容器里运行的一些网络应用,要让外部也可以访问,就需要将端口映射到宿主机上。
hello-docker:为我们的镜像名字
可以看到新增的容器:
此时我们的 Node.js 服务已经运行在 Docker 容器的虚拟环境里了,curl http://localhost:30001 可以进行测试
检查日志
4ffceef152f4 为容器 ID,执行命令docker logs -f 4ffceef152f4
更进一步 动态设置环境变量
在原来hello-docker项目中,修改package.json
app.js
dockerfile
可构建一个 Docker 镜像
docker image build . -t lp/hello-docker
运行镜像
docker run -d -p 3000:3002 lp/hello-docker
按照上面 CMD npm run dev 这样写死只能打包一种环境。
修改dockerfile
构建镜像,传入环境变量
docker build --build-arg node_env=dev . -t lpp/hello-docker
运行
docker run -d -p 3002:3003 lpp/hello-docker
查看日志
再更进一步
在项目中, 新建dockerfile
#使用基础镜像库
FROM nginx
#创建工作路径
RUN mkdir -p /data/web/
# 切换到data/web/目录
WORKDIR /data/web/
# 将当前的dist目录拷贝到容器的/data/web/
COPY ./dist/ /data/web/
COPY nginx.template /tmp/
# 启动nginx,关闭守护式运行,否则容器启动后会立刻关闭 docker run 的时候命令行输入的环境变量参数会在这边被替代 传入nginx.template
CMD envsubst '$API_URL $POINT_URL' < /tmp/nginx.template > /etc/nginx/nginx.conf && nginx -g "daemon off;"
package.josn中新增docker命令,复制Nginx.template到tmp目录
在script目录下新建docker_run.sh 设置环境变量
执行npm run docker ,就会执行docker_run.sh里的语句,docker服务就跑起来了。 从docker桌面打开运行终端
我们项目里面的nginx.template内容原封不动地复制到tmp文件夹下
查看/etc/nginx/nginx.conf 中的内容 此时nginx.conf是以nginx.template为模板 并且里面的环境变量被替换了,就可以看到实际生效的nginx配置文件。