docker 常用命令
资料
docker 服务操作
- sudo systemctl start docker
- sudo systemctl stop docker #停止
- sudo systemctl restart docker #重新启动
- sudo systemctl enable docker #开机自动启动
设置镜像加速
- ⚠️:此处以阿里云举例「加速地址只能在自己的云平台中使用」
- 阿里云 aliyun.com
- 登录 阿里云
- 选择菜单->【产品】-> 【容器】-> 【容器镜像服务 ACR】-> 点击按钮【管理控制台】-> 左侧菜单【镜像工具->镜像加速器】-> 会看到一个镜像加速地址
- 不收费
- 加速地址: https://iiesyla9.mirror.aliyuncs.com
- 具体配置方法下面有详细的说明
#如果没有/etc/docker目录就建立,没有daemon.json文件就建立。 #此处举例为没有这个目录和文件 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://iiesyla9.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
查看版本
- docker --version 「-v」 只能查看版本号,不能看出来是ce 还是 io 版本。
- docker version 可以查看时ce还是io版本。
配置文件位置
- ⚠️:没有 /etc/docker 目录和daemon.json 文件也是正常的。
- linux
- /etc/docker/daemon.json
- mac
- ~/.docker/config.json
根目录存储位置
- linux
docker info #命令,里面有一项 Docker Root Dir: /var/lib/docker #映像文件存储位置默认路径: /var/lib/docker - mac
- 在docker的图形设置界面中,有一个磁盘的选项里面有具体大小的配置,是一个很大的raw文件。
查看容器详细信息
- 命令: docker inspect 容器名
- Mounts:挂载的卷
- Networks:网络信息
- Ports:映射的端口
- Config:包括:环境变量、Cmd、使用的映像、EntryPoint「入口命令」、Volumes等
监控docker
#类似linux的top命令
docker stats
镜像操作
- docker pull 镜像名称 「拉取镜像」
- docker images 「查看本地镜像列表」
- docker rmi 镜像名字 「删除指定镜像」
- docker push 「推镜像到镜像仓库」
容器相关操作
- docker create 「创建容器」
#使用docker镜像nginx:latest创建一个容器,并将容器命名为myrunoob docker create --name myrunoob nginx:latest - docker run 「创建并运行一个容器」
#如果没有发现镜像,会下载一个镜像,然后运行容器 docker run -d --name mysql -p 3306:3306 -e TZ=Asia/Shanghai -e MYSQL_ROOT_PASSWORD=123 mysql- -d : 容器后台运行;不加这个参数会卡住在控制台,停止后进程会停止
- --name 指定容器的名称
- -p 宿主机端口:容器内端口
- 例如: -p 3307:3306
- -e 环境变量,不同镜像的变量不同
- mysql 是镜像的名字
- 完整写法: mysql:5.7
- tag不写就是 lastest
- -v 宿主机目录:容器内部目录
- 宿主机目录没有:自动创建
- 容器内部目录没有:自动创建
- 都没有:同时创建
- -w
- 指定容器内部的工作目录
- docker stop 容器 「停止容器的运行,并没有删除容器」
- docker start 容器 「启动 容器进程」
- docker ps
- 查看容器状态,默认只显示运行的容器 -a 查看所有容器
- 已表格的方式查看
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}" #可以做一个linux的命令别名 dps='docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"' #简化显示 docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}\t{{.ID}}" - docker rm
- 删除容器 容器中的数据会被删除
- -f 强制删除容器,可以删除运行的容器
- docker exec
- 执行命令进入容器内步
- -it 进入交互状态
docker exec -it 容器名 bash #执行mysql 命令 带参数 docker exec -it 容器名 mysql -uroot -p
- docker save 「可以写多个image,这样就把多个镜像保存了」
docker save -o 输出文件名.tar ngnix:latest
- docker load 「不用写映像的名字,文件中自己会指定」
docker load -i file.tar
- docker logs 「查看容器日志」
#查看日志 -f 是follow的缩写,查看日志不停,持续输出
docker logs -f 容器名
- docker cp 「拷贝容器里面的文件到宿主机 nginx 是容器名称」
docker cp nginx:/etc/nginx/nginx.conf /home/nginx/conf/nginx.conf
帮助
- docker 命令 --help
#查看save命令的帮助
dockder save --help
#查看run命令的帮助
docker run --help
磁盘的使用情况
- docker system df
清理镜像、容器、卷、网络
- 清理 「镜像、容器、卷、网络的清理」
- https://blog.51cto.com/u_16175493/8099417
- sudo docker image prune
- 清理悬空镜像
- sudo docker system prune -a
- 清理未使用的镜像、容器、网络和卷
- 加上
-a参数后,命令还会删除所有未被容器使用的悬空镜像(dangling 和非 dangling 镜像都会被清理)。
#清理停止的容器
docker container prune
#清理悬空的镜像
docker image prune
#清理未被任何容器使用的卷
docker volume prune
#清理未被任何容器使用的网络
docker network prune
卷被哪些容器使用
docker ps -a --filter volume=VOLUME_NAME_OR_MOUNT_POINT
数据卷
- 说明 - 容器内部都是最小化安装的,不会安装vi等工具。 - 所以容器中的工作内容最好通过卷的形式映射到宿主机中。
- volume
- 是一个虚拟目录,是内容目录与宿主机目录之间映射的桥梁
- 数据卷目录固定存放在宿主机
- /var/lib/docker/volumes 下面
- volumes下建立目录例如: html/_data 对应html数据卷 conf/_data 对应conf数据卷
- 命令
- docker volume create
- 创建卷
- docker volume ls
- 查看
- docker volume rm
- 删除
- docker volume prune
- 删除没有使用的本地卷
- docker volume inspect
- 查看某个数据卷的详细信息
- docker run
- -v 数据卷名字:容器内目录
- ⚠️:-v 卷名:容器目录,直接写名字:就是卷名,使用绝对或相对路径就是挂载本地目录
- -v nginx-html:/usr/share/nginx/html 「使用卷: nginx-html」
- -v ./nginx-html:/usr/share/nginx/html 「挂载本地目录: ./nginx-html」
- ⚠️:数据卷不存在会自动创建,并会拷贝容器中的内容
- 用途⚠️:可以使用没有的卷做映射,这样可以把容器里的数据和配置文件拿到
#系统中没有nginx-html卷, 执行此命令后创建卷并且卷中有网页内容 sudo docker run --name nginx -v nginx-html:/usr/share/nginx/html -d nginx:stable - ⚠️:-v 卷名:容器目录,直接写名字:就是卷名,使用绝对或相对路径就是挂载本地目录
- -v 数据卷名字:容器内目录
- docker inspect 容器名
- 查看容器详情
- 匿名卷
- 不是我们创建的,容器创建的时候默认创建的卷叫匿名卷,名字是一长串。
- mysql : 创建mysql容器的时候,会自动创建一个存储数据库数据的卷
- 删除容器的时候数据卷不会被删除
- 也就是说数据会被永久保留
本地目录挂载
- docker run -v 本地目录:容器内目录
- 与挂载数据卷方法相同,只是使用的本地目录
- 目录必须使用路径开头,可以是绝对路径或相对路径。
- 例如: -v mysql:/var/lib/mysql 这就是挂载一个数据卷 -v ./mysql:/var/lib/mysql 就是挂载本地目录
- 步骤,查看映像官方文档,把所有需要的目录都挂载到本地。

