1. 安装与基础配置
1.1 Ubuntu / Debian 安装 Docker CE
bash
# 安装依赖
sudo apt update
sudo apt install -y ca-certificates curl
# 添加 Docker 官方 GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# 添加仓库
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装 Docker 与 Compose 插件
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Debian 把上面仓库地址里的 ubuntu 换成 debian 即可;建议不要长期使用各大发行版旧仓库里的 docker.io。
1.2 CentOS / RHEL / Rocky / Alma 安装
bash
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
1.3 安装后必做检查
bash
docker version # 客户端与服务端版本
docker info # 引擎信息、存储驱动、镜像加速等
docker compose version # Compose 插件版本
docker run hello-world # 最小化验证
sudo usermod -aG docker $USER # 允许当前用户免 sudo 使用 docker,重新登录生效
1.4 镜像加速
编辑 /etc/docker/daemon.json:
json
{
"registry-mirrors": ["https://你的加速器地址.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
重启:
bash
sudo systemctl daemon-reload
sudo systemctl restart docker
docker info | grep -i mirror -A 3
云服务器内网访问 CR/ACR/其他镜像服务时,优先使用云厂商提供的内网域名;公开加速器可用性和稳定性经常变化,不要把业务构建强绑定到第三方加速器。
2. 镜像:pull、tag、push、save/load
| 目的 | 命令 |
|---|---|
| 拉取镜像 | docker pull nginx:1.27 |
| 查看本地镜像 | docker images / docker image ls |
| 查看完整 ID | docker images --no-trunc |
| 查看镜像详情 | docker inspect nginx:1.27 |
| 查看镜像历史 | docker history nginx:1.27 |
| 打标签 | docker tag nginx:1.27 registry.example.com/app/nginx:v1 |
| 推送私有仓库 | docker login registry.example.com 后 docker push registry.example.com/app/nginx:v1 |
| 导出镜像 | docker save -o nginx.tar nginx:1.27 |
| 导入镜像 | docker load -i nginx.tar |
| 删除镜像 | docker rmi nginx:1.27 |
| 强制删除 | docker rmi -f nginx:1.27 |
| 清理悬空镜像 | docker image prune |
| 清理未使用镜像 | docker image prune -a |
离线环境常见组合:
bash
docker save $(docker images --format '{{.Repository}}:{{.Tag}}') -o all-images.tar
# 或导出指定镜像
docker save -o app-v1.tar app:v1 busybox:1.36
3. 容器:运行、查看、进入、停止、删除
3.1 启动容器
bash
docker run -d --name nginx \
-p 8080:80 \
-v /etc/localtime:/etc/localtime:ro \
-v html:/usr/share/nginx/html \
--restart unless-stopped \
nginx:1.27
常用参数记忆法:
| 参数 | 含义 |
|---|---|
-d |
后台运行 |
--name |
指定容器名 |
-p 宿主机:容器 |
端口映射,如 -p 8080:80 |
-P |
随机映射 EXPOSE 端口 |
-v 宿主机路径:容器路径[:ro] |
绑定挂载;:ro 只读 |
-v 卷名:容器路径 |
使用命名卷 |
--mount |
更明确的挂载写法,推荐脚本/生产用 |
--restart unless-stopped |
除主动停止外自动拉起 |
--rm |
退出后自动删除,适合一次性任务 |
-it |
交互式终端,适合调试用 |
-e KEY=VALUE |
注入环境变量 |
--env-file .env |
从文件注入环境变量 |
--network |
指定网络 |
--memory 512m --cpus 1.0 |
限制资源 |
-u 1000:1000 |
指定运行用户 |
--privileged |
高危,尽量不用 |
示例:运行一次性命令并自动清理
bash
docker run --rm -it --entrypoint sh nginx:1.27 -c 'echo hello'
3.2 查看与排查
bash
docker ps # 运行中容器
docker ps -a # 全部容器
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
docker stats # 实时资源占用
docker logs nginx # 查看日志
docker logs -f --tail 200 nginx # 跟踪日志
docker logs --since 30m nginx
docker inspect nginx # 容器配置详情
docker port nginx # 查看端口映射
docker diff nginx # 查看容器文件系统改动
3.3 进入容器
优先用:
bash
docker exec -it nginx sh
如果镜像没有 shell,可用:
bash
docker exec -it nginx /bin/busybox sh
不建议日常依赖 docker attach:退出容易误杀前台进程;attach 更适合临时接管前台应用。
3.4 停止、启动、重启、删除
bash
docker stop nginx # 优雅停止,发 SIGTERM,超时再 SIGKILL
docker start nginx
docker restart nginx
docker kill nginx # 直接 SIGKILL,慎用
docker rm nginx
docker rm -f nginx # 运行中强制删除
docker container prune # 清理已停止容器
3.5 拷贝与导入导出容器
bash
docker cp nginx:/etc/nginx/nginx.conf ./nginx.conf
docker cp ./nginx.conf nginx:/etc/nginx/nginx.conf
docker export -o nginx-container.tar nginx # 导出容器文件系统
docker import nginx-container.tar nginx:imported # 导入为镜像
容器迁移更推荐"镜像层面"的
save/load或 registry 推送;export/import会丢失构建历史与元数据。
4. 数据卷
| 目的 | 命令 |
|---|---|
| 创建卷 | docker volume create pgdata |
| 列出卷 | docker volume ls |
| 查看详情 | docker volume inspect pgdata |
| 删除卷 | docker volume rm pgdata |
| 清理未使用卷 | docker volume prune |
常用挂载方式:
bash
docker run -d --name pg \
-e POSTGRES_PASSWORD=strong \
-v pgdata:/var/lib/postgresql/data \
postgres:16
注意:数据库类服务务必确认数据是否写入卷内;空卷挂载到非空容器目录时,容器目录内容会被复制到卷;反之已含数据的卷挂载到空容器目录时,容器会看到卷内容,需以 docker inspect Mounts 核实。
5. 网络
bash
docker network create app-net # 创建桥接网络
docker network ls # 查看网络
docker network inspect app-net # 查看网络详情
docker network connect app-net nginx # 容器加入网络
docker network disconnect app-net nginx # 容器离开网络
docker network rm app-net # 删除网络
docker network prune # 清理未使用网络
同一网络内用容器名直接访问:
bash
docker run -d --name app --network app-net -p 8080:8080 your/app:v1
docker run -d --name mysql --network app-net -e MYSQL_ROOT_PASSWORD=strong mysql:8.0
# 在 app 容器内访问:mysql:3306
查看容器 IP:
bash
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx
排错常用:
bash
docker exec -it app sh
ping app
wget -qO- http://app:8080/health
nslookup app
6. 构建镜像:Dockerfile、build、buildx
6.1 一个可写进博客的通用 Dockerfile
dockerfile
# syntax=docker/dockerfile:1
FROM eclipse-temurin:21-jre-jammy AS runtime
WORKDIR /app
ENV JAVA_OPTS="" TZ=Asia/Shanghai
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl tzdata ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY target/app.jar /app/app.jar
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=30s --retries=3 \
CMD curl -fsS http://127.0.0.1:8080/actuator/health || exit 1
USER 10001:10001
ENTRYPOINT ["sh","-c","java $JAVA_OPTS -jar /app/app.jar"]
构建:
bash
docker build -t registry.example.com/demo/app:v1 .
docker build --build-arg APP_ENV=prod -t demo/app:v1 .
docker build --no-cache -t demo/app:v1 . # 排障常用
6.2 构建与发布
bash
docker tag demo/app:v1 registry.example.com/demo/app:v1
docker login registry.example.com
docker push registry.example.com/demo/app:v1
多平台构建需要 buildx:
bash
docker buildx create --use
docker buildx build --platform linux/amd64,linux/arm64 \
-t registry.example.com/demo/app:v1 --push .
GitHub Actions 构建镜像时优先用
docker/build-push-action,本地多平台推送可用docker buildx bake管理。
6.3 Dockerfile 高频最佳实践
- 基础镜像固定小版本:
FROM nginx:1.27,不要裸latest上生产。 - 变更少的层放前面,依赖安装放在
COPY源码之前。 - 合并
RUN,及时清理包管理缓存,减少层体积。 - 不把 secret 写进
COPY的源码、构建参数或镜像历史;用 BuildKit secret 或运行时注入。 - 非 root 运行;
USER放在拷贝应用之后即可,但确保权限已修正。 - 显式
EXPOSE、定义HEALTHCHECK。 .dockerignore至少包含:.git、target、.idea、node_modules、日志和本地配置。- 用
docker history、dive或docker buildx du看镜像为什么变大。
7. Docker Compose:本地开发和测试环境
compose.yaml 示例:
yaml
name: demo
services:
app:
image: registry.example.com/demo/app:v1
build: .
ports:
- "8080:8080"
environment:
SPRING_PROFILES_ACTIVE: docker
DB_HOST: mysql
env_file:
- .env
depends_on:
mysql:
condition: service_healthy
networks:
- app-net
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8080/actuator/health"]
interval: 30s
timeout: 5s
retries: 3
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: demo
volumes:
- mysql-data:/var/lib/mysql
networks:
- app-net
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-p$${MYSQL_ROOT_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 10
networks:
app-net:
driver: bridge
volumes:
mysql-data:
常用命令:
bash
docker compose up -d # 创建并启动
docker compose up -d --build # 重新构建后启动
docker compose ps # 查看服务
docker compose logs -f app # 跟踪日志
docker compose exec app sh # 进入服务
docker compose restart app # 重启单个服务
docker compose stop app # 停止单个服务
docker compose rm -f app # 删除某个服务容器
docker compose pull # 更新使用镜像
docker compose up -d --force-recreate
docker compose down # 停并删除容器和网络,保留卷
docker compose down -v # 连卷一起删,危险
docker compose config # 校验并展开最终配置
docker compose config > rendered.yaml
8. 清理与空间治理
bash
docker system df # 看空间占用
docker system df -v # 逐项看
docker container prune # 清理停止容器
docker image prune # 清理悬空镜像
docker image prune -a # 清理未被容器使用的镜像,慎用在多项目机器
docker volume prune # 清理未使用卷,慎用于数据库卷
docker network prune # 清理未使用网络
docker builder prune # 清理 build cache
docker system prune # 温和清理
docker system prune -a --volumes # 核弹级,确认后再用
构建缓存很大时:
bash
docker buildx du
docker builder prune -a -f
9. 日常排错清单
| 现象 | 先查什么 |
|---|---|
| 容器起不来 | docker logs 容器、docker inspect 容器、docker events |
| 端口不通 | docker port 容器、宿主机 ss -lntup、容器内监听 curl/wget |
| 访问不到容器名 | 是否同一 network;docker network inspect |
| 权限不足 | docker info、当前用户是否在 docker 组、/var/run/docker.sock 权限 |
| 拉取镜像超时 | daemon 镜像加速、代理、仓库鉴权 docker login |
| 镜像突然变大 | .dockerignore 漏了、COPY . .、缓存层、多阶段构建失效 |
| 数据丢失 | 是否用了绑定挂载覆盖容器目录、卷名拼错、宿主机路径权限 |
| 日志撑爆磁盘 | daemon log-opts;容器 json-file 的 max-size/max-file |
| 构建失败但本地能跑 | BuildKit、构建上下文、构建参数、基础镜像架构不一致 |
辅助命令:
bash
docker events --filter container=nginx
docker inspect -f '{{json .Mounts}}' nginx | jq
docker top nginx