适用人群:后端开发者、DevOps工程师
学习时长:约2-3天(每天3小时)
Docker版本:24.x+
重要程度:★★★★☆(强烈推荐学习)
一、Docker 是什么?
Docker 是一个开源的容器化平台,用于打包、分发和运行应用程序,解决"在我电脑上能跑"的问题。
| 概念 | 说明 | 类比 |
|---|---|---|
| 镜像(Image) | 只读的应用模板 | 安装光盘 |
| 容器(Container) | 运行中的应用实例 | 运行中的程序 |
| Dockerfile | 构建镜像的脚本 | 安装说明书 |
| Docker Compose | 多容器编排工具 | 多程序启动器 |
二、安装 Docker
# ====================
# macOS
# ====================
# 下载 Docker Desktop:https://www.docker.com/products/docker-desktop
# ====================
# Ubuntu
# ====================
sudo apt update
sudo apt install docker.io docker-compose-plugin
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER # 允许非root运行
# ====================
# CentOS
# ====================
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
sudo systemctl enable docker
# ====================
# 验证安装
# ====================
docker --version
docker-compose --version
docker run hello-world
三、基本操作
3.1 镜像操作
# 搜索镜像
docker search nginx
docker search mysql
# 拉取镜像
docker pull nginx:latest
docker pull mysql:8.0
docker pull python:3.12
docker pull node:20-alpine
# 查看本地镜像
docker images
# 删除镜像
docker rmi nginx:latest
docker image prune # 删除无用镜像
3.2 容器操作
# ====================
# 运行容器
# ====================
# 前台运行
docker run nginx
# 后台运行
docker run -d --name my-nginx nginx
# 端口映射
docker run -d -p 8080:80 --name web nginx
# 访问 http://localhost:8080
# 环境变量
docker run -d -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0
# 挂载目录
docker run -d -v $(pwd)/html:/usr/share/nginx/html nginx
# 交互式运行
docker run -it ubuntu:22.04 /bin/bash
# ====================
# 管理容器
# ====================
docker ps # 查看运行中的容器
docker ps -a # 查看所有容器(含停止的)
docker stop my-nginx # 停止容器
docker start my-nginx # 启动容器
docker restart my-nginx # 重启容器
docker logs my-nginx # 查看日志
docker logs -f my-nginx # 实时查看日志
docker exec -it my-nginx /bin/bash # 进入容器
docker exec my-nginx cat /etc/nginx/nginx.conf # 执行命令
docker rm my-nginx # 删除容器
docker rm -f my-nginx # 强制删除运行中的容器
docker container prune # 删除所有停止的容器
3.3 数据卷
# 创建数据卷
docker volume create mydata
# 查看数据卷
docker volume ls
# 使用数据卷
docker run -d -v mydata:/var/lib/mysql mysql:8.0
# 删除数据卷
docker volume rm mydata
docker volume prune # 删除无用数据卷
四、Dockerfile
4.1 基本语法
# 基础镜像
FROM python:3.12-slim
# 设置工作目录
WORKDIR /app
# 复制依赖文件
COPY requirements.txt .
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 5000
# 设置环境变量
ENV FLASK_APP=app.py
# 启动命令
CMD ["python", "app.py"]
4.2 各语言 Dockerfile 示例
Python Flask
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]
Node.js
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Go
# 构建阶段
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o server .
# 运行阶段
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/server .
EXPOSE 8080
CMD ["./server"]
PHP
FROM php:8.2-fpm-alpine
WORKDIR /var/www/html
COPY . .
RUN docker-php-ext-install pdo pdo_mysql
EXPOSE 9000
Java Spring Boot
FROM eclipse-temurin:17-jdk-alpine AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN apk add --no-cache maven && mvn clean package -DskipTests
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
五、Docker Compose
5.1 基本配置
# docker-compose.yml
version: '3.8'
services:
# Web应用
web:
build: .
ports:
- "8080:5000"
environment:
- DATABASE_URL=mysql://root:password@db:3306/mydb
depends_on:
- db
- redis
volumes:
- ./uploads:/app/uploads
restart: always
# MySQL数据库
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: mydb
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
restart: always
# Redis缓存
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
restart: always
# Nginx反向代理
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./ssl:/etc/nginx/ssl
depends_on:
- web
restart: always
volumes:
mysql_data:
redis_data:
5.2 常用命令
# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f web
# 停止所有服务
docker-compose down
# 重建并启动
docker-compose up -d --build
# 进入容器
docker-compose exec web bash
# 查看资源使用
docker-compose top
六、实际项目配置
6.1 PHP + MySQL + Nginx
version: '3.8'
services:
php:
build:
context: .
dockerfile: Dockerfile
volumes:
- ./www:/var/www/html
restart: always
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./www:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
restart: always
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: mydb
MYSQL_USER: app
MYSQL_PASSWORD: app123
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
restart: always
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- "8080:80"
environment:
PMA_HOST: mysql
depends_on:
- mysql
restart: always
volumes:
mysql_data:
6.2 Python + PostgreSQL + Redis
version: '3.8'
services:
app:
build: .
ports:
- "5000:5000"
environment:
- DATABASE_URL=postgresql://postgres:password@db:5432/mydb
- REDIS_URL=redis://redis:6379/0
depends_on:
- db
- redis
restart: always
db:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
volumes:
- pg_data:/var/lib/postgresql/data
restart: always
redis:
image: redis:7-alpine
restart: always
volumes:
pg_data:
七、宝塔面板 + Docker
# 宝塔面板安装Docker
# 软件商店 → Docker管理器 → 安装
# 宝塔中使用Docker
# 1. 镜像管理:拉取、删除镜像
# 2. 容器管理:创建、启动、停止容器
# 3. 编排管理:使用docker-compose.yml
# 部署示例
cd /www/wwwroot/myproject
docker-compose up -d
学习建议
- 先理解镜像和容器的关系,镜像是模板,容器是实例
- 掌握基本命令:run, ps, stop, rm, logs
- 学会写Dockerfile,这是部署的核心
- 学习Docker Compose,多服务编排必备
- 配合宝塔面板使用,生产环境部署更方便
常见问题
| 问题 | 解答 |
|---|---|
| Docker和虚拟机的区别? | Docker更轻量,共享宿主机内核,启动秒级 |
| 如何查看容器日志? | docker logs -f 容器名 |
| 如何进入容器? | docker exec -it 容器名 bash |
| 如何持久化数据? | 使用数据卷 -v volume_name:/path |
| 容器间如何通信? | 使用docker-compose的service名作为主机名 |