docker 笔记
操作
##拉取镜像
docker pull 镜像名:标签
##拉取所有标签
docker pull -a 镜像名
##指定平台
docker pull --platform linux/amd64 镜像名
##⽤摘要拉取
docker pull 镜像名@sha256:...
##列出所有镜像
docker images
##按仓库名过滤
docker images nginx
##列出虚悬镜像
docker images -f dangling=true
##只输出 ID
docker images -q
##显⽰摘要
docker images --digests
##⾃定义格式
docker images --format "..."
##查看空间占⽤
docker system df
##删除指定镜像
docker rmi 镜像名:标签
## 强制删除
docker rmi -f 镜像名
## 删除虚悬镜像
docker image prune
##删除未使⽤镜像
docker image prune -a
##批量删除
docker rmi $(docker images -q -f ...)
虚悬镜像
<none>:<none>
产生原因:后辈夺权,把名字和标签全抢走了(覆盖),原有镜像成了光杆司令
安全清理命令: docker image prune
如果要强制删除所有不再被使用的中间层,包括缓存,可以加 -a,但不推荐,因为会丢掉构建缓存,导致下次构建变慢
# 激进清理(慎用)
docker image prune -a
端口映射
## 将容器的 80 端⼝映射到宿主机的 8080 端⼝
$ docker run -d -p 8080:80 nginx:latest
## 随机映射端⼝
$ docker run -d -P nginx:latest
## 只绑定到 localhost
$ docker run -d -p 127.0.0.1:8080:80 nginx:latest
数据卷挂载
## 挂载命名卷
$ docker run -v mydata:/data nginx:latest
## 挂载宿主机⽬录
$ docker run -v /host/path:/container/path nginx:latest
## 只读挂载
$ docker run -v /host/path:/container/path:ro nginx:lates
环境变量
## 设置单个环境变量
$ docker run -e MYSQL_ROOT_PASSWORD=secret mysql
## 从文件加载环境变量
$ docker run --env-file .env myapp
资源限制
## 限制内存
$ docker run -m 512m nginx:latest
## 限制 CPU
$ docker run --cpus=1.5 nginx:latest
后台运行使用 -d(detach)参数
使用 --rm 自动删除,运行完成后自动删除
$ docker run --rm ubuntu:24.04 echo "Hello, World!"
后台配合⽇志查看
## 后台启动
$ docker run -d --name myapp myimage:v1.0.0
## 查看最近 100 ⾏⽇志
$ docker logs --tail 100 myapp
## 实时跟踪⽇志
$ docker logs -f myapp
## 查看带时间戳的⽇志
$ docker logs -t myapp
docker终止方式
docker stop / docker kill
Here document ,避免多行连接,增加可读性,需要docker 23 +
# syntax=docker/dockerfile:1
ENV环境变量设置
ENV <Key> <Value>
##单个变量
ENV node_version 20
##多个变量,带空格的变量需要用双引号包起来
ENV node_version = 20 \
app_name = "hello world"
以下指令可以使用 “
{变量名}”
RUN,CMD,ENTRYPOINT,COPY,ADD,WORKERDIR,EXPOSE,VOLUME,USER,LABEL,FROM
运行时覆盖使用 -e 或者--env
$ docker run -e APP_ENV=development -e DEBUG=true myimage
ARG参数仅构建时生效,覆盖参数 使用
--build-arg
VOLUME 指令创建挂载点,并标记为外部挂载的卷
EXPOSE 暴露端⼝
EXPOSE 声明容器运⾏时提供服务的端⼝。这是⼀个文档性质的声明,告诉使⽤者容器会监听哪些端口。
## 声明单个端⼝
EXPOSE 80
## 声明多个端⼝
EXPOSE 80 443
## 声明 TCP 和 UDP 端⼝
EXPOSE 80/tcp
EXPOSE 53/udp
WORKDIR 指定⼯作⽬录
WORKERDIR /app
USER 指定当前⽤户
使用非root用户执行后续指令,提高安全性和隔离性
USER <用户名>[:<用户组>]
HEALTHCHECK 健康检查
FROM nginx
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD curl -fs http://localhost/ || exit 1
ONBUILD 为他人作嫁衣裳
ONBUILD 是⼀个特殊的指令,它后⾯跟的是其它指令 (如 RUN,COPY 等),这些指令 在当前镜像构建
时不会执⾏,只有当以当前镜像为基础镜像去构建下⼀级镜像时才会被执⾏
LABEL 为镜像添加元数据
为什么需要 LABEL
版本管理:记录版本号、构建时间、Git Commit ID
联系信息:维护者邮箱、文档地址、支持渠道
⾃动化⼯具:CI/CD ⼯具可以读取标签触发操作
-
许可证信息:声明开源协议
LABEL maintainer="user@example.com" \ version="1.2.0" \ description="My App Description" \ org.opencontainers.image.authors="Yeasy"
SHELL 指令
为什么要⽤ SHELL 指令
-
使⽤ bash 特性
默认的 /bin/sh (通常是 dash 或 alpine 的 ash) 功能有限。如果你需要使⽤ bash 的特有功能 (如数
组、{} 扩展、pipefail 等),可以切换 shell。
FROM ubuntu:24.04
## 切换到 bash
SHELL ["/bin/bash", "-c"]
## 现在可以使⽤ bash 特性了
RUN echo {a..z}
-
增强错误处理
默认情况下,管道命令 cmd1 | cmd2 只要 cmd2 成功,整个指令就视为成功。这可能掩盖构建错误。
##这⾥的 wget 失败了,但构建继续(因为 tar 成功了)
RUN wget -O - https://invalid-url | tar xz
##使⽤ SHELL 启⽤ pipefail:
##Built with mdPress## 启⽤ pipefail
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
## 如果 wget 失败,整个 RUN 就会失败
RUN wget -O - https://invalid-url | tar xz