docker
云部署已逐渐被 Kubernetes + containerd 替代
vim /etc/docker/daemon.json
{"registry-mirrors": ["https://xxxxx.mirror.aliyuncs.com"]}
常用命令
# run 创建并运行容器,如果没有镜像会自动pull
# --name 必须唯一
# 如果启动2个MySQL,宿主机的端口必须是唯一的。但是容器的端口都可以叫3306,因为容器内是隔离的。宿主机端口:容器端口
# -e 环境变量,可以多个。由镜像决定
# -it 直接进入终端
# --privileged -u root 更高权限运行
# --entrypoint /bin/sh 入口点覆盖为/bin/sh
# --rm 容器停止后,自动删除容器
# --add-host=host.docker.internal:host-gateway 在容器内添加DNS解析规则,使host.docker.internal指向宿主机IP。此配置允许容器内应用访问宿主机上的服务
# --restart always ghcr.io/open-webui/open-webui:main 确保容器退出后自动重启,提高服务的可用性
docker run -d --name mysql1 -p 3306:3306 -e TZ=Asia/Shanghai -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
# 查看容器,能看到IP地址、挂载信息、环境变量等
docker inspect mysql1
# 查看镜像
docker images
# 删除镜像
docker rmi
# 停止容器
docker stop
# 启动容器
docker start
# 查看容器运行状态,-a查看所有容器
docker ps
# 查看容器运行日志,-f持续跟踪
docker logs 容器名
# 进入容器,-it可交互终端。bash使用bash进行交互
docker exec -it 容器名 bash
# 直接使用mysql命令进行交互
docker exec -it mysql_container mysql -u root -p
# 删除容器,-f强制删除
docker rm
# docker cp命令用于从正在运行的Docker容器里面,将文件拷贝到本机
docker cp [containID]:[/path/to/file] .
# docker镜像地址不填,默认为:Docker Hub
# 仓库名为<用户名>/<软件名>,官方镜像<用户名>默认为library,可不填
docker pull [选项] [docker镜像地址[:端口号]/]仓库名[:标签]
# 示例,镜像地址为:docker.1ms.run/mintplexlabs,仓库名为:anythingllm
docker pull docker.1ms.run/mintplexlabs/anythingllm
# 查看已下载的镜像体积
docker system df
# 查看image历史变更
docker history image_name或image_id
数据卷
数据卷(volume)是一个虚拟目录,是容器内目录和宿主机目录之间映射的桥梁
通常在 /var/lib/docker/volumes 下,具体在哪可以通过 docker volume inspect 查看
# 查看帮助信息
docker volume --help
# 创建数据卷
docker volume create
# 查看所有数据卷
docker volume ls
# 删除指定数据卷
docker volume rm
# 查看某个数据卷的详情
docker volume inspect 数据卷名
# 删除所有未使用的数据卷
docker volmue prune
挂载数据卷,需要在 docker run 的时候使用 -v 数据卷名:容器内目录 进行挂载
如果挂载时,所需要的数据卷不存在会自动创建。即:不需要显式调用 docker volume create
docker run -d --name nginx1 -p 8080:80 -v nginx_public:/usr/share/nginx/html nginx
本地目录挂载
挂载本地目录,需要在 docker run 的时候使用 -v 宿主机目录:容器内目录(只要把数据卷名改成本地目录即可)
目录必须以 / 或 ./ 开头,否则会被认为是数据卷名
挂载前,需要在宿主机创建目录。以下是MySQL挂载示例
docker run -d --name mysql1 -v /root/mysql/data:/var/lib/mysql \ -v /root/mysql/conf:/etc/mysql/conf.d \ -p 3306:3306 -e TZ=Asia/Shanghai -e MYSQL_ROOT_PASSWORD=123456 \ mysql:5.7
自定义镜像
镜像就是包含了应用程序、程序运行的系统函数库、运行配置等文件的文件包
构建镜像的过程其实就是把上述文件打包的过程
入口(Entrypoint):镜像运行入口,一般是程序启动的脚本和参数
层(Layer):添加安装包、依赖、配置等,每次操作都形成新的一层
基础镜像(BaseImage):应用依赖的系统函数库、环境、配置、文件等
设置 Dockerfile
Dockerfile中包含了一个个指令,用指令来说明要执行什么操作
# ARG定义变量,docker build的时候可以通过 --build-arg VERSION=8 修改变量
ARG VERSION=6
# 指定基础镜像
FROM centos:$VERSION
# 设置环境变量,可以在后面的指令使用
ENV key value
# 将工作目录切换为/tmp
WORKDIR /tmp
# 将当前目录下的所有内容(除.dockerignore排除的)复制到image文件的/app下
COPY . /tmp
# 执行Linux的shell命令,一般是安装过程的命令
RUN tar -zxvf /tmp/jre11.tar.gz && EXPORTS path=/tmp/jre11:$path
# 指定容器运行时监听的端口,是给镜像使用者看的
EXPOSE 8080
# 镜像中应用的启动命令,容器运行时调用
ENTRYPOINT java -jar xx.jar
以上命令,以及有人制作了JDK的基础镜像,可以简化
FROM openjdk:11.0-jre-buster
COPY docker-demo.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
# 也可以使用CMD,但是两者是有区别的
# ENTRYPOINT 定义容器启动时必须执行的主命令(不可被覆盖,除非使用 --entrypoint)
# 而 CMD 提供默认参数或可被 docker run 参数覆盖的默认命令,两者结合时 CMD 作为 ENTRYPOINT 的默认参数
# CMD ["java", "-jar", "/app.jar"]
ENTRYPOINT定义主命令,CMD提供默认参数,示例如下:
ENTRYPOINT ["nginx"]
CMD ["-g", "daemon off;"]
默认执行 nginx -g 'daemon off;'
用户可通过 docker run my-nginx -s reload 覆盖 CMD,最终执行 nginx -s reload
构建镜像(通常与Dockerfile同目录),docker build -t repository:tag . 如果不写tag,默认latest
docker build -t myImage:1.0 .
保存、加载镜像
docker save xxx.tar
docker load -i xxx.tar
方式2:
docker push
docker pull
容器网络互联
默认情况下,所有容器都是以bridge方式连接到docker的一个虚拟网桥上
默认虚拟网卡: docker0 172.17.0.1/16
容器间是可以互通互联的,但是IP地址是不固定的
加入自定义网络的容器可以通过容器名互相访问,可以避免IP地址不固定的问题
# 创建一个网络
docker network create 网络名
# 查看所有网络
docker network ls
# 删除指定网络
docker network rm 网络名
# 清除未使用的网络
docker network prune
# 使指定容器连接加入某网络
docker network connect 网络名 容器名
# 使指定容器连接离开某网络
docker network disconnect 网络名 容器名
# 查看往来详细信息
docker network inspect 网络名
也可以在容器创建的时候直接加入网络
docker run -d --name redis -p 6379:6379 --network 网络名 redis
compose
Docker Compose通过一个单独的docker-compose.yml文件来定义一组相关联的应用容器
配置docker-compose.yml
- version - 表示模板使用的规则版本号
- services - 表示所有服务
- webapp - 表示服务名称
- containername - 指定容器名称,不填默认为:项目名称服务名称_序号
- image - 表示镜像
- working_dir - 工作路径
- expose - 暴露端口,但不映射到宿主机,只被连接的服务访问
- ports - 表示端口映射
- env_file - 从文件中获取环境变量,可以是一个或多个文件
- depends_on - 解决容器的依赖、启动先后的问题,先启动redis再启动webapp
- environment - 设置环境变量
模板示例1:
version: "3.8"
services:
webapp:
image: A
container_name: A
env_file: .env
working_dir: /wwwroot/
ports:
- "11:11"
containerB:
image: B
container_name: B
ports:
- "22:22"
模板示例2:
version: "3.8"
services:
mysql:
image: mysql
container_name: mysql
ports:
- "3306:3306"
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: 123456
volumes:
- "./mysql/conf:/etc/mysql/conf.d"
- "./mysql/data:/var/lib/mysql"
networks:
- bestlove
my_project:
build:
context: .
dockerfile: Dockerfile
container_name: stock
ports:
- "8080:8080"
networks:
- bestlove
depends_on:
- mysql
networks:
bestlove:
name: bestlove
docker compose [OPTIONS] [COMMANDS]
# Options
-f 指定compose文件的路径和名称
-p 指定project名称
-d 后台运行
# Commands
up 创建并启动所有service容器
down 停止并移除所有容器、网络
ps 列出所有启动的容器
logs 查看指定容器的日志
stop 停止容器
start 启动容器
restart 重启容器
top 查看运行的进程
exec 在指定的运行容器中执行命令
docker compose down && docker compose up -d
Linux别名
有些命令比较常用又比较长,不方便书写。可以使用linux的别名
vim ~/.bashrc
# 内容设置举例
alias dps='docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"'
source ~/.bashrc
发布自定义镜像
.dockerignore