- mysql 挂载本地目录

#本地的三个目录要提前创建好 #配置文件和脚本,提前拷贝进去 , 配置文件可以通过提前安装一个myslq进行获取。 docker run -d \ --name mysql \ -p 3306:3306 \ -e TZ=Asia/Shanghai \ -e MYSQL_ROOT_PASSWORD=123 \ -v ./data:/var/lib/mysql \ -v ./init:/docker-entrypoint-initdb.d \ #只在run的时候执行 -v ./conf:/ect/mysql/conf.d \ mysql #执行后data目录会有数据库的内容 #run的时候把初始化数据库的脚本放到初始化目录里面。进行数据库的创建和基础数据的加入。
本地文件和文件夹挂载到容器的文件关系
背景介绍
docker volume 可以使我们在启动docker容器时,动态的挂载一些文件(如配置文件), 以覆盖镜像中原有的文件,但是,挂载一个主机上尚不存在的文件夹或者文件到容器中会怎样呢?这里特意做了一下实践,记录实验结果如下:
「文件夹挂载」
docker在文件夹挂载上的行为是统一的,具体表现为:
- 若文件夹不存在,则先创建出文件夹(若为多层文件夹,则递归创建)
- 用host上的文件夹内容覆盖container中的文件夹内容
docker run -v /path-to-folder/A:/path-to-folder/B test-image
详细说明如下:
host上文件夹存在,且非空
| host | container | mount result |
|---|---|---|
| 存在的非空文件夹A | 不存在的文件夹B | 先在contanier中创建文件夹B,再将A文件夹中的所有文件copy到B中 |
| 存在的非空文件夹A | 存在的非空文件夹B | 先将container中文件夹B的原有内容清空,再将A中文件copy到B中 |
无论container中的文件夹B是否存在, A都会完全覆盖B的内容
host上文件夹存在,但为空
| host | container | mount result |
|---|---|---|
| 存在的空文件夹A | 存在的非空文件夹B | container中文件夹B的内容被清空 |
container中对应的文件夹内容被清空
host上文件夹不存在
| host | container | mount result |
|---|---|---|
| 不存在的文件夹A | 存在的非空文件夹B | 在host上创建文件夹A,container中文件夹B的内容被清空 |
| 不存在的文件夹A/B/C | 存在的非空文件夹B | 在host上创建文件夹A/B/C,container中文件夹B的内容被清空 |
container中对应的文件夹内容被清空
总结
host上文件夹一定会覆盖container中文件夹:
| host | container | mount result |
|---|---|---|
| 文件夹不存在/文件夹存在但为空 | 文件夹不存在/存在但为空/存在且不为空 | container中文件被覆盖(清空) |
| 文件夹存在且不为空 | 文件夹不存在/存在但为空/存在且不为空 | container中文件夹内容被覆盖(原内容清空, 覆盖为host上文件夹内容) |
「文件挂载」
文件挂载与文件夹挂载最大的不同点在于:
- ⚠️:docker 禁止用主机上不存在的文件挂载到container中已经存在的文件
- 文件挂载不会对同一文件夹下的其他文件产生任何影响
除此之外, 其覆盖行为与文件夹挂载一致,即:
- 用host上的文件的内容覆盖container中的文件的内容
docker run -v /path-to-folder/non-existent-config.js:/path-to-folder/config.js test-image # forbidden
详细说明如下:
- host上文件不存在
| host | container | mount result |
|---|---|---|
| 不存在的文件configA.js | 已经存在的文件congfigB.js | 报错,Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type. 同时会在host上生成两个空目录 configA.js 和 configB.js, 但是container无法启动 |
- host上文件存在
| host | container | mount result |
|---|---|---|
| 存在的文件configA.js | 存在的文件congfigB.js | container中文件名configB.js保持不变,但是文件内容被congfigA.js的内容覆盖了 |
| 存在的文件configA.js | 不存在的文件congfigB.js | container中新建一个文件configB.js,其内容为configA.js的文件内容, configB.js所在文件下的所有其他文件维持不变 |
- 总结
host上文件一定会覆盖container中文件夹
| host | container | mount result |
|---|---|---|
| 不存在的文件 | 已经存在的文件 | 禁止行为 |
| 存在的文件 | 不存在的文件/已经存在的文件 | 新增/覆盖 (若目录不存在则会创建目录) |
结论
「文件夹挂载」
- 允许不存在的文件夹或者存在的空文件夹挂载进container, container中对应的文件夹将被清空
- 非空文件夹挂载进container将会覆盖container中原有文件夹
「文件挂载」
- 禁止将不存在的文件挂载进container中已经存在的文件上
- 存在的文件挂载进container中将会覆盖container中对应的文件, 若文件不存在则新建
应用场景
- 从上面的分析可知,文件夹挂载以整个文件夹为单位进行文件覆盖,故可在需要将大量文件挂载进container时使用,另外,如果挂载一个空文件夹或者不存在的文件夹,一般是做逆向使用: 即容器启动后,可能会在容器内挂载点的文件夹下生成一些文件(如日志),此时,在对应的host上的文件夹内就能直接看到。
- 文件挂载由于只会覆盖单个文件而不会影响container中同一文件夹下的其他文件,常常被用来挂载配置文件,以在运行时,动态的修改默认配置。
特别注意
容器中类似mysql,redis这样的数据目录可以映射到宿主机目录的原因是,目录里的内容不是在容器启动前就存在的,而是在容器启动后生成的。
- 下面是mysql容器运行的时候对数据目录的处理:
内容来自deepseek
当您运行 MySQL 的 Docker 容器时,数据目录的初始化过程会根据不同场景(首次运行/非首次运行)和配置方式(环境变量/挂载卷/Dockerfile 等)有所差异。以下是详细流程:
---
### 1. **首次运行容器时的初始化逻辑**
MySQL 官方镜像(如 `mysql:8.0`)的 `ENTRYPOINT` 脚本会执行以下关键步骤:
#### **(1) 检查数据目录是否为空**
- **目标目录**:默认是 `/var/lib/mysql`(可通过 `$MYSQL_DATA_DIR` 自定义)。
- **如果目录为空**(如首次运行或挂载了空目录):
- 调用 `mysql_install_db`(MySQL 5.7 及以下)或 `mysqld --initialize-insecure`(MySQL 8.0+)初始化数据目录。
- 生成系统表(如 `mysql`、`sys`、`performance_schema` 等)。
- 创建默认用户(`root@localhost`)并设置初始密码(通过 `$MYSQL_ROOT_PASSWORD` 或随机密码)。
#### **(2) 应用自定义配置**
- 通过环境变量(如 `$MYSQL_DATABASE`、`$MYSQL_USER` 等)创建指定的数据库和用户。
- 执行 `/docker-entrypoint-initdb.d/` 下的脚本(`.sh`/`.sql`/`.sql.gz`),用于导入数据或自定义配置。
#### **(3) 启动 MySQL 服务**
- 最终以 `mysqld` 启动服务,数据目录初始化完成。
---
### 2. **非首次运行的行为**
- **如果数据目录已存在且非空**(如挂载了已有数据的宿主机目录或复用卷):
- **跳过初始化**,直接启动 `mysqld`。
- 原有数据(包括数据库、用户、权限等)会被保留。
---
### 3. **关键配置方式与示例**
#### **(1) 使用环境变量初始化**
bash
docker run -d --name mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=myapp \
-e MYSQL_USER=user \
-e MYSQL_PASSWORD=pass \
mysql:8.0
- 首次运行时自动初始化数据目录并创建指定数据库和用户。
#### **(2) 挂载宿主机目录或卷**
bash
# 挂载宿主机目录(需确保目录权限正确)
docker run -d --name mysql \
-v /path/on/host:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0
# 使用命名卷(推荐)
docker volume create mysql_data
docker run -d --name mysql \
-v mysql_data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0
- **首次挂载空目录**:容器会初始化数据到宿主机目录。
- **挂载已有数据目录**:直接使用现有数据。
#### **(3) 通过 `/docker-entrypoint-initdb.d/` 初始化数据**
bash
# 将 SQL 脚本或 Shell 脚本挂载到初始化目录
docker run -d --name mysql \
-v ./init-scripts:/docker-entrypoint-initdb.d \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0
- 脚本按字母顺序执行(例如 `01-create-tables.sql`、`02-insert-data.sh`)。
---
### 4. **数据目录权限问题**
MySQL 容器默认以 `mysql` 用户(UID: 999)运行,需确保挂载的宿主机目录权限正确:
bash
mkdir -p /path/on/host
chown -R 999:999 /path/on/host # 或 chmod 777(测试用途)
---
### 5. **调试技巧**
- **查看初始化日志**:
bash
docker logs mysql # 观察首次运行的初始化输出
- **手动进入容器检查**:
bash
docker exec -it mysql bash
ls /var/lib/mysql # 查看数据文件
---
### 总结表
| 场景 | 行为 |
|--------------------------|----------------------------------------------------------------------|
| **首次运行 + 空目录** | 初始化数据目录,创建系统库和默认用户,执行自定义脚本。 |
| **首次运行 + 非空目录** | 直接使用现有数据,跳过初始化。 |
| **非首次运行** | 直接启动 `mysqld`,保留原有数据。 |
| **挂载 `initdb.d` 脚本** | 仅在首次初始化时执行(数据目录为空时)。 |
通过合理组合环境变量、卷挂载和初始化脚本,可以灵活控制 MySQL 容器的数据初始化流程。
Dockerfile
制作自己的镜像
用途
⚠️:我们自己制作好的项目做成镜像需要以下内容:
- 安装JRE并配置环境变量
- 拷贝JAR包
- 运行JAR
做好镜像后就可以直接发布。

