核心组成
Docker 中有三个核心概念:Image、Container、Repository。
- Image: 有领“好人卡”倾向的广大程序猿一定对 镜像 的概念不会陌生。但和 windows 的那种 iso 镜像相比,Docker 中的镜像是分层的,可复用的,而非简单的一堆文件迭在一起(类似于一个压缩包的源码和一个 git 仓库的区别)。
- Container: 容器的存在离不开镜像的支持,他是镜像运行时的一个载体(类似于实例和类的关系)。依托 Docker 的虚拟化技术,给容器创建了独立的端口、进程、文件等“空间”,Container 就是一个与宿机隔离 “容器”。容器可宿主机之间可以进行 port、volumes、network 等的通信。
- Repository: Docker 的仓库和 git 的仓库比较相似,拥有仓库名、tag。在本地构建完镜像之后,即可通过仓库进行镜像的分发。常用的 Docker hub 有 hub.docker.com/ 、 cr.console.aliyun.com/ 等。
应用场景
- Web 应用的自动化打包和发布。
- 自动化测试和持续集成、发布。
- 在服务型环境中部署和调整数据库或其他的后台应用。
- 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。
Docker安装
Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了
Windows Docker安装
Docker 并非是一个通用的容器工具,它依赖于已存在并运行的 Linux 内核环境。
Docker 实质上是在已经运行的 Linux 下制造了一个隔离的文件环境,因此它执行的效率几乎等同于所部署的 Linux 主机。
因此,Docker 必须部署在 Linux 内核的系统上。如果其他系统想部署 Docker 就必须安装一个虚拟 Linux 环境。
在 Windows 上部署 Docker 的方法都是先安装一个虚拟机,并在安装 Linux 系统的的虚拟机中运行 Docker。
以Win10 系统为例
Docker Desktop 是 Docker 在 Windows 10 和 macOS 操作系统上的官方安装方式,这个方法依然属于先在虚拟机中安装 Linux 然后再安装 Docker 的方法。
Docker Desktop 官方下载地址: hub.docker.com/editions/co…
注意: 此方法仅适用于 Windows 10 操作系统专业版、企业版、教育版和部分家庭版!
检查运行WSL2 docs.microsoft.com/zh-cn/windo…
安装完毕,通过 docker version 查看安装版本信息
MacOS Docker安装
macOS 我们可以使用 Homebrew 来安装 Docker。
Homebrew 的 Cask 已经支持 Docker for Mac,因此可以很方便的使用 Homebrew Cask 来进行安装:
brew install --cask --appdir=/Applications docker
CentOS Docker安装
Docker 支持以下的 64 位 CentOS 版本:
- CentOS 7
- CentOS 8
- 更高版本... 使用官方安装脚本自动安装 安装命令如下:
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
也可以使用国内 daocloud 一键安装命令:
curl -sSL https://get.daocloud.io/docker | sh
Docker 镜像加速
国内从 DockerHub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务,例如:
- 科大镜像:docker.mirrors.ustc.edu.cn/
- 网易:hub-mirror.c.163.com/
- 阿里云:https://<你的ID>.mirror.aliyuncs.com
- 七牛云加速器:reg-mirror.qiniu.com
当配置某一个加速器地址之后,若发现拉取不到镜像,请切换到另一个加速器地址。国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务。
阿里云镜像获取地址:cr.console.aliyun.com/cn-hangzhou…,登陆后,左侧菜单选中镜像加速器就可以看到你的专属地址了:
Win10 / MacOS Docker 镜像加速
点击Docker Desktop, 然后点击 Settings,打开配置窗口后左侧导航菜单选择 Daemon。在 Registrymirrors 一栏中填写加速器地址 hub-mirror.c.163.com/ ,之后点击 Apply 保存后 Docker 就会重启并应用配置的镜像地址了
Docker Hello-world
现在我们准备运行hello-world
方法1:远程 hello-world镜像
docker pull hello-world
docker run hello-world
方法2:用Node写一个hello world程序,然后在容器里跑起来
- 创建
docker-demo文件夹 - 创建
demo.js,并在demo.js里编写代码console.log('来自docker容器里运行的 hello world') - 编写 Dockerfile文件,并写入以下代码
FROM node:16.11.1-slim
COPY . ./demo
WORKDIR /demo
CMD node demo.js
- 进入
docker-demo目录,在命令行工具中运行docker image build -t demo . docker images查看镜像列表docker container run demo
Docker 常用命令
查看Docker构成及版本
docker version
列出所有镜像
docker image ls 或 docker images
从仓库拉取镜像
docker pull node
完整命令写法如下:
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
推送镜像到远程仓库
docker push [OPTIONS] NAME[:TAG]
OPTIONS说明:
- --disable-content-trust : 忽略镜像的校验,默认开启
举栗
docker push demo:v1
运行镜像
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
OPTIONS说明:
- -a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
- -d: 后台运行容器,并返回容器ID;
- -i: 以交互模式运行容器,通常与 -t 同时使用;
- -P: 随机端口映射,容器内部端口随机映射到主机的端口
- -p: 指定端口映射,格式为:主机(宿主)端口:容器端口
- -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
- --name="nginx-lb": 为容器指定一个名称;
- --dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
- --dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;
- -h "mars": 指定容器的hostname;
- -e username="ritchie": 设置环境变量;
- --env-file=[]: 从指定文件读入环境变量;
- --cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;
- -m : 设置容器使用内存最大值;
- --net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
- --link=[]: 添加链接到另一个容器;
- --expose=[]: 开放一个端口或一组端口;
- --volume , -v: 绑定一个卷
使用本地镜像 demo 以交互模式启动一个容器,在容器内执行/bin/bash命令。
docker run -it demo /bin/bash
使用docker镜像nginx:latest以后台模式启动一个容器,并将容器命名为myng。
docker run --name myng -d nginx:latest
使用镜像nginx:latest以后台模式启动一个容器,并将容器的80端口映射到主机随机端口。
docker run -P -d nginx:latest
使用镜像 nginx:latest,以后台模式启动一个容器,将容器的 80 端口映射到主机的 80 端口,主机的目录 /data 映射到容器的 /data。
docker run -p 80:80 -v /data:/data -d nginx:latest
绑定容器的 8080 端口,并将其映射到本地主机 127.0.0.1 的 80 端口上。
docker run -p 127.0.0.1:80:8080/tcp ubuntu bash
使用镜像nginx:latest以交互模式启动一个容器,在容器内执行/bin/bash命令。
docker run -it nginx:latest /bin/bash
删除镜像
# image_name表示镜像名,image_id表示镜像id
docker image rm image_name/image_id
或
docker rmi image_name/image_id
查看所有容器
docker container ls
或
docker ps
启动容器
启动容器有两种方式,一种是我们前面已经介绍过的,使用docker run命令通过镜像创建一个全新的容器
docker run hello-world
另外一种启动容器的方式就是启动一个已经停止运行的容器:
# container_id表示容器的id
docker start container_id
停止正在运行的容器
docker container stop container_id
或
docker stop container_id
进入容器
# command 为linux命令, eg: /bin/bash
docker exec -it container_id command
删除容器
删除某个容器,请先用 docker ps 查看容器id
docker rm container_id
删除所有容器
docker rm $(docker ps -q)
删除所有退出的容器
docker container prune
登录登出
登录
docker login -u 用户名 -p 密码
登出 Docker Hub
docker logout
从Docker Hub查找镜像
docker search [OPTIONS] TERM
OPTIONS说明:
- --automated : 只列出 automated build类型的镜像;
- --no-trunc : 显示完整的镜像描述;
- -f <过滤条件>: 列出收藏数不小于指定值的镜像。
举栗
docker search -f stars=10 node
容器与主机之间copy文件
docker cp : 用于容器与主机之间的数据拷贝。 语法如下
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
OPTIONS说明:
- -L : 保持源目标中的链接
举栗
主机文件拷贝进容器
将windows主机下的docker-demo目录下的文件test.txt拷贝仅 容易的/demo目录下, 其中d5e7e5080b47为对应的容器ID
docker cp D:\\docker-demo\\test.txt d5e7e5080b47:/demo
将容器文件拷贝到主机
将容器中的demo目录拷贝到主机D:\docker-demo2目录下
docker cp d5e7e5080b47:/demo D:\\docker-demo2
结果如下图
Visual Studio Code Docker拓展
Docker
Remote - Containers
Docker部署前端项目
Dockerfile最简单配置
FROM nginx:latest
# 设置linux时区为东8区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone
# 将当前项目打包生成的dist文件夹copy到容器的nginx的默认目录
COPY dist/ /usr/share/nginx/html/
# 暴露端口8080
EXPOSE 8080
Dockerfile最佳实践
FROM nginx:latest
# 设置linux时区为东8区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone
# 将当前项目打包生成的dist文件夹copy到容器的nginx的默认目录
COPY dist /usr/share/nginx/html/fe-proj
# 在项目根目录下的nginx个性化配置
COPY default.conf /etc/nginx/conf.d/
# 暴露端口8080
EXPOSE 8080
Docker部署Nodejs项目
Dockerfile
FROM node:8.11.1
# 设置linux时区为东8区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone
# 容器中创建fe-node-proj目录
RUN mkdir -p /fe-node-proj
# 将当前项目所有文件copy到容器的/fe-node-proj目录
COPY . /fe-node-proj
WORKDIR /fe-node-proj
# 全局安装pm2
RUN npm install pm2@4.5.2 -g --registry=https://registry.npmmirror.com
# 安装pm2插件pm2-logrotate
RUN pm2 install pm2-logrotate
# 设置pm2保留的日志文件个数为50个
RUN pm2 set pm2-logrotate:retain 50
# 设置pm2单个日志文件文件大小最大为 30M
RUN pm2 set pm2-logrotate:max_size 30M
# 声明容器中/share/log为匿名卷 (可选。推荐,因为有些情况需要同步pm2日志到宿主机记录起来,方便后续扫描日志到日志平台)
VOLUME /share/log
# 暴露端口8080
EXPOSE 8080
# 容器启动后执行pm2启动服务,这里必须为 pm2-runtime
# pm2-runtime是为Docker容器设计的,它将应用程序置于前台,从而使容器保持运行状态
CMD ["pm2-runtime", "start", "/fe-node-proj/pm2.config.json"]
pm2.config.json
{
"apps": [
{
"name": "fe-node-proj-service",
"script": "app.js",
"cwd": "./",
"instances": 1,
"error_file": "/share/log/fe-node-proj-service/error.log",
"out_file": "/share/log/fe-node-proj-service/out.log",
"log_date_format": "YYYY-MM-DD HH:mm:ss"
}
]
}
那么使用该Dockerfile构建镜像的命令为
# 构建镜像fe-node
docker build -t fe-node
# 运行一个容器并且将当前机器的/log目录绑定到容器的匿名卷中
docker run -d -it -name fe-node-container -v /log:/share/log fe-node
# 运行一个容器但是不绑定目录到容器的匿名卷,这时候再/var/lib/docker/volumes(不同版本目录不一样)中就会创建一个目录绑定匿名卷
docker run -d -it -name fe-node-container fe-node
利用docker动态扩容出来的Node服务截图