一、 写在前面
小弟对于Docker的理解还不够深刻,所以到网上找了很多教程,但是大多都是动辄十几二十小时的超长培训班教程,感觉事无巨细地把所有内容都灌输给你,但是平时我只需要用到其中的很小一部分命令,只需要知道Docker的整个工作流和概念就行,发现了一个宝藏博主:技术蛋老师,链接:🐳Docker概念,工作流和实践 - 入门必懂_哔哩哔哩_bilibili
二、 容器Contrainer
Docker不会创建完整的操作系统,但还是会创建独立的环境,也就是容器Container。
容器里面也是有操作系统的,这样可以跑着各自的应用程序,互不干扰。
容器之间共用的是主机的内核,但是容器不会直接访问内核,而是通过Docker引擎来访问。
三、 镜像Image
每个选手在特定厨房,根据特定步骤和材料做出来的菜,每个选手的菜都是独一无二的。拍照后这张照片就相当于Docker里的镜像image。各种版本的应用就定格形成镜像,如果其中有一个应用或者多个应用的版本不一样,就是另一个镜像了。
镜像是一个相对静态的东西,要让镜像动起来,也就是说我们可以根据不同的镜像,运行在不同的容器里面,做到相互隔离。
四、 定制镜像文件Dockerfile
厨师根据特定步骤和材料做菜,也就是根据不同的菜谱,比如第一步烧开水,第二部给鸡泡水,第三步给鸡去毛等。这个菜谱就相当于制作镜像的Dockerfile了。
每个镜像image的形成需要特定步骤,因为我们需要指明用什么操作系统,应用版本和各种指令。
如果你在特定的操作系统,使用特定版本的应用,以及各种依赖,那我们就可以把这些给写入Dockerfile,也就像写进我们的菜谱里面。
五、 构建镜像
- 要真正形成一个镜像,要使用
docker build
命令来构建,运行的时候Docker引擎就会构建镜像,这个镜像实际上是还没有运行的,就如同给做好的菜拍好了照片而已。 - 运行的话要使用
docker run
,这个命令让Docker引擎为我们分配一个新的容器。一个镜像分别可以在多个容器里运行。 - 制作好的镜像使用
docker push
,别人就可以去Docker Hub找适合自己的镜像 docker pull
把镜像拉取到自己的本地
六、 构建Dockerfile
FROM node:18-alpine3.15 # 选择操作系统,alpine是linux的轻量级发行版
WORKDIR /egg # 指定容器的工作目录,也可以不指定,但是很常用
COPY package.json . # 把本地的package.json复制到镜像里,因为package.json是Node项目的核心,里面也会指定依赖的版本;因为前面指明了工作目录,所以这里可以用相对地址,从本机当前文件夹复制到镜像里的egg文件夹
RUN npm install # 容器有了package.json,就可以用npm安装指定依赖,写Dockerfile就是前面提到的做菜的流程
COPY . . # 保存系统文件,把当前目录下的所有文件复制到容器的工作目录,为什么要写两个copy,因为npm install的花销非常大,我们一般都是改js文件,这样可以用缓存,再次执行dockerfile的时候就会很快
EXPOSE 3000 # 暴露端口号,我们在容器的端口号和本机的端口号是不一样的,各自处于不同的操作系统,不同的环境
CMD ["node", "app.js"] # 运行镜像里的app.js,用cmd命令,要注意cmd命令接的内容要用数组表示
注意,这个EXPOSE很坑,他只起到文档作用,就是告诉别人这个镜像用的端口,真正要起作用的话还是要做端口映射。我们开启了这个端口,容器里有其他应用要使用这个端口是ok的,只不过我们不行而已,因此需要进行端口映射。
# dokcker引擎自动寻找Dockerfile并进行构建
# .表示当前目录,即Dockerfile所在的目录
docker build .
docker build -t 名字 .
# 查看镜像
docker images
# 镜像命名
docker tag 344 用户名/镜像名:版本
# 删除镜像
docker rmi -f 镜像名/TAG # rm表示remove,i表示image,有时候镜像在使用中,-f表示force
# 运行镜像,-d是detached mode的缩写,让容器在后台运行,会返回容器id
# -p 端口映射,3000:3000表示访问主机端口3000的时候就会访问容器端口3000
# --name,如果不自定义名字,docker会自动给你的容器起一个名字
# 一个镜像可以起很多个容器的,镜像只是一张照片而已
# -v把本地指定文件夹和容器指定文件夹绑定,要绝对路径
# 绑定路径的话这样外面本机的文件改变后,容器里的文件也会改变
# 但是使用-v的话会使两边的文件夹进行绑定,也就是说本地的node_modules会覆盖掉容器里的
# 本地的node_modules如果没了或者修改了,容器里的也会同步删除或者修改
# 因此我们要申明容器里的某些文件夹是不能进行同步的,加个-v /egg/node_modules就好,说明node_modules里面的文件不进行同步
# 因为两边是同步的,如果容器有新增的文件或文件夹,本地也会同步新增
# 要解决这个问题,就是要让本地变为readonly,直接在第一个-v选项后面加上:ro就好了
docker run -d -v 本地路径:容器路径 -p 主机端口:容器端口 --name 自定义容器名字 镜像名
# process status
docker ps
# 暂停容器运行,相当于关机
docker stop 容器ID
# 查看所有容器,包括暂停运行的
docker ps -a
# 删除容器, -f可以强制移除在运行的容器
docker rm -f 容器id
# 访问容器, exec是execute执行的意思,和docker run差不多
# -i表示interactive交互,类似于上面的-t,-t表示以终端的方式交互,t表示pseudo-TTY伪终端
# /bin/sh表示执行一个新的bash shell,这是alpine进入shell的方式
# 回车即可进入容器,直接进入到工作目录的文件夹
docker exec -it 容器name /bin/sh
# 退出容器
exit
# 如果使用了volume,在删除容器的时候,记得把对应的volume给删掉,不然你的volume会越来越多
# 只需要在-f后面价格v就可以了
docker rm -fv 容器id
七、匿名卷(volume)
假设你运行了一个容器,并创建了一个匿名卷:
# 该容器会在主机上创建一个匿名卷,用于挂载 /data 目录。
docker run -d --name my-container -v /data my-image
# 删除容器时不加-v,容器被删除,但匿名卷仍然存在。
docker rm my-container
# 删除容器时加-v,容器和 关联的匿名卷 都会被删除。
docker rm -v my-container
# 如何查看和清理残留的匿名卷
# 查看所有卷
docker volume ls
● 输出示例:
DRIVER VOLUME NAME
local abc123def456
local xyz789uvw012
● abc123def456 和 xyz789uvw012 是匿名卷。
# 删除未使用的卷,该命令会删除 所有未被容器使用的卷,包括匿名卷。
docker volume prune
八、 docker-compose
每次运行docker时要写很长的命令,很麻烦,为了避免这种情况,就要使用docker-compose
touch docker-compose.yml
# 创建yml文件
version: "3.8" # 声明yml文件的版本
services: # 每个容器都需要在services底下声明,所以先写个services
xxx-container: # 容器名
build: . # 路径,根据当前文件夹进行构建,Docker引擎自动找Dockerfile去构建镜像
ports: # 端口映射
- "3000:3000"
volumes: # -v,这里可以用相对地址进行绑定
- ./:/egg:ro
- /egg/node_modules
# 运行docker-compose,-d:后台运行;--build:镜像有修改,docker-compose就会自动重建
# 不加--build,下次就会使用之前的缓存
docker-compose up -d --build
# 清除容器,记得加-v
docker-compose down -v
Docker
- Docker 是一个开源的容器化平台,允许开发者将应用程序及其依赖打包到一个轻量级、可移植的容器中。
- 它提供了创建、运行和管理容器的核心功能。
- 使用
Dockerfile
定义容器的镜像,然后通过docker build
构建镜像,通过docker run
运行容器。 - 适合单个容器的场景。
Docker Compose
- Docker Compose 是 Docker 的一个工具,用于定义和运行多容器 Docker 应用程序。
- 它通过一个
docker-compose.yml
文件来描述多个容器之间的关系、网络、卷等配置。 - 使用
docker-compose up
命令可以一次性启动所有定义的服务。 - 适合需要多个容器协同工作的场景(例如,一个 Web 应用可能需要一个 Web 服务器容器、一个数据库容器和一个缓存容器)。
关系总结
- Docker 是底层的基础工具,负责容器的创建和管理。
- Docker Compose 是基于 Docker 的上层工具,用于简化多容器应用程序的管理和部署。
- 你可以单独使用 Docker 来管理单个容器,但如果需要管理多个容器,Docker Compose 是一个更高效的选择。
举例
假设你有一个应用,需要一个 Web 服务器和一个数据库:
- 使用 Docker,你需要分别运行两个容器,并手动配置它们之间的网络连接。
- 使用 Docker Compose,你可以在
docker-compose.yml
中定义这两个服务,然后通过一条命令docker-compose up
启动整个应用。
总之,Docker Compose 是 Docker 的扩展工具,专门用于简化多容器应用的开发和部署。
九、 0.0.0.0详解
0.0.0.0:3000
表示 放行任意 IP,都可以访问你这台服务器的 3000 端口。
0.0.0.0
:
-
- 这是一个 通配符 IP 地址,表示 所有可用的网络接口。
- 包括:
-
-
- 本地回环地址(
127.0.0.1
,即localhost
)。 - 主机的内网 IP 地址(如
192.168.1.100
)。 - 主机的公网 IP 地址(如
203.0.113.1
)。
- 本地回环地址(
-
:3000
:
-
- 表示服务器的 3000 端口。
0.0.0.0:3000
的含义:
-
- 服务器监听所有网络接口的
3000
端口。 - 任何设备(无论是本机、局域网设备还是公网设备)都可以通过
3000
端口访问这台服务器。
- 服务器监听所有网络接口的