- Dockerfile 「就是一个文件,包含一个个的指令,用于定义如何构建Docker镜像。」
- 常见命令

- FROM
- 指定基础镜像
- FROM centos:6
- ENV
- 设置环境变量,可以在后面指令使用
- ENV key value
- COPY
- 拷贝本地文件到镜像指定的目录
- COPY ./jrell1.tar.gz /tmp
- RUN
- 执行Linux的shell命令,一般是安装过程命令
- RUN targ -zxvf /tmp/jre11.tar.gz && EXPORTS path=/tmp/jre11:$path
- RUN yum -y install vim
- 安装vim
- EXPOSE
- 指定容器运行时监听的端口,是给镜像使用者看的
- EXPOSE 8080
- ENTRYPOINT
- 镜像中应用的启动命令,容器运行时调用
- ENTRYPOINT java -jar xx.jar
- WORKDIR
- 设置工作目录
- WORKDIR /app
- MAINTAINER
- 指定维护者信息
- 可以包括:姓名 邮箱等
# 指定维护者信息 MAINTAINER OceanXDevelopment <isupport@oceanxtech.com> - ADD
- 该命令将复制指定的 路径下内容到镜像中的 路径下
- ⚠️:ADD 和 COPY 的区别和使用场景
- ADD 支持添加远程 url 和自动提取压缩格式的文件,COPY 只允许从本机中复制文件
- COPY 支持从其他构建阶段中复制源文件(–from)
- 根据官方 Dockerfile 最佳实践,除非真的需要从远程 url 添加文件或自动提取压缩文件才用 ADD,其他情况一律使用 COPY
- ⚠️:ADD 从远程 url 获取文件和复制的效果并不理想,因为该文件会增加 Docker Image 最终的大小。相反,应该使用 curl huo wget 来获取远程文件,然后在不需要它时进行删除
- VOLUME
- 创建一个匿名数据卷挂载点
VOLUME /home/ruoyi/redis
- 官方详细文档
- 例子:从ubuntu 构建一个java运行项目
#指定基础镜像
FROM ubuntu:16.04
#配置环境变量,JDK的安装目录,容器内识趣
ENV JAVA_DIR=/usr/local
#拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
#安装 jdk
RUN cd $JAVA_DIR \
&& tar -xf ./jdk8.tar.gz \
&& mv ./jdk1.8.0_144 ./java8
#配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$JAVA_HOME/bin
#入口,java项目的启动命令
ENTRYPOINT ["java", "-jar", "/tmp/app.jar"]
- 例子:从jdk镜像构建一个java项目
方法一: 直接把jar文件构拷贝到包中。 此方法适合发布不修改的jar项目。
#基础镜像
FROM openjdk:11.0-jre-buster
#设置时区,默认时区不是东八区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
#拷贝jar包
COPY docker-demo.jar /app.jar
#入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
方法二:
- 首先构建一个openjdk镜像
#Dockerfile
#基础镜像
FROM openjdk:11.0-jre-buster
#设置时区,默认时区不是东八区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
- 用run构建容器
#run 后面可以直接跟执行命令,这样可以把jar文件映射进去,然后启动执行
sudo docker run -d --name app.jar -p 8080:8080 -v ./app:/app openjdk11:1.0 java -jar /app/app.jar
#更新jar包: 只需要stop容器,更新jar文件,start容器即可。
- 命令
- docker build -t myImage:1.0 .
- -t tag的缩写,后面是名称:tag . 在最后,指定dockerfile文件所在的目录 注意COPY中使用的路径都是相对这个路径的
- 建立好的镜像就在docker中,可以使用docker images 查看
- 配置文件名: Dockerfile
- docker build -t myImage:1.0 .
容器网络互联
- docker inspect 容器名
- 可以查看容器的ip地址,每个容器都有自己的ip地址
- 初始网络
- 安装docker的时候会在机器上安装一个虚拟网卡:名字 docker0 并创建一个虚拟的网桥:172.17.0.1/16 【16】前16位不能动
- 容器之间是可以互相连通的
- 容器的ip地址不是固定的,需要做自定义网络,可以通过容器名访问
- 不能使用IP地址链接,ip地址是会变的
- 同一网桥中的容器可以互相访问,不是同一网桥的不能互相访问。
- ⚠️:默认网络不能通过容器名称进行互相访问,ip地址可以,但IP地址是变化的不准确不能使用

