# Docker 常用语法与命令:CLI、Dockerfile 与 Compose 速查

摘要:用开发环境场景整理 Docker CLI、Dockerfile、Buildx、Bind Mount、Compose、镜像迁移与磁盘清理的常用语法,重点解释参数改变了什么。

@[toc]

在这里插入图片描述

这一篇把前面频繁出现的 Docker 语法集中成开发机速查表,不穷举全部参数,只保留最常用对象和命令结构。

1. Docker CLI 先按“对象 + 动作”理解

现代 Docker CLI 很多命令可以读成:

1
docker <object> <command> [options]

例如:

1
2
3
4
5
6
docker image ls
docker image inspect arm64-dev:20.04
docker container ls
docker container rm demo
docker volume ls
docker network ls

同时 Docker 仍保留大量短写:

1
2
3
4
docker images
docker ps
docker rm
docker rmi

完整对象形式更容易建立 Image、Container、Volume、Network、Builder 的边界。

2. 一条 docker run 命令怎么拆

例如:

1
2
3
4
5
6
7
docker run --rm -it \
--name demo-shell \
-e MODE=debug \
--mount type=bind,src=/home/dev/project,dst=/workspace \
-w /workspace \
arm64-dev:20.04 \
cmake --build build --parallel 4

从左到右分成四段:

1
2
3
4
5
6
7
8
9
10
docker run

Docker runtime options
--rm -it --name -e --mount -w

Image
arm64-dev:20.04

Container 内执行的命令
cmake --build build --parallel 4

Image 名之后的 --build --parallel 4 已经属于 Container 内的 cmake,不是 Docker 参数。

3. docker run 最常用参数

--rm

1
docker run --rm image

主进程退出后自动删除这个 Container。

它不会删除 Image 或 bind mount 的 Host 文件,适合一次性开发 shell、编译和验证任务。

-i-t

通常写成:

1
-it

-i 保持标准输入打开,-t 分配伪终端。

进入 Bash 时通常两个都要:

1
docker run --rm -it ubuntu:24.04 bash

如果只是跑一个非交互命令:

1
docker run --rm image verify-env

就不一定需要 -it

--name

1
--name demo-dev

给 Container 一个明确名称,方便后续:

1
2
3
docker exec -it demo-dev bash
docker inspect demo-dev
docker rm -f demo-dev

-e / --env

1
2
-e HOST_UID=1000
-e MODE=debug

向 Container 注入环境变量。

也可以:

1
--env-file .env

但要注意不要把密码、token 等敏感信息随意写入版本库。

-w / --workdir

1
-w /workspace

设置 Container 主进程的工作目录,相当于启动程序前先 cd /workspace

--entrypoint

1
docker run --entrypoint /bin/sh image

它会覆盖 Image 原来的 ENTRYPOINT。假设原入口负责:

1
2
3
4
source SDK
→ 设置环境变量
→ 降权
→ 执行参数命令

你用 --entrypoint verify-env 后,这整条初始化链都被跳过。

如果只是想让原 ENTRYPOINT 最终执行一个验证命令,通常写:

1
docker run --rm image verify-env

更合适。

4. docker rundocker execdocker start 不一样

docker run

1
docker run image

创建新的 Container,并立即启动。

docker start

1
docker start old-container

启动一个已经存在、当前停止的 Container。

docker exec

1
docker exec -it running-container bash

在一个已经运行的 Container 里再启动一个新进程。

所以:

1
2
3
run   = create + start 新 Container
start = 启动旧 Container
exec = 在运行中的 Container 增加进程

排障时这三者不要混用。

5. Image 常用命令

列出:

1
docker image ls

查看某个 Image:

1
docker image inspect arm64-dev:20.04

只看 ENTRYPOINT/CMD:

1
2
docker image inspect arm64-dev:20.04 \
--format 'Entrypoint={{json .Config.Entrypoint}} Cmd={{json .Config.Cmd}}'

删除:

1
docker image rm arm64-dev:20.04

拉取:

1
docker pull ubuntu:24.04

注意 tag 不是不可变版本号。ubuntu:24.04 后续可能指向更新后的镜像内容;如果需要严格固定内容,可以进一步研究 digest pinning。

6. Container 常用命令

查看运行中的:

