Docker
→ 返回运维工具
容器化平台,将应用及其依赖打包为镜像,实现「一次构建,到处运行」。
核心概念
| 概念 | 说明 |
|---|---|
| 镜像(Image) | 只读模板,包含运行应用所需的一切 |
| 容器(Container) | 镜像的运行实例,相互隔离 |
| 仓库(Registry) | 存储和分发镜像,如 Docker Hub |
| Dockerfile | 构建镜像的声明式脚本 |
| 卷(Volume) | 持久化存储,容器重启后数据不丢失 |
| 网络(Network) | 容器间通信的虚拟网络层 |
docker run 详解
docker run 是最常用命令,完整语法:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]运行模式
docker run -d nginx # 后台(detached)模式
docker run -it ubuntu bash # 交互模式,分配伪终端
docker run --rm alpine echo "hello" # 容器退出后自动删除
docker run -d -it ubuntu # 后台运行但保持 stdin 打开命名与标识
docker run --name web nginx # 指定容器名称
docker run --hostname myhost nginx # 设置容器内主机名
docker run --label env=prod nginx # 添加标签端口映射(-p)
docker run -p 8080:80 nginx # 主机 8080 → 容器 80
docker run -p 127.0.0.1:8080:80 nginx # 仅绑定本地回环
docker run -p 8080:80/udp nginx # UDP 协议
docker run -P nginx # 随机映射所有 EXPOSE 端口环境变量(-e / —env-file)
docker run -e MYSQL_ROOT_PASSWORD=secret mysql
docker run -e APP_ENV=prod -e LOG_LEVEL=info myapp
docker run --env-file .env myapp # 从文件批量注入.env 文件格式(每行 KEY=VALUE,# 开头为注释):
MYSQL_ROOT_PASSWORD=secret
MYSQL_DATABASE=mydb
APP_PORT=8080数据卷挂载(-v / —mount)
# 绑定挂载(Bind Mount):挂载宿主机目录
docker run -v /host/data:/container/data nginx
docker run -v $(pwd)/logs:/app/logs myapp
# 具名卷(Named Volume):由 Docker 管理
docker run -v mydata:/var/lib/mysql mysql
# --mount 语法(更明确,推荐)
docker run --mount type=bind,source=/host/data,target=/data nginx
docker run --mount type=volume,source=mydata,target=/data nginx
docker run --mount type=tmpfs,target=/tmp nginx # 内存临时文件系统
# 只读挂载
docker run -v /host/config:/config:ro nginx网络配置(—network)
docker run --network bridge myapp # 默认 bridge 网络
docker run --network host myapp # 共享宿主机网络(Linux)
docker run --network none myapp # 完全隔离,无网络
docker run --network mynet myapp # 自定义网络
docker run --network mynet --network-alias db myapp # 添加 DNS 别名
# 端口和 DNS
docker run --add-host db:192.168.1.10 myapp # 添加 /etc/hosts 条目
docker run --dns 8.8.8.8 myapp # 指定 DNS重启策略(—restart)
docker run --restart no nginx # 不自动重启(默认)
docker run --restart always nginx # 总是重启(含宿主机重启)
docker run --restart unless-stopped nginx # 手动停止则不重启
docker run --restart on-failure nginx # 仅非零退出码时重启
docker run --restart on-failure:3 nginx # 最多重试 3 次资源限制
# 内存
docker run --memory 512m nginx # 最大内存 512MB
docker run --memory 512m --memory-swap 1g nginx # 含 swap 共 1GB
# CPU
docker run --cpus 1.5 nginx # 使用 1.5 个 CPU 核
docker run --cpu-shares 512 nginx # 相对权重(默认 1024)
docker run --cpuset-cpus "0,2" nginx # 绑定到指定 CPU 核
# 组合限制
docker run --memory 256m --cpus 0.5 myapp用户与权限
docker run --user 1000:1000 nginx # 指定 UID:GID
docker run --user nobody nginx # 非特权用户
docker run --privileged myapp # 完全特权(慎用)
docker run --cap-add NET_ADMIN myapp # 添加单个 Linux capability
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE myapp # 最小权限
docker run --read-only myapp # 只读文件系统覆盖入口点
docker run --entrypoint /bin/sh myapp # 覆盖 ENTRYPOINT
docker run --entrypoint "" myapp ls / # 清空 ENTRYPOINT,直接执行命令实用完整示例
# MySQL 生产环境
docker run -d \
--name mysql \
--restart unless-stopped \
-p 127.0.0.1:3306:3306 \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=mydb \
-v mysql_data:/var/lib/mysql \
--memory 1g --cpus 2 \
mysql:8.0
# Spring Boot 应用
docker run -d \
--name myapp \
--restart always \
-p 8080:8080 \
--env-file .env \
-v $(pwd)/logs:/app/logs \
--network app-net \
--memory 512m --cpus 1 \
myapp:1.0
# 一次性任务容器(执行完自动删除)
docker run --rm \
-v $(pwd):/workspace \
-w /workspace \
node:20-alpine \
npm install镜像管理
docker pull nginx:latest # 拉取镜像
docker pull nginx:1.25-alpine # 指定版本
docker images # 列出本地镜像
docker images --filter dangling=true # 列出悬空镜像(<none>)
docker rmi nginx:latest # 删除镜像
docker tag myapp:latest myapp:1.0 # 打标签
docker save myapp:1.0 | gzip > myapp.tar.gz # 导出镜像
docker load < myapp.tar.gz # 导入镜像
docker history myapp:1.0 # 查看镜像分层历史
docker inspect nginx # 查看镜像详细信息容器管理
docker ps # 查看运行中容器
docker ps -a # 查看所有容器
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
docker stop web # 优雅停止(SIGTERM)
docker kill web # 强制停止(SIGKILL)
docker start web # 启动已停止容器
docker restart web # 重启
docker pause / unpause web # 暂停/恢复
docker rm web # 删除已停止容器
docker rm -f web # 强制删除运行中容器
docker container prune # 删除所有已停止容器
docker logs web # 查看日志
docker logs -f web # 实时追踪日志
docker logs --tail 100 web # 最近 100 行
docker logs --since 30m web # 最近 30 分钟
docker exec -it web bash # 进入容器 shell
docker exec web cat /etc/nginx/nginx.conf # 非交互执行命令
docker cp web:/etc/nginx/nginx.conf ./ # 从容器复制文件
docker cp ./nginx.conf web:/etc/nginx/ # 复制文件到容器
docker stats # 实时资源使用
docker top web # 查看容器进程
docker inspect web # 查看容器详细信息网络管理
docker network ls # 列出网络
docker network create app-net # 创建自定义 bridge 网络
docker network create \
--driver overlay \
--subnet 10.0.0.0/24 \
my-overlay # Swarm overlay 网络
docker network inspect app-net # 查看网络详情
docker network connect app-net web # 将容器加入网络
docker network disconnect app-net web
docker network rm app-net卷管理
docker volume create mydata # 创建具名卷
docker volume ls # 列出卷
docker volume inspect mydata # 查看卷详情
docker volume rm mydata # 删除卷
docker volume prune # 删除所有未使用卷Dockerfile 最佳实践
# 多阶段构建(减小最终镜像体积)
FROM maven:3.9-openjdk-17 AS builder
WORKDIR /build
COPY pom.xml .
RUN mvn dependency:go-offline # 单独缓存依赖层
COPY src ./src
RUN mvn package -DskipTests
FROM openjdk:17-jre-slim
WORKDIR /app
# 非 root 用户运行(安全最佳实践)
RUN groupadd -r appgroup && useradd -r -g appgroup appuser
COPY --from=builder /build/target/app.jar app.jar
# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
CMD curl -f http://localhost:8080/actuator/health || exit 1
EXPOSE 8080
ENV JAVA_OPTS="-Xmx512m -Xms256m"
USER appuser
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]Dockerfile 指令对比
| 指令 | 说明 |
|---|---|
FROM | 基础镜像,多阶段构建可有多个 |
WORKDIR | 设置工作目录(自动创建) |
COPY | 复制文件(推荐,比 ADD 更透明) |
ADD | 支持 URL 和自动解压 tar |
RUN | 构建时执行,每条创建一个层 |
CMD | 默认命令,docker run 末尾参数可覆盖 |
ENTRYPOINT | 入口点,CMD 作为其参数 |
ENV | 设置环境变量(构建和运行时生效) |
ARG | 仅构建时变量,--build-arg 传入 |
EXPOSE | 声明监听端口(文档用途) |
VOLUME | 声明挂载点 |
USER | 切换执行用户 |
HEALTHCHECK | 容器健康检查 |
LABEL | 添加元数据 |
层缓存优化
# 好:依赖文件单独复制,代码变动不影响依赖缓存
COPY package*.json ./
RUN npm ci
COPY . .
# 差:任何文件变动都导致 npm install 重新执行
COPY . .
RUN npm install.dockerignore
node_modules
.git
*.log
.env
dist
Docker Compose
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
args:
BUILD_ENV: production
image: myapp:latest
container_name: myapp
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
env_file:
- .env
depends_on:
db:
condition: service_healthy # 等待 db 健康检查通过
volumes:
- ./logs:/app/logs
networks:
- app-net
restart: unless-stopped
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
db:
image: mysql:8.0
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: mydb
volumes:
- mysql_data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
networks:
- app-net
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- app
networks:
- app-net
restart: always
networks:
app-net:
driver: bridge
volumes:
mysql_data:
driver: localdocker compose up -d # 后台启动所有服务
docker compose up -d app # 仅启动指定服务
docker compose down # 停止并删除容器、网络
docker compose down -v # 同时删除具名卷
docker compose ps # 查看服务状态
docker compose logs -f app # 追踪指定服务日志
docker compose exec app bash # 进入服务容器
docker compose restart app # 重启指定服务
docker compose pull # 拉取最新镜像
docker compose build --no-cache # 重新构建镜像
docker compose config # 验证并查看合并后配置清理
docker system prune # 删除停止容器、无用镜像、网络
docker system prune -a # 同时删除未被使用的镜像
docker system prune --volumes # 同时删除未使用卷
docker system df # 查看 Docker 磁盘占用
docker image prune # 仅清理悬空镜像
docker container prune # 仅清理停止的容器
docker network prune # 仅清理未使用网络
docker volume prune # 仅清理未使用卷从0-1快速启动
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
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
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://myspecialaddress.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker相关文档
- Kubernetes — 容器编排
- Jenkins — CI/CD 构建推送镜像
- GitHub Actions — 自动构建推送镜像