Docker 是什么
把应用 + 依赖打包成"镜像"(image),在隔离的容器里跑——"在我电脑上能跑"问题的终结者。
装 Docker
Ubuntu:
# 官方一键脚本
curl -fsSL https://get.docker.com | sudo sh
# 让当前用户能直接跑 docker(不用 sudo)
sudo usermod -aG docker $USER
# 重新登录 SSH 让组生效
exit # 然后重新 ssh 进来
# 验证
docker run hello-world
核心概念
| 概念 | 一句话 |
|---|---|
| 镜像 image | 不可变的模板(类比类) |
| 容器 container | 镜像的运行实例(类比对象) |
| 仓库 registry | 存镜像的服务器(Docker Hub / 自建) |
| Dockerfile | 描述怎么建镜像的脚本 |
| 卷 volume | 容器外持久化数据 |
| 网络 network | 容器间通信 |
基础命令
# 拉镜像
docker pull nginx:alpine
# 跑容器
docker run -d --name web -p 80:80 nginx:alpine
# ↓ ↓ ↓ ↓
# 后台 命名 端口映射 镜像
# 看容器
docker ps # 跑着的
docker ps -a # 所有(含已停)
# 看日志
docker logs web
docker logs -f web # 实时跟踪
# 进容器
docker exec -it web sh
# 在容器里执行命令
docker exec web ls /usr/share/nginx/html
# 停止 / 删除
docker stop web
docker rm web
docker stop web && docker rm web # 一行搞定
# 看镜像
docker images
docker rmi nginx:alpine
跑一个有数据持久化的容器
# 1. 建命名卷
docker volume create pg-data
# 2. 跑 Postgres
docker run -d \
--name pg \
-p 5432:5432 \
-e POSTGRES_PASSWORD=secret \
-v pg-data:/var/lib/postgresql/data \
postgres:16
# 3. 进去
docker exec -it pg psql -U postgres
数据存在卷 pg-data 里——容器删了重建数据还在。
写 Dockerfile:把自己的应用打包
例 Node 应用 Dockerfile:
# 1. 基础镜像
FROM node:22-alpine
# 2. 工作目录
WORKDIR /app
# 3. 装依赖(先 copy package*.json 是为了利用缓存)
COPY package*.json ./
RUN npm ci --omit=dev
# 4. 拷代码
COPY . .
# 5. 暴露端口
EXPOSE 3000
# 6. 启动命令
CMD ["node", "server.js"]
构建 + 跑:
docker build -t myapp:1.0 .
docker run -d -p 3000:3000 --name myapp myapp:1.0
docker compose:多容器编排
docker-compose.yml:
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html:ro
restart: unless-stopped
depends_on:
- api
api:
build: ./api
environment:
- DATABASE_URL=postgresql://app:secret@db:5432/app
restart: unless-stopped
depends_on:
- db
db:
image: postgres:16-alpine
environment:
- POSTGRES_USER=app
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=app
volumes:
- pg-data:/var/lib/postgresql/data
restart: unless-stopped
volumes:
pg-data:
docker compose up -d # 起整栈
docker compose ps # 看状态
docker compose logs -f api # 看某服务日志
docker compose stop # 停
docker compose down # 停 + 删容器(卷保留)
docker compose down -v # 同时删卷(**数据没了**)
几个常用模式
网络互通
compose 自动建网络——服务之间用服务名互访:
api 容器里访问 `db:5432` = 连到 db 服务
不用 IP / 不用 localhost。
环境变量
.env 文件:
DB_PASSWORD=secret
API_KEY=abc123
docker-compose.yml 引用 ${DB_PASSWORD}。.env 加 .gitignore。
资源限制
services:
api:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
日志限制
services:
api:
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
防止日志无限增长把磁盘吃光。
镜像优化
多阶段构建(减小镜像)
# 阶段 1:构建
FROM node:22 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 阶段 2:运行(只复制必要文件)
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=builder /app/dist ./dist
USER node
CMD ["node", "dist/server.js"]
docker build -t myapp .
docker images | grep myapp
# 镜像比"一阶段构建"小一半以上
用小基础镜像
node:22≈ 1GBnode:22-alpine≈ 150MBgcr.io/distroless/nodejs22≈ 100MB(连 shell 都没有,更安全)
.dockerignore
和 .gitignore 类似——告诉 docker build 别复制哪些文件:
node_modules
.git
.env
*.log
安全提示
- 不要用 root 跑应用(Dockerfile 加
USER node) - 不要
:latesttag——锁版本(生产) - 扫镜像漏洞:
trivy image myapp:1.0 - 不要把 secret 写到镜像里——
docker history能看出来
接下来
学完 Docker 之后的几条路径:
- 生产部署 → 用 docker compose 起小型服务
- 多机协调 → 学 Kubernetes(ops-corp/09-13 系列)
- CI/CD → push 即自动 build + 部署(ops-quick/15-cicd-actions)
下一篇:整个 Linux 教程的总结。