1
docker container ls

包含停止的:

1
docker container ls -a

停止:

1
docker stop demo

删除:

1
docker rm demo

强制删除仍在运行的 Container:

1
docker rm -f demo

能正常 stop 时优先正常停止,不要默认依赖 -f

查看日志:

1
docker logs demo

持续跟踪:

1
docker logs -f demo

Inspect:

1
docker inspect demo

挂载、环境变量或启动命令异常时,优先看 inspect

7. Bind mount:开发源码最常见

长语法:

1
2
3
docker run --rm -it \
--mount type=bind,src=/home/dev/project,dst=/workspace \
image

短语法:

1
2
3
docker run --rm -it \
-v /home/dev/project:/workspace \
image

工程脚本更推荐 --mount 或 Compose 长语法。

只读:

1
--mount type=bind,src=/home/dev/config,dst=/config,ro

Bind mount 的关键语义:

1
2
3
Container 看到的是 Host 真实文件
Container 默认可以修改它们
Container 删除不影响这些文件

因此源码、配置和需要 Host IDE/Git 同时访问的内容适合 bind mount。

8. Volume:Docker 管理的持久数据

创建:

1
docker volume create build-cache

使用:

1
2
3
docker run --rm \
--mount type=volume,src=build-cache,dst=/home/dev/.cache \
image

查看:

1
docker volume ls

删除:

1
docker volume rm build-cache

Volume 更适合数据库、编译缓存和由 Docker 管理的长期状态;需要 Host 与 Container 双方直接编辑的文件则优先 bind mount。

10. Dockerfile 最常见指令

一个基础开发镜像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
FROM ubuntu:20.04

ARG DEBIAN_FRONTEND=noninteractive

