如果没有docker,我们需要手动在一台机器上安装数据库,配置nginx,然后还要做不同机器操作系统差异的适配。有了docker,我们可以把开发、测试环境,一键部署到任何一台机器上。只要该机器安装了Docker 。
Docker就是一种虚拟机技术,比传统虚拟机(如vmware、virtualbox)要更加简单、轻量。
- 启动快
- 资源占用少
-
安装
https://docs.docker.com/desktop/install/mac-install/
安装完记得镜像加速,搜索”docker 镜像加速“即可。
安装完,运行docker version
可查看版本。相关文档
术语
Dockerfile构建出镜像,镜像推送到镜像仓库
- 从 仓库下载镜像
镜像启动容器,一个镜像可以启动多个容器。容器就是虚拟机的能力。
常用命令
image镜像
下载镜像 docker pull
: - 查看所有镜像 docker images
- 删除镜像 docker rmi
- 上传镜像 docker push
/ : ,要先注册https://hub.docker.com/
如果 docker images出现REPOSITORY是docker image prune
删除。
container容器
容器是有能力的,比如nginx容器。可以看做最小型的一个操作系统
启动容器
docker run -p xxxx:xxxx -v=hostPath:containerPath -d --name <container-name><image-name>
- -p 端口映射 :本地和容器端口的映射
- -v 数据卷,文件映射
- -d 后台运行
- —name 定义容器名称 镜像的名称
- 查看所有容器 docker ps ,加-a显示隐藏的容器
- 停止容器 docker stop
- 删除容器 docker rm
,加-f是强制删除 - 查看容器信息,如IP地址 docker inspect
- 查看容器日志 docker logs
进入容器控制台 docker exec -it
/bin/sh 创建容器
基于 nginx 镜像创建一个最简单的容器:启动一个最简单的 http 服务
使用 docker run 来启动容器,docker ps 查看容器启动状态。docker run -d --name nginx -p 8888:80 nginx:alpine
其中:
-d: 启动一个 daemon 进程
- —name: 为容器指定名称
- -p host-port:container-port: 宿主机与容器端口映射,方便容器对外提供服务
- nginx:alpine: 基于该镜像创建容器
仅仅让nginx做为静态服务
单独演示一下 -v 数据卷。
# 1. 新建 /Users/wfp/html/index.html ,内容自定义即可
# 让nginx服务指向外面(docker外面)的文件
# 2. 运行
docker run -p 81:80 -v=/Users/wfp/html:/usr/share/nginx/html -d --name nginx1 nginx
# 3. 访问 重新访问 localhost:81 ,看是否你创建的页面?
Dockerfile
在使用 docker 部署自己应用时,往往需要自己构建镜像。docker 使用 Dockerfile 作为配置文件构建镜像,
注意∶必须是 Dockerfile
这个文件名,必须在项目的根目录。
简单看一个 node 应用构建的Dockerfile
。
1、编写Dockerfile
# 基于一个旧有的镜像,格式: FROM <image> [AS <name>]
FROM node:alpine
# 把目录,或者 url 地址文件加入到镜像的文件系统中
ADD package.json package-lock.json /code/
WORKDIR /code
# 设置时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
# 构建镜像时,一般用于做一些系统配置,安装必备的软件。可有多个 RUN
# 安装
RUN npm set registry https://registry.npm.taobao.org
RUN npm install
RUN npm install pm2 -g
ADD . /code
# 启动容器时,只能有一个 CMD
CMD echo $SERVER_NAME && echo $AUTHOR_NAME &&npm run server && npx pm2 log #一定要是阻塞控制台的程序
# 环境变量
ENV SERVER_NAME="tanchidemao"
ENV AUTHOR_NAME="roy"
- Dockerfile描述了镜像如何构建和启动,应该要把一些麻烦的操作放在构建镜像的阶段去操作,然后在启动容器时,就会比较快。因为构建一般只有一次,启动是有多次的。
- 注意CMD后面一定要是能阻塞控制台的程序
- 本地安装pm2
npm i pm2 --save-dev
,或者Dockerfile中全局安装pm2 - 由于 Docker 容器中没有数据库环境,服务启动不会成功
可以临时修改一下,再测试:
- 去掉数据库连接
- 去掉
bin/www
数据同步 - Dockerfile
2、**.dockerignore**
文件忽略
.git
node_modules
logs
.docker-volumes
wfp_test
3、构建镜像并启动容器
docker build -t editor-server . # 构建 image
docker images
docker run -p 8081:3000 -d --name server1 editor-server # 创建容器,注意端口映射
docker ps
docker logs <container-id> # 需等待构建完成
# 访问 localhost:8081 ,查看 docker logs
docker stop <container-id>
docker rm <container-id>
docker rmi <image-id>
- 关于端口映射:单独用docker run 启动某个服务就需要进行端口映射。如果用docker-compose启动就不用,因为端口映射等相关参数已经写在配置文件里面了,所以其实用docker-compose up 比较方便
4、访问[http://0.0.0.0:8081/](http://0.0.0.0:8081/)
,查看日志:docker logs editor-server
多阶段构建
理解:这里最后生成的镜像以最后一个 FROM 为准,之前的会被抛弃。
底层原理
docker 底层使用了一些 linux 内核的特性,大概有 namespace,cgroups 和 ufs。
1、docker 使用 linux namespace 构建隔离的环境
它由以下 namespace 组成
- pid: 隔离进程
- net: 隔离网络
- ipc: 隔离 IPC
- mnt: 隔离文件系统挂载
- uts: 隔离hostname
- user: 隔离uid/gid
2、使用control groups限制资源
比如某个容器只能使用 100M 内存3、使用Union file systems进行分层
UnionFS 是一种分层、轻量级并且高性能的文件系统,支持对文件系统的修改作为一次提交来一层层的叠加。docker 的镜像与容器就是分层存储,可用的存储引擎有 aufs,overlay 等。
关于分层存储的详细内容可以查看官方文档 docker: About storage drivers