
如果你曾经遇到过这些情况:
Docker 基本就是为了解决这类问题而生的。
Docker 是一种基于 Linux 内核能力的开源容器化平台,核心依赖 namespaces、cgroups 等机制。
它可以把应用及其依赖一起打包进轻量级容器中,从而实现“一次构建,随处运行”。
容器不是完整虚拟机,而是共享宿主机内核的隔离进程环境,因此通常启动更快、占用资源更少。

常见组件如下:
| 对比项 | Docker(容器) | KVM(虚拟机) |
|---|---|---|
| 启动速度 | 通常更快 | 通常更慢 |
| 资源占用 | 较低,共享宿主机内核 | 较高,需要完整操作系统 |
| 性能 | 接近原生 | 有一定虚拟化开销 |
| 隔离性与安全 | 进程级隔离,隔离强度相对较弱 | 隔离更强 |
| 使用前提 | 依赖宿主机内核能力 | 依赖 CPU 虚拟化支持 |
总结:容器更适合敏捷开发、持续交付和微服务场景;虚拟机更适合需要更强隔离边界的场景。
Docker 最常见的使用路径其实很简单:
构建镜像 -> 启动容器 -> 暴露端口 -> 持久化数据 -> 查看日志 -> 推送仓库
下面的命令和案例,基本都围绕这条主线展开。
| 命令 | 作用 | 示例 |
|---|---|---|
image ls |
查看镜像列表 | docker image ls |
search |
搜索镜像 | docker search nginx |
pull |
拉取镜像 | docker pull redis:6 |
rmi |
删除镜像 | docker rmi imageID |
history |
查看镜像构建历史 | docker history nginx |
inspect |
查看镜像详细信息 | docker inspect imageID |
save |
保存镜像为 tar 包 | docker save -o redis.tar redis:6 |
load |
从 tar 包导入镜像 | docker load -i redis.tar |
tag |
给镜像打标签 | docker tag redis:6 myrepo/redis:v1 |
push |
推送镜像到仓库 | docker push myrepo/redis:v1 |
| 操作 | 命令示例 | 说明 |
|---|---|---|
| 启动容器 | docker run -it ubuntu /bin/bash |
交互式进入容器 |
| 后台运行 | docker run -d nginx |
容器后台运行 |
| 查看容器 | docker ps -a |
查看容器状态 |
| 停止容器 | docker stop containerID |
优雅停止 |
| 强制终止 | docker kill containerID |
类似 kill -9 |
| 删除容器 | docker rm containerID |
删除容器 |
| 批量删除 | docker rm $(docker ps -aq) |
删除所有容器,谨慎使用 |
| 进入容器 | docker exec -it containerID /bin/bash |
推荐使用 exec |
| 拷贝文件 | docker cp containerID:/path/in/container ./localdir |
容器和本地之间拷贝文件 |
Docker 常见网络模式:
| 网络模式 | 命令示例 | 特点 |
|---|---|---|
| bridge | --network bridge |
默认模式,容器通过虚拟网桥通信 |
| host | --network host |
直接使用宿主机网络,性能更高但隔离更弱 |
| container | --network container:containerID |
与指定容器共享网络命名空间 |
| none | --network none |
无网络,仅保留本地回环 |
生产环境更常用自定义
bridge网络或overlay网络。自定义bridge通常支持基于容器名的 DNS 解析,适合服务发现。
docker commit -m="add nginx" -a="user" containerID mynginx:v1
FROM node:22
ENV NODE_ENV=production
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
构建:
docker build -t myapp:v1 .
.dockerignore建议配合 .dockerignore 一起使用,避免把无关文件打进构建上下文:
node_modules/
dist/
*.log
.git/
.vscode/
.idea/
.env
如果想让镜像更小,可以使用多阶段构建:
# syntax=docker/dockerfile:1
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
Docker Compose 用于通过一个 compose.yml 文件定义和管理多容器应用。
通常推荐使用 Docker 自带的 Compose 插件,而不是旧版 pip install docker-compose。
| 命令 | 作用 |
|---|---|
docker compose up |
启动服务 |
docker compose down |
停止并删除容器、网络、卷 |
docker compose ps |
查看服务状态 |
docker compose logs -f svc |
查看服务日志 |
docker compose exec svc sh |
进入容器执行命令 |
docker compose up --scale web=3 |
启动多个副本 |
services:
nginx:
build:
context: ./nginx
dockerfile: Dockerfile
container_name: mynginx
ports:
- "8080:80"
- "8443:443"
volumes:
- ./wwwroot:/usr/share/nginx/html
networks:
ydq:
ipv4_address: 172.100.0.10
networks:
ydq:
driver: bridge
ipam:
config:
- subnet: 172.100.0.0/16
提醒:
container_name不适合需要横向扩容的服务,实际生产中通常让 Compose 自动命名更灵活。
容器默认是短生命周期的,容器删除后,写在容器内部可写层的数据也会丢失。生产里一般要把数据放到卷或宿主机目录。
volume 是 Docker 管理的数据卷,适合数据库、缓存等需要长期保存的数据。
docker volume create appdata
docker run -d --name mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-v appdata:/var/lib/mysql \
mysql:8
bind mount 直接把宿主机目录挂载进容器,适合开发调试和本地源码同步。
docker run -it --mount type=bind,src=.,target=/src ubuntu bash
容器内部监听的端口,默认不会直接暴露到宿主机。需要通过 -p 映射:
docker run -d -p 8080:80 nginx
这里的含义是:
8080 端口80 端口访问宿主机的 8080,就等于访问容器里的 80。
日常排障最常用的是这几条命令:
docker ps -a
docker logs -f containerID
docker inspect containerID
docker exec -it containerID sh
docker stats
它们分别用于查看容器状态、日志、详细配置、进入容器和实时资源占用。
容器可以通过参数限制资源,避免某个服务吃掉整台机器:
docker run -d \
--name demo \
--memory 512m \
--cpus 1.5 \
--restart unless-stopped \
nginx
常见重启策略:
no:默认,不重启always:退出后总是重启unless-stopped:除非手动停止,否则一直重启on-failure:异常退出时重启镜像构建完成后,通常会推送到仓库,方便团队协作和部署。
docker tag myapp:v1 myrepo/myapp:v1
docker push myrepo/myapp:v1
docker pull myrepo/myapp:v1
仓库可以是:
.dockerignore 减少无关文件进入构建上下文。alpine 或精简版镜像。Docker 用久了会积累镜像、容器、卷和网络,可以定期清理:
docker system df
docker system prune
docker image prune
docker volume prune
docker network prune
注意:
prune类命令会删除未使用资源,执行前要确认是否真的要清。
下面用一个最常见的 Node 服务,串起“构建、运行、映射端口、挂载数据”这条链路。
myapp/
├── src/
├── package.json
├── package-lock.json
├── Dockerfile
├── .dockerignore
└── compose.yml
# syntax=docker/dockerfile:1
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --omit=dev
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
node_modules/
dist/
*.log
.git/
.env
services:
app:
build: .
ports:
- "3000:3000"
environment:
NODE_ENV: production
restart: unless-stopped
docker compose up -d --build
docker compose ps
docker compose logs -f
这个例子的意义是:你不只是“会写命令”,而是真的知道一套最小可用的容器化流程长什么样。
通常是主进程结束了。Docker 容器的生命周期跟主进程绑定,主进程退出,容器就退出。
常见原因有:
常见原因有:
node_modules、缓存、日志打进去了因为改的是容器可写层,不是持久化存储。要用 volume 或 bind mount。
还没有公开评论
欢迎留下第一条想法,评论会在博主审核后显示。