ENV DEV_MODE=1

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
git cmake make \
&& rm -rf /var/lib/apt/lists/*

COPY docker/entrypoint.sh /usr/local/bin/entrypoint

WORKDIR /workspace

ENTRYPOINT ["/usr/local/bin/entrypoint"]
CMD ["/bin/bash"]

FROM

1
FROM ubuntu:20.04

指定基础 Image。

RUN

1
RUN apt-get update && apt-get install -y git

镜像构建阶段执行命令,结果进入 Image layer。

不要和 Container 运行后的 shell 命令混淆。

COPY

1
COPY docker/entrypoint.sh /usr/local/bin/entrypoint

从 build context 把文件写进 Image。

日常源码如果使用 bind mount,就不需要 COPY 进开发 Image。

ARG

1
ARG DEBIAN_FRONTEND=noninteractive

主要用于 build time。

ENV

1
ENV SDK_ROOT=/opt/vendor-sdk

写入 Image 配置,后续 Container 默认能看到。

WORKDIR

1
WORKDIR /workspace

设置后续 Dockerfile 指令和默认 Container 工作目录。

ENTRYPOINTCMD

例如:

1
2
ENTRYPOINT ["/usr/local/bin/entrypoint"]
CMD ["/bin/bash"]

默认可以理解为:

1
/usr/local/bin/entrypoint /bin/bash

如果运行:

1
docker run image verify-env

通常变成:

1
/usr/local/bin/entrypoint verify-env

所以 ENTRYPOINT 适合固定初始化入口,CMD 适合提供默认命令/参数。

12. .dockerignore 怎么读

例如:

1
2
3
4
5
6
7
.git
logs
*.log
workspace/*
!workspace/.gitkeep
*.tar.gz
!assets/tool.tar.gz

常用规则:

1
2
pattern       排除匹配内容
!pattern 重新包含

.dockerignore 的目标是减少不必要的主 build context 输入,并避免日志、Git 数据、源码 workspace、归档包意外进入构建。

如果一个文件先被 *.tar.gz 排除,但确实是 Dockerfile 的必要资产,就可以再用 ! 精确包含。

13. docker buildx build 常用参数

典型:

1
2
3
4
5
6
docker buildx build \
--progress=plain \
--build-context sdk=/opt/vendor-sdk \
--load \
-t arm64-dev:20.04 \
.

重点参数:

参数 含义
--progress=plain 纯文本构建日志
--build-context name=path 增加额外构建输入
--load 把单平台结果导入本地 Docker Image store
-t 设置 repository:tag
. 当前目录作为主 build context

最后的 . 很重要。它不是“结束符”,而是 build context 路径。

Dockerfile 不在 context 根目录时,用 -f 指定文件位置。

14. BuildKit 的 RUN --mount

Dockerfile 中可能看到:

1
2
RUN --mount=type=bind,from=sdk,source=/,target=/mnt/sdk,ro \
cp -a /mnt/sdk/. /opt/vendor-sdk/

它是构建时临时 mount,生命周期只覆盖当前 RUN

还常见:

1
2
RUN --mount=type=cache,target=/root/.cache \
some-build-command

用于构建 cache。

不要把 Dockerfile RUN --mount 与:

1
docker run --mount ...

混为一谈。前者是 Image build 阶段,后者是 Container runtime 阶段。

15. Compose 最小结构

开发 Container 可以写:

1
2
3
4
5
6
7
8
9
10
11
12
13
services:
dev:
image: "${DEV_IMAGE:-arm64-dev:20.04}"
environment:
HOST_UID: "${HOST_UID:-1000}"
HOST_GID: "${HOST_GID:-1000}"
volumes:
- type: bind
source: "${WORKSPACE_DIR:-./workspace}"
target: /workspace
working_dir: /workspace
stdin_open: true
tty: true

Compose 的价值不是只用于“很多微服务”。一个单 Container 开发环境也可以用它把长 docker run 参数版本化。

常用检查:

1
docker compose config

它能展开变量并显示 Compose 最终解析后的配置。

16. docker compose runupexec 怎么区分

run

1
docker compose run --rm dev

为某个 Service 创建一个一次性 Container。

很适合开发 shell 或一次性 build。

up

1
docker compose up

按 Compose 描述启动整个应用/Service 集合,更适合长期服务。

后台:

1
docker compose up -d

exec

1
docker compose exec dev bash

在已经由 Compose 启动且正在运行的 Service Container 里执行新进程。

17. Image 导入导出:save/load

导出:

1
docker save -o arm64-dev.tar arm64-dev:20.04

导入:

1
docker load -i arm64-dev.tar

如果压缩:

1
gzip -1 arm64-dev.tar

迁移前建议生成校验:

1
sha256sum arm64-dev.tar.gz > arm64-dev.tar.gz.sha256

这里迁移的是 Image,不是 bind mount 的 Host 源码。开发镜像迁移通常优先 save/load,不要和 Container filesystem 的 export/import 混淆。

18. Docker 磁盘空间怎么看

Host 文件系统:

1
df -h /var/lib/docker

Docker 对象分类:

1
docker system df

Build cache:

1
docker builder prune

删除停止的 Container 等常见无用对象:

1
docker system prune

范围更大的:

1
docker system prune -a

需要谨慎,因为 -a 会把所有没有被 Container 使用的 Image 也纳入清理范围。

刚构建完的大开发 Image 即使 ACTIVE 0 也可能仍然重要。

所以清理前先:

1
2
docker image ls
docker system df

明确自己要删的是 cache、Container 还是 Image。

19. 常用排障命令组合

Docker 命令存在,但 Engine 是否正常

1
2
docker version
docker info

Image 是否存在

1
docker image ls arm64-dev:20.04

Image 默认入口是什么

1
2
docker image inspect arm64-dev:20.04 \
--format 'Entrypoint={{json .Config.Entrypoint}} Cmd={{json .Config.Cmd}}'

Container 实际挂载了什么

1
docker inspect demo

重点看 Mounts

Container 为什么已经退出

1
2
docker ps -a
docker logs demo

Compose 变量最终解析成什么

1
docker compose config

Docker 占了多少磁盘

1
docker system df

这些命令比“先删了重装”更适合做第一轮证据收集。

20. 四组最值得记住的模板

临时进入一个 Image

1
docker run --rm -it image bash

把 Host 源码挂到 Container

1
2
3
4
docker run --rm -it \
--mount type=bind,src=/host/project,dst=/workspace \
-w /workspace \
image

构建一个本地开发 Image

1
docker buildx build --load -t dev-image:tag .

用 Compose 进入一次性开发环境

1
docker compose run --rm dev

理解这四个模板后,其他命令主要是在此基础上增加参数。

参考资料