速查 13 · Docker
按问题索引。Ctrl+F 页内搜索。 系统学习见 01 · Docker 与容器化 与 02 · 部署与 CI/CD。 前端的"依赖地狱"是
node_modules,后端的依赖地狱是整台运行环境——Docker 把环境也打包了。
目录
镜像与容器常用命令
bash
# 镜像
docker images # 列出本地镜像
docker pull nginx:alpine # 拉镜像
docker build -t my-api . # 构建(-t 打 tag)
docker rmi my-api # 删镜像
# 容器
docker run -d --name api -p 8000:8000 my-api # 后台运行 + 端口映射
docker run --rm -it node:20 sh # 一次性进容器调试(--rm 退出即删)
docker ps # 运行中的容器
docker ps -a # 全部(含已退出)
docker stop api && docker start api # 停 / 起
docker rm api # 删容器
docker inspect api # 看配置详情(IP、挂载、环境变量)
# 端口映射规则:-p 宿主机:容器
docker run -p 8000:8000 my-api进容器 / 看日志 / 调试
bash
docker exec -it api sh # 进容器开 shell(镜像有 bash 就用 bash)
docker logs api # 看日志
docker logs -f --tail 100 api # 实时看最近 100 行
docker cp api:/app/log.txt ./ # 把容器内文件拷出来
docker top api # 看容器内进程
# 排查"容器起来了但连不上"
docker exec api curl http://localhost:8000/health # 容器内自测
docker inspect api | grep IPAddress # 看容器 IPDockerfile 常用指令
dockerfile
FROM python:3.12-slim # 基础镜像,越精简越好
WORKDIR /app # 工作目录(没有自动创建)
COPY requirements.txt . # 依赖先拷,利用层缓存
RUN pip install -r requirements.txt # 构建时执行
COPY . . # 代码后拷(这层一改就重建)
EXPOSE 8000 # 声明端口(只是文档,实际映射靠 -p)
ENV TZ=Asia/Shanghai # 环境变量
USER appuser # 非 root 运行(安全)
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] # 运行时命令
# 记忆口诀:RUN 是构建时,CMD 是运行时.dockerignore(类比 .gitignore,防止把 .git/node_modules 塞进镜像):
text
.git/
node_modules/
__pycache__/
*.pyc
.env
.venv/
dist/Python / Node 模板
dockerfile
# Python (FastAPI)
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]dockerfile
# Node(多阶段:构建期有工具链,运行期只要产物)
FROM node:20 AS build
WORKDIR /app
COPY package*.json .
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80镜像体积与构建缓存
bash
docker system df # 看空间占用
docker history my-api # 看每层体积
docker build --no-cache -t my-api . # 强制不缓存(排"改了没生效")
docker build --progress=plain . # 看完整构建日志
# 体积优化三板斧
# 1. 基础镜像用 slim/alpine/distroless
# 2. 多阶段构建(构建产物单独拷到运行镜像)
# 3. 依赖先 COPY + 代码后 COPY,最大化层缓存命中数据卷与网络
bash
# 数据卷:容器重建不丢数据
docker volume create pgdata
docker run -v pgdata:/var/lib/postgresql/data postgres:16
# 绑定挂载(开发热更新用,生产慎用)
docker run -v "$PWD":/app my-api
# 网络
docker network create mynet
docker run --network mynet --name api my-api
# 同网络内用容器名互访:http://api:8000(不是 localhost!)
# 端口
# -p 8000:8000 宿主机 8000 → 容器 8000
# -p 127.0.0.1:8000:8000 只允许本机访问(安全)Compose 编排
yaml
services:
api:
build: .
ports: ["8000:8000"]
environment:
DATABASE_URL: postgres://user:pass@db:5432/app
depends_on: [db]
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
retries: 3
db:
image: postgres:16
volumes: ["pgdata:/var/lib/postgresql/data"]
volumes:
pgdata:bash
docker compose up -d # 后台一键起整套
docker compose ps # 看服务状态
docker compose logs -f api # 看某个服务日志
docker compose exec api sh # 进某服务容器
docker compose down # 停掉(加 -v 连数据卷一起删,慎用)
docker compose build --no-cache api # 重建某个服务清理与资源
bash
docker container prune # 删所有停止的容器
docker image prune # 删悬空镜像
docker system prune -a # 大扫除(容器/镜像/网络/缓存),慎用
docker rm $(docker ps -aq) # 删全部容器
# 资源限制:不给限制,一个容器能吃光宿主机
docker run --memory=512m --cpus=1 my-api常见报错速查
| 报错 | 原因 / 解法 |
|---|---|
port is already allocated | 端口被占:换端口或 docker ps 找到占用容器 |
Cannot connect to the Docker daemon | Docker 没启动(Windows 需打开 Docker Desktop) |
No space left on device | 镜像/卷堆满:docker system prune -a |
Error response from daemon: conflict | 同名容器已存在:换 --name 或先删旧的 |
exit code 1 秒退 | 启动命令失败:docker logs 看原因(常是 CMD 拼错/缺依赖) |
容器内 localhost 连不上别的服务 | 容器网络隔离,用服务名/容器名互访 |
| 改了代码镜像没变化 | 层缓存:docker build --no-cache,并检查 .dockerignore |
permission denied 挂载失败 | Windows 共享盘符未授权,Docker Desktop 设置里勾选 |