前言:Docker 是容器化技术的代名词,它让应用交付变得像集装箱运输一样标准化。不管开发环境、测试环境还是生产环境,一个镜像跑到底,再也不用说“在我机器上能跑啊”。本文从零开始,带你掌握 Docker 的核心概念、镜像管理、容器操作、Dockerfile 编写和 Compose 编排。
一、Docker 是什么?
1.1 一句话定位
Docker 是一个容器化平台,它将应用及其所有依赖打包成一个标准化的镜像,在任何安装了 Docker 的机器上都可以运行,保证环境一致性。
1.2 核心概念
| 概念 | 说明 | 类比 |
|---|---|---|
| 镜像(Image) | 只读的模板,包含应用和依赖环境 | 安装光盘 / 类 |
| 容器(Container) | 镜像的运行实例,可创建、启停、删除 | 运行中的程序 / 对象 |
| 仓库(Repository) | 存放镜像的地方(如 Docker Hub) | 应用商店 / Maven 仓库 |
| Dockerfile | 构建镜像的脚本 | 安装说明书 / Makefile |
二、安装 Docker
2.1 Linux(Ubuntu/Debian)
# 更新包索引 sudo apt update # 安装依赖 sudo apt install -y ca-certificates curl # 添加 Docker 官方 GPG 密钥 sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc # 添加 Docker 软件源 echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] 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 sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
2.2解决 sudo 权限问题(Linux)
每次执行docker都要加sudo,可以将当前用户加入 docker 组:
sudo usermod -aG docker $USER # 重新登录后生效
三、镜像操作(Image)
3.1 镜像仓库登录
# 登录 Docker Hub(公共仓库) docker login # 登录私有仓库 docker login registry.example.com
3.2 拉取镜像
# 从 Docker Hub 拉取镜像 docker pull nginx:latest docker pull redis:7.0 docker pull mysql:8.0 # 从私有仓库拉取 docker pull registry.example.com/myapp:v1.0
3.3 查看本地镜像
# 列出所有镜像 docker images docker image ls # 查看镜像详细信息 docker inspect nginx:latest
3.4 构建镜像
# 从 Dockerfile 构建镜像 docker build -t myapp:v1.0 . # 使用指定 Dockerfile docker build -f Dockerfile.prod -t myapp:prod .
3.5 标记镜像
# 给镜像打标签(用于推送到仓库) docker tag myapp:v1.0 registry.example.com/myapp:v1.0
3.6 推送镜像
# 推送到远程仓库 docker push registry.example.com/myapp:v1.0
3.7 删除镜像
# 删除指定镜像 docker rmi myapp:v1.0 docker image rm myapp:v1.0 # 删除所有未被使用的镜像 docker image prune docker image prune -a # 更激进
四、容器操作(Container)
4.1 创建并运行容器
# 最简单的运行 docker run nginx:latest # 后台运行(detach模式)-d docker run -d nginx:latest # 端口映射 -p(宿主机端口:容器端口) docker run -d -p 8080:80 nginx:latest # 挂载数据卷 -v(宿主机目录:容器目录) docker run -d -v /host/data:/app/data myapp:v1.0 # 设置环境变量 -e docker run -d -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0 # 设置容器名称 --name docker run -d --name web-server nginx:latest # 容器自动重启 --restart docker run -d --restart=always nginx:latest # 完整示例 docker run -d \ --name myapp \ -p 8080:80 \ -v /data/logs:/var/log/app \ -e APP_ENV=production \ --restart=always \ myapp:v1.0
4.2 查看容器
# 查看运行中的容器 docker ps # 查看所有容器(包括已停止的) docker ps -a # 查看容器详细信息 docker inspect myapp # 查看容器资源使用 docker stats myapp
4.3 启停容器
# 启动已存在的容器 docker start myapp # 停止容器 docker stop myapp # 强制停止(kill) docker kill myapp # 重启容器 docker restart myapp # 暂停/恢复容器进程 docker pause myapp docker unpause myapp
4.4 进入容器
# 使用 /bin/bash(大多数 Linux 镜像) docker exec -it myapp /bin/bash # 如果镜像没有 bash,用 /bin/sh docker exec -it myapp /bin/sh # 以 root 用户进入 docker exec -it -u root myapp /bin/bash
4.5 查看日志
# 查看容器日志 docker logs myapp # 实时跟踪日志(tail -f 模式) docker logs -f myapp # 查看最近 100 行 docker logs --tail 100 myapp # 带时间戳 docker logs -t myapp
4.6 文件拷贝
# 从容器拷贝文件到宿主机 docker cp myapp:/app/config.yml ./config.yml # 从宿主机拷贝文件到容器 docker cp ./config.yml myapp:/app/config.yml
4.7 删除容器
# 删除已停止的容器 docker rm myapp # 强制删除运行中的容器 docker rm -f myapp # 删除所有已停止的容器 docker container prune
五、Dockerfile 编写指南
5.1 基础语法
| 指令 | 说明 |
|---|---|
FROM | 指定基础镜像(必须) |
WORKDIR | 设置工作目录 |
COPY | 复制文件/目录到镜像 |
ADD | 功能类似 COPY,支持 URL 和自动解压 |
RUN | 构建时执行的命令 |
ENV | 设置环境变量 |
EXPOSE | 声明容器监听的端口 |
CMD | 容器启动时执行的命令(可被覆盖) |
ENTRYPOINT | 容器启动时执行的命令(不可被覆盖) |
5.2 Node.js 应用示例
# 1. 指定基础镜像 FROM node:18-alpine # 2. 设置工作目录 WORKDIR /app # 3. 复制依赖文件(分层构建,利用缓存) COPY package*.json ./ COPY yarn.lock ./ # 4. 安装依赖 RUN npm install --registry=https://registry.npmmirror.com # 5. 复制源代码(放在后面,避免依赖变更时重建) COPY . . # 6. 构建项目 RUN npm run build # 7. 声明端口 EXPOSE 3000 # 8. 启动命令 CMD ["node", "dist/index.js"]
5.3 Python 应用示例
FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple COPY . . EXPOSE 8000 CMD ["python", "app.py"]
六、Docker Compose 多容器编排
6.1 什么是 Docker Compose
Compose 用于定义和运行多个容器的应用,通过一个docker-compose.yml文件配置所有服务,一键启动。
6.2 安装
Docker Desktop 自带 Compose。Linux 需单独安装:
# 已随 docker-ce 安装 docker-compose-plugin,使用命令为 docker compose # 或单独安装 docker-compose(旧版) sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose
6.3 docker-compose.yml 示例(Web + Redis + MySQL)
version: '3.8' services: # Web 应用 web: build: . container_name: myapp-web ports: - "8080:3000" environment: - NODE_ENV=production - REDIS_HOST=redis - MYSQL_HOST=mysql depends_on: - redis - mysql restart: always volumes: - ./logs:/app/logs # Redis 缓存 redis: image: redis:7-alpine container_name: myapp-redis ports: - "6379:6379" restart: always volumes: - redis-data:/data # MySQL 数据库 mysql: image: mysql:8.0 container_name: myapp-mysql environment: - MYSQL_ROOT_PASSWORD=123456 - MYSQL_DATABASE=myapp - MYSQL_USER=appuser - MYSQL_PASSWORD=app123 ports: - "3306:3306" restart: always volumes: - mysql-data:/var/lib/mysql volumes: redis-data: mysql-data:
七、常用命令速查表
7.1 镜像命令
| 操作 | 命令 |
|---|---|
| 拉取镜像 | docker pull <镜像名>:<标签> |
| 列出镜像 | docker images |
| 构建镜像 | docker build -t <镜像名>:<标签> . |
| 删除镜像 | docker rmi <镜像名>:<标签> |
| 查看镜像详情 | docker inspect <镜像名>:<标签> |
| 标记镜像 | docker tag <原> <新> |
| 推送镜像 | docker push <镜像名>:<标签> |
7.2 容器命令
| 操作 | 命令 |
|---|---|
| 运行容器 | docker run -d --name <容器名> <镜像> |
| 列出运行中容器 | docker ps |
| 列出所有容器 | docker ps -a |
| 启动容器 | docker start <容器名> |
| 停止容器 | docker stop <容器名> |
| 重启容器 | docker restart <容器名> |
| 进入容器 | docker exec -it <容器名> /bin/bash |
| 查看日志 | docker logs -f <容器名> |
| 删除容器 | docker rm -f <容器名> |
| 查看资源占用 | docker stats |
| 查看容器详情 | docker inspect <容器名> |
八、实战场景
8.1 部署一个 Nginx 静态网站
# 1. 拉取 nginx 镜像 docker pull nginx:alpine # 2. 准备静态文件 mkdir -p ~/html echo "<h1>Hello Docker</h1>" > ~/html/index.html # 3. 运行容器 docker run -d \ --name my-nginx \ -p 8080:80 \ -v ~/html:/usr/share/nginx/html:ro \ nginx:alpine
8.2 启动一个 MySQL 数据库
docker run -d \ --name mysql-dev \ -e MYSQL_ROOT_PASSWORD=123456 \ -e MYSQL_DATABASE=dev \ -p 3306:3306 \ -v mysql-data:/var/lib/mysql \ mysql:8.0
8.3 清理所有停止的容器和未使用的镜像
# 清理停止的容器 docker container prune -f # 清理未使用的镜像 docker image prune -f # 清理所有未使用的资源(容器、镜像、网络、构建缓存) docker system prune -a -f
九、常见问题
Q1:端口被占用怎么办?
# 查看端口占用 netstat -tunlp | grep 8080 # 或修改映射端口 docker run -d -p 8081:80 nginx:latest
Q2:容器内无法联网?
# 检查 DNS 配置 docker run --dns 8.8.8.8 nginx:latest # 使用宿主机网络 docker run --network host nginx:latest
Q3:如何查看容器 IP?
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 容器名Q4:容器日志太大占满磁盘?
# 限制日志大小(在 docker run 时) docker run --log-opt max-size=10m --log-opt max-file=3 nginx:latest # 或在 /etc/docker/daemon.json 中全局配置 { "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }十、结语
Docker 的核心思想是Build once, run anywhere。掌握 Docker,你可以轻松解决环境不一致的问题,让应用交付变得标准、可重复、可追溯。
学习建议:
先在本机装好 Docker,把
docker run玩熟尝试给一个自己写的项目写 Dockerfile
用 Docker Compose 把 Web + DB + Cache 串起来
多看别人的 Dockerfile,模仿优化