- 自定义网桥
- 必须是自定义网络中才可以通过容器名称进行访问
- 默认网络是没有这个功能的
- 所以要做容器之间的网络通信,就必须要自定义网络

- 命令
- docker network create
- 创建一个网络
- 创建一个网络会在宿主机上多出一个虚拟网卡,增加一个网段,默认是网桥的模式
- docker network ls
- 查看所有网络
- docker network rm
- 删除指定网络
- docker network prune
- 删除未使用的网络
- docker network connect
- 使指定容器链接加入网络
- docker network connect 网络名字 容器名字
- 容器加入网络后,会同时在两个网络中
- docker network disconnect
- 使指定容器链接断开某网络
- docker network inspect
- 查看网络详细信息
- docker network create
- docker run --network 网络名称
- 创建的容器直接在这个网络中
docker run -d --name nginx -p 80:80 --network test
项目的部署 「docker compose」
- docker-compose.yml
- version 可以设置 2.x 和 3.x 「这个是旧版了,version已经不需要设置了」
- version 现代docker compose不需要设置 「也就是 compose v2版本以上」
- docker compose 可以运行就是v2版本的compose,不需要设置version
- docker compose version 查看版本信息
- 模版

- docker run 和docker-compose.yml 语法之间的对比

entrypoint 定义容器启动时运行的主程序(可执行文件或脚本)。
command 作为参数传递给 entrypoint(相当于 ENTRYPOINT 的默认参数)。
services:
webapp:
image: nginx:alpine
entrypoint: ["/run.sh"]
command: ["arg1", "arg2", "arg3"]
执行命令为: /run.sh arg1 arg2 arg3
关键点
如果 entrypoint 是列表形式(如 "/docker-entrypoint.sh"):
Docker 会直接执行 /docker-entrypoint.sh,并附加 command 作为参数。 不会 通过 shell 解析(如 sh -c),所以环境变量替换等 shell 功能不会自动生效。如果 entrypoint 是字符串形式(如 "/docker-entrypoint.sh"):
Docker 会通过 /bin/sh -c 执行,支持 shell 功能(如变量替换 $VAR)。但推荐使用列表形式以避免 shell 解析的意外行为。
如果 entrypoint 未设置:
会使用镜像中定义的 ENTRYPOINT(来自 Dockerfile)。 command 会完全覆盖 Dockerfile 的 CMD。
- 容器启动执行的命令用参数 command:进行配置
services:
app.jar:
image: openjdk11:1.0
container_name: app.jar
volumes:
- "./app:/app"
command: java -jar /app/app.jar
networks:
- net
networks:
net:
external: true #使用已经创建的网络
限制容器使用资源
在 Docker 中,可以通过多种方式限制容器使用的资源(CPU、内存、磁盘 I/O 等)。以下是常用的资源限制方法:
- 内存限制
限制容器最大内存使用量:
docker run -it --memory="1g" --memory-swap="2g" ubuntu
--memory:容器可用的物理内存上限(例如1g表示 1GB)。--memory-swap:内存+交换分区的总限制(需 ≥--memory)。--memory-swappiness:控制交换分区的使用比例(0-100,0 表示禁用交换)。
防止容器耗尽宿主机内存:
docker run -it --memory="500m" --oom-kill-disable ubuntu
--oom-kill-disable:禁止 OOM Killer 终止容器进程(慎用)。
- CPU 限制** 限制容器使用的 CPU 核心数:
docker run -it --cpus="1.5" ubuntu
--cpus:限制容器最多使用 1.5 个 CPU 核心。
绑定到指定 CPU 核心:
docker run -it --cpuset-cpus="0,2" ubuntu
--cpuset-cpus:限制容器只运行在 CPU 0 和 2 上。
按权重分配 CPU 时间:
docker run -it --cpu-shares="512" ubuntu
--cpu-shares:默认值为 1024,权重越高分配的 CPU 时间越多(相对比例)。
- 磁盘 I/O 限制
限制磁盘读写带宽:
docker run -it \
--device-read-bps="/dev/sda:1mb" \
--device-write-bps="/dev/sda:1mb" \
--device-read-iops="/dev/sda:100" \
--device-write-iops="/dev/sda:100" \
ubuntu
--device-read-bps/--device-write-bps:限制每秒读写带宽(例如1mb)。--device-read-iops/--device-write-iops:限制每秒 IO 操作次数。
- 进程数限制(PID 限制)
docker run -it --pids-limit=100 ubuntu
--pids-limit:限制容器内最大进程数(防止 fork 炸弹)。
- 使用
docker-compose配置资源限制** 在docker-compose.yml中示例:
services:
app:
image: ubuntu
deploy:
resources:
limits:
cpus: "0.5"
memory: 500M
reservations:
memory: 200M
limits:硬性限制。reservations:预留资源(仅 Swarm 模式下有效)。
- 动态查看资源使用情况
docker stats [容器名]
实时监控容器的 CPU、内存、网络等资源占用。
- 注意事项
- 资源限制的优先级:部分参数(如
--memory)是硬限制,超出会导致容器被终止。 - Swarm/Kubernetes:在生产环境中,通常结合编排工具(如 Swarm/K8s)实现更精细的资源管理。
- 性能影响:过度限制可能导致容器性能下降,需根据实际需求调整。
- 建议: 不限制容器资源,而是通过监控报警的方式进行管理。
- 资源限制的优先级:部分参数(如
多容器


depends_on 依赖哪个容器
- 配置文件和镜像生成
#docker-compose.yml
services:
ruoyi-mysql:
container_name: ruoyi-mysql
#设置了image映像得到过程如下:
#1. 从本地查找镜像是否存在,存在直接使用
#2. 从中央仓库查找镜像是否存在,存在下载
#3. 中央仓库没有,配置文件中有build,则从build指定的配置文件中创建。
#4. 如果没有build则找不到映像。
#没有设置image映像的得到过程:
#1. 通过build指定的dockerfile配置文件,生成镜像。
# 镜像名称一般是项目名称「执行docker compose时候指定的」-服务名称。
#建议:
#1. 非必要不要自己通过dockerfile建立映像,尽量使用run的参数「或者compose配置文件」去生成。
#2. 如果一定要创建映像文件,则尽量把image的名字起的不重复防止中央仓库中有而下载。
# 更好的办法是不指定image的名字,而是up的时候现生成一个映像。
# image: mysql:5.7
build:
context: .
dockerfile: mysql-dockerfile
ports:
- "3306:3306"
volumes:
- ./mysql/conf:/etc/mysql/conf.d
- ./mysql/logs:/logs
- ./mysql/data:/var/lib/mysql
command: [
'mysqld',
'--innodb-buffer-pool-size=80M',
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_unicode_ci',
'--default-time-zone=+8:00',
'--lower-case-table-names=1'
]
environment:
MYSQL_DATABASE: 'ry-vue'
MYSQL_ROOT_PASSWORD: password
- links、external-links、network的关系
external_links 和 links 都是用于在 Docker 中建立容器之间的链接关系,但它们在使用方式和适用范围上有一些区别。
- 语法和使用方式:
links:links是 Docker Compose 中的字段,用于在同一 Compose 文件中定义容器之间的链接关系。它使用的语法是将容器名称指定为链接的目标,并可以为链接指定别名。例如:links: - container1:alias1。external_links:external_links是 Docker Compose 中的字段,用于在容器之间建立链接关系,但链接的目标容器不一定在同一 Compose 文件中定义。它使用的语法是将外部容器的名称指定为链接的目标,并可以为链接指定别名。例如:external_links: - container2:alias2。
- 适用范围:
links:links字段适用于同一 Docker Compose 文件中的容器之间的链接关系。它使得容器可以通过链接的别名来进行网络连接和服务访问。external_links:external_links字段适用于在不同 Docker Compose 文件、甚至不同项目中的容器之间建立链接关系。它使得容器可以通过链接的别名来访问在其他 Compose 文件或项目中定义的容器服务。
- 推荐使用:
links:在较新的 Docker Compose 版本中,links已经被弃用,不再推荐使用。取而代之的是使用自定义网络(networks)来定义容器之间的关联关系。external_links:虽然external_links仍然可用,但在较新的 Docker Compose 版本中,也推荐使用自定义网络(networks)来定义容器之间的链接关系,以提供更灵活和可控的网络连接方式。
总结来说,links 用于在同一 Compose 文件中定义容器之间的链接关系,而 external_links 用于在不同 Compose 文件或项目中的容器之间建立链接关系。然而,推荐使用自定义网络(networks)来取代 links 和 external_links,以提供更好的网络管理和连接方式。
docker compose 命令

#up 一键启动
#down 一键删除
docker compose up -d #-d后台运行,-d 一定要放在up的后面
sudo docker compose down #容器、网络会被删除,下砸的影像不会被删除
- docker compose 多服务器部署
- 可以做单服务器多实例的负载均衡
- Docker Compose 本身不支持跨多个服务器分布式部署。如果你想要在多个服务器上运行容器,你需要在每台服务器上分别运行Docker和Docker Compose,并在每台服务器上定义相同的服务。
但是,你可以使用Docker Swarm或Kubernetes这样的编排工具来在多个服务器上部署容器,并且可以通过编排工具来管理这些容器的分布式部署。
备份
- 使用以下命令备份所有正在运行的容器及其卷
- 备份前停止所有的容器 docker stop $(docker ps -aq)
docker ps -a -q | xargs -I {} docker export {} -o container_{}.tar docker volume ls -q | xargs -I {} docker run --rm -v {}:/data -v $(pwd):/backup ubuntu tar czf /backup/volume_{}.tar.gz /data- docker export 是 Docker 的一个命令,用于将容器的文件系统导出为一个 tar 归档文件,但不包含容器的元数据、日志或运行状态信息。它主要用于持久化容器的文件系统快照,适用于数据备份或迁移场景。
#基本用法 docker export [OPTIONS] CONTAINER > output.tar #或 docker export [OPTIONS] CONTAINER -o output.tar #CONTAINER:可以是容器名称或 ID。 #output.tar 或 -o output.tar:将导出的内容保存为 .tar 文件。
与 docker save 的区别命令 作用对象 输出内容 典型用途 docker export 容器 仅当前文件系统快照(单层) 备份或迁移容器数据 docker save 镜像 整个镜像(包括历史和层结构) 分发或存档镜像
与 docker commit 的区别命令 功能 docker commit 会将容器的变更保存为新镜像(保留元数据)。 docker export 仅生成一个无元数据的文件系统快照(不可直接运行)。 - 备份配置文件
#Linux 系统 sudo cp /etc/docker/daemon.json ~/docker_daemon_backup.json - 备份 Docker 数据目录
#通常位于 /var/lib/docker #可以使用 docker info 查看 sudo docker info |grep "Docker Root Dir" sudo tar czf docker_data_backup.tar.gz /var/lib/docker