Docker 完整学习指南
·
Docker 完整学习指南
目录
Docker 基础概念
什么是 Docker?
Docker 是一个开源的容器化平台,它允许开发者将应用程序及其依赖项打包到一个轻量级、可移植的容器中。
核心概念
- 镜像 (Image): 只读的模板,用于创建容器
- 容器 (Container): 镜像的运行实例
- 仓库 (Repository): 存储镜像的地方
- Dockerfile: 构建镜像的脚本文件
- Docker Hub: Docker 官方的公共镜像仓库
Docker vs 虚拟机
| 特性 | Docker 容器 | 虚拟机 |
|---|---|---|
| 启动速度 | 秒级 | 分钟级 |
| 资源占用 | 少 | 多 |
| 隔离性 | 进程级 | 系统级 |
| 可移植性 | 高 | 中等 |
Docker 安装
Windows 安装
- 下载 Docker Desktop for Windows
- 启用 WSL 2 功能
- 安装并重启系统
- 验证安装:
docker --version
docker run hello-world
Linux 安装 (Ubuntu)
# 更新包索引
sudo apt-get update
# 安装必要的包
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
# 添加 Docker 官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 设置稳定版仓库
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装 Docker Engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# 启动 Docker 服务
sudo systemctl start docker
sudo systemctl enable docker
# 将用户添加到 docker 组
sudo usermod -aG docker $USER
macOS 安装
- 下载 Docker Desktop for Mac
- 拖拽到 Applications 文件夹
- 启动应用并完成设置
Docker 核心命令
镜像管理
# 搜索镜像
docker search nginx
# 拉取镜像
docker pull nginx:latest
# 查看本地镜像
docker images
# 删除镜像
docker rmi nginx:latest
# 构建镜像
docker build -t myapp:v1.0 .
# 给镜像打标签
docker tag myapp:v1.0 myapp:latest
容器管理
# 运行容器
docker run -d --name mynginx -p 80:80 nginx
# 查看运行中的容器
docker ps
# 查看所有容器
docker ps -a
# 停止容器
docker stop mynginx
# 启动容器
docker start mynginx
# 重启容器
docker restart mynginx
# 删除容器
docker rm mynginx
# 进入容器
docker exec -it mynginx /bin/bash
# 查看容器日志
docker logs mynginx
# 查看容器详细信息
docker inspect mynginx
数据管理
# 创建数据卷
docker volume create myvolume
# 查看数据卷
docker volume ls
# 挂载数据卷
docker run -d -v myvolume:/data nginx
# 绑定挂载
docker run -d -v /host/path:/container/path nginx
# 删除数据卷
docker volume rm myvolume
Dockerfile 详解
基本结构
# 基础镜像
FROM ubuntu:20.04
# 维护者信息
LABEL maintainer="your-email@example.com"
# 设置工作目录
WORKDIR /app
# 复制文件
COPY . /app
# 安装依赖
RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*
# 安装 Python 依赖
RUN pip3 install -r requirements.txt
# 暴露端口
EXPOSE 8000
# 设置环境变量
ENV PYTHONPATH=/app
# 启动命令
CMD ["python3", "app.py"]
常用指令详解
- FROM: 指定基础镜像
- RUN: 执行命令并创建新的镜像层
- CMD: 容器启动时执行的默认命令
- ENTRYPOINT: 容器启动时执行的入口点
- COPY: 复制文件到镜像中
- ADD: 复制文件到镜像中(支持 URL 和自动解压)
- WORKDIR: 设置工作目录
- EXPOSE: 声明端口
- ENV: 设置环境变量
- VOLUME: 创建挂载点
多阶段构建示例
# 构建阶段
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 生产阶段
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Docker Compose
什么是 Docker Compose?
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。
docker-compose.yml 示例
version: '3.8'
services:
web:
build: .
ports:
- "8000:8000"
volumes:
- .:/app
environment:
- DEBUG=1
depends_on:
- db
- redis
db:
image: postgres:13
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
redis:
image: redis:alpine
ports:
- "6379:6379"
volumes:
postgres_data:
Compose 常用命令
# 启动服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs
# 停止服务
docker-compose down
# 重新构建并启动
docker-compose up --build
# 扩展服务
docker-compose up --scale web=3
项目部署实战
1. Python Flask 应用部署
项目结构
flask-app/
├── app.py
├── requirements.txt
├── Dockerfile
└── docker-compose.yml
app.py
from flask import Flask, jsonify
import os
app = Flask(__name__)
@app.route('/')
def hello():
return jsonify({
'message': 'Hello from Docker!',
'environment': os.environ.get('ENV', 'development')
})
@app.route('/health')
def health():
return jsonify({'status': 'healthy'})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
requirements.txt
Flask==2.3.3
gunicorn==21.2.0
Dockerfile
FROM python:3.9-slim
WORKDIR /app
# 复制依赖文件
COPY requirements.txt .
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 创建非 root 用户
RUN useradd --create-home --shell /bin/bash app && chown -R app:app /app
USER app
# 暴露端口
EXPOSE 5000
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:5000/health || exit 1
# 启动命令
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "4", "app:app"]
docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "5000:5000"
environment:
- ENV=production
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
interval: 30s
timeout: 10s
retries: 3
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- web
restart: unless-stopped
2. Node.js 应用部署
package.json
{
"name": "node-docker-app",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
},
"dependencies": {
"express": "^4.18.2",
"cors": "^2.8.5"
}
}
server.js
const express = require('express');
const cors = require('cors');
const app = express();
const PORT = process.env.PORT || 3000;
app.use(cors());
app.use(express.json());
app.get('/', (req, res) => {
res.json({
message: 'Node.js app running in Docker!',
timestamp: new Date().toISOString()
});
});
app.get('/health', (req, res) => {
res.json({ status: 'OK' });
});
app.listen(PORT, '0.0.0.0', () => {
console.log(`Server running on port ${PORT}`);
});
Dockerfile
FROM node:18-alpine
WORKDIR /usr/src/app
# 复制 package 文件
COPY package*.json ./
# 安装依赖
RUN npm ci --only=production
# 复制应用代码
COPY . .
# 创建非 root 用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
USER nextjs
EXPOSE 3000
CMD ["npm", "start"]
3. 全栈应用部署 (React + Node.js + PostgreSQL)
docker-compose.yml
version: '3.8'
services:
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- REACT_APP_API_URL=http://localhost:5000
depends_on:
- backend
backend:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- "5000:5000"
environment:
- DATABASE_URL=postgresql://user:password@db:5432/myapp
- JWT_SECRET=your-secret-key
depends_on:
- db
volumes:
- ./backend:/app
- /app/node_modules
db:
image: postgres:15
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5432:5432"
redis:
image: redis:alpine
ports:
- "6379:6379"
command: redis-server --appendonly yes
volumes:
- redis_data:/data
volumes:
postgres_data:
redis_data:
4. 微服务架构部署
docker-compose.microservices.yml
version: '3.8'
services:
# API Gateway
gateway:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
depends_on:
- user-service
- product-service
- order-service
# 用户服务
user-service:
build: ./services/user-service
environment:
- DB_HOST=user-db
- REDIS_HOST=redis
depends_on:
- user-db
- redis
user-db:
image: postgres:15
environment:
POSTGRES_DB: users
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- user_data:/var/lib/postgresql/data
# 产品服务
product-service:
build: ./services/product-service
environment:
- DB_HOST=product-db
depends_on:
- product-db
product-db:
image: mongo:5
environment:
MONGO_INITDB_DATABASE: products
volumes:
- product_data:/data/db
# 订单服务
order-service:
build: ./services/order-service
environment:
- DB_HOST=order-db
- RABBITMQ_HOST=rabbitmq
depends_on:
- order-db
- rabbitmq
order-db:
image: postgres:15
environment:
POSTGRES_DB: orders
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- order_data:/var/lib/postgresql/data
# 消息队列
rabbitmq:
image: rabbitmq:3-management
ports:
- "15672:15672"
environment:
RABBITMQ_DEFAULT_USER: admin
RABBITMQ_DEFAULT_PASS: password
# 缓存
redis:
image: redis:alpine
volumes:
- redis_data:/data
volumes:
user_data:
product_data:
order_data:
redis_data:
最佳实践
1. Dockerfile 优化
使用多阶段构建
# 构建阶段
FROM node:16 AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
# 生产阶段
FROM node:16-alpine
WORKDIR /app
COPY --from=build /app/node_modules ./node_modules
COPY . .
CMD ["npm", "start"]
减少镜像层数
# 不好的做法
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y vim
# 好的做法
RUN apt-get update && \
apt-get install -y curl vim && \
rm -rf /var/lib/apt/lists/*
使用 .dockerignore
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.nyc_output
coverage
.nyc_output
2. 安全最佳实践
使用非 root 用户
FROM node:16-alpine
# 创建应用用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# 设置工作目录权限
WORKDIR /app
RUN chown nextjs:nodejs /app
# 切换到非 root 用户
USER nextjs
COPY --chown=nextjs:nodejs . .
扫描镜像漏洞
# 使用 Docker Scout
docker scout cves myapp:latest
# 使用 Trivy
trivy image myapp:latest
3. 性能优化
合理使用缓存
# 先复制依赖文件,利用 Docker 缓存
COPY package*.json ./
RUN npm ci --only=production
# 再复制应用代码
COPY . .
选择合适的基础镜像
# 开发环境
FROM node:16
# 生产环境
FROM node:16-alpine
# 最小化镜像
FROM scratch
4. 监控和日志
健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
日志管理
version: '3.8'
services:
app:
image: myapp
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
5. 环境管理
使用环境变量
# docker-compose.yml
version: '3.8'
services:
app:
image: myapp
environment:
- NODE_ENV=production
- DATABASE_URL=${DATABASE_URL}
env_file:
- .env
多环境配置
# 开发环境
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up
# 生产环境
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up
常见问题解决
1. 容器无法启动
检查日志
docker logs container_name
docker logs -f container_name # 实时查看
调试容器
# 进入容器调试
docker exec -it container_name /bin/bash
# 运行临时容器
docker run -it --rm image_name /bin/bash
2. 端口冲突
查看端口占用
# Linux/macOS
netstat -tulpn | grep :8080
# Windows
netstat -ano | findstr :8080
修改端口映射
docker run -p 8081:8080 myapp
3. 数据持久化问题
使用命名卷
docker volume create mydata
docker run -v mydata:/data myapp
绑定挂载
docker run -v /host/path:/container/path myapp
4. 网络连接问题
查看网络
docker network ls
docker network inspect bridge
创建自定义网络
docker network create mynetwork
docker run --network mynetwork myapp
5. 镜像构建失败
清理构建缓存
docker builder prune
docker system prune -a
查看构建过程
docker build --no-cache -t myapp .
docker build --progress=plain -t myapp .
6. 容器资源限制
设置内存限制
docker run -m 512m myapp
设置 CPU 限制
docker run --cpus="1.5" myapp
在 Compose 中设置
services:
app:
image: myapp
deploy:
resources:
limits:
memory: 512M
cpus: '0.5'
7. 清理 Docker 资源
清理未使用的资源
# 清理停止的容器
docker container prune
# 清理未使用的镜像
docker image prune
# 清理未使用的卷
docker volume prune
# 清理未使用的网络
docker network prune
# 清理所有未使用的资源
docker system prune -a
高级主题
1. Docker Swarm 集群
初始化 Swarm
docker swarm init --advertise-addr <MANAGER-IP>
部署服务
docker service create --name web --replicas 3 -p 80:80 nginx
2. 使用 Docker Registry
推送镜像到私有仓库
docker tag myapp:latest registry.example.com/myapp:latest
docker push registry.example.com/myapp:latest
3. CI/CD 集成
GitHub Actions 示例
name: Build and Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build Docker image
run: docker build -t myapp .
- name: Push to registry
run: |
echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
docker push myapp
总结
Docker 是现代应用部署的重要工具,掌握 Docker 可以大大简化应用的部署和管理。通过本指南,您应该能够:
- 理解 Docker 的核心概念
- 熟练使用 Docker 命令
- 编写高质量的 Dockerfile
- 使用 Docker Compose 管理多容器应用
- 部署各种类型的项目
- 遵循最佳实践
- 解决常见问题
继续实践和学习,您将能够在生产环境中有效地使用 Docker!
更多推荐

所有评论(0)