Docker 容器化部署实战——从环境搭建到生产应用的完整指南

Docker 已经成为现代运维的标配技术。它解决了"在我机器上能跑"的环境一致性问题,让应用部署变得轻量、快速、可复制。本文将从基础环境搭建开始,带你一步步掌握 Docker 容器化部署的核心技能。

一、Docker 安装与基础配置

1.1 CentOS 7/8 安装 Docker

# 安装依赖包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

# 设置 Docker 阿里云镜像源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 安装 Docker CE
sudo yum install -y docker-ce docker-ce-cli containerd.io

# 启动并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker

# 验证安装
docker --version

1.2 Ubuntu 安装 Docker

# 更新包索引
sudo apt-get update

# 安装依赖
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common

# 添加 GPG 密钥
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

# 添加软件源
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

# 安装 Docker CE
sudo apt-get update
sudo apt-get install -y docker-ce

# 启动并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker

1.3 配置镜像加速器(必做)

默认从 Docker Hub 拉取镜像很慢,配置国内加速器:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com"
  ]
}
EOF

# 重启 Docker 生效
sudo systemctl daemon-reload
sudo systemctl restart docker

验证配置:

docker info
# 看到 Registry Mirrors 有上面的地址就成功了

二、Docker 基础命令速查

2.1 镜像相关命令

# 搜索镜像
docker search nginx

# 拉取镜像(不写标签默认 latest)
docker pull nginx:1.25

# 查看本地镜像
docker images

# 删除镜像
docker rmi nginx:1.25

# 导出镜像到文件
docker save -o nginx.tar nginx:1.25

# 从文件导入镜像
docker load -i nginx.tar

2.2 容器相关命令

# 运行容器
docker run -d --name my-nginx -p 8080:80 nginx:1.25
# -d: 后台运行  --name: 容器名  -p: 端口映射 宿主端口:容器端口

# 查看运行中的容器
docker ps

# 查看所有容器(包括停止的)
docker ps -a

# 停止容器
docker stop my-nginx

# 启动停止的容器
docker start my-nginx

# 重启容器
docker restart my-nginx

# 删除容器(运行中的需要加 -f 强制删除)
docker rm -f my-nginx

# 查看容器日志
docker logs -f --tail 100 my-nginx
# -f: 实时查看  --tail N: 只看最后 N 行

# 进入容器内部
docker exec -it my-nginx /bin/bash
# -i: 交互模式  -t: 分配终端

# 从容器复制文件到宿主机
docker cp my-nginx:/etc/nginx/nginx.conf ./

# 从宿主机复制文件到容器
docker cp ./nginx.conf my-nginx:/etc/nginx/

三、Dockerfile 编写最佳实践

Dockerfile 是构建镜像的蓝图,写得好的 Dockerfile 能让镜像更小、构建更快、更安全。

3.1 基础 Nginx 镜像示例

# 使用官方 Alpine 基础镜像(体积小)
FROM nginx:1.25-alpine

# 维护者信息
LABEL maintainer="ops@example.com"

# 设置工作目录
WORKDIR /usr/share/nginx/html

# 复制静态文件(先复制依赖少的文件,利用缓存)
COPY index.html .
COPY css/ ./css/
COPY js/ ./js/

# 复制 Nginx 配置
COPY nginx.conf /etc/nginx/nginx.conf

# 暴露端口
EXPOSE 80

# 启动命令(CMD 可以被 docker run 后面的命令覆盖)
CMD ["nginx", "-g", "daemon off;"]

构建镜像:

docker build -t my-website:v1 .
# -t: 镜像名:标签  .: Dockerfile 所在目录

3.2 Node.js 应用镜像示例

# 第一阶段:构建阶段(只需要构建工具)
FROM node:18-alpine AS builder

WORKDIR /app

# 先复制 package.json,利用缓存
COPY package*.json ./
RUN npm install --production

# 再复制源代码
COPY . .

# 构建应用
RUN npm run build

# 第二阶段:运行阶段(只需要运行时,不需要构建工具)
FROM node:18-alpine

WORKDIR /app

# 从构建阶段复制构建产物
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package.json .

# 使用非 root 用户运行(安全)
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
USER nextjs

EXPOSE 3000

CMD ["npm", "start"]

这种多阶段构建的方式,最终镜像只包含运行时需要的文件,体积能小很多。

3.3 Dockerfile 优化技巧

  1. 选择 Alpine 基础镜像:比 Ubuntu/CentOS 小很多
  2. 合并 RUN 命令:减少镜像层数

    # ❌ 不好的写法
    RUN yum install -y gcc
    RUN yum install -y make
    RUN yum clean all
    
    # ✅ 好的写法
    RUN yum install -y gcc make && yum clean all
  3. 利用缓存:把变化少的命令放在前面,变化多的放在后面
  4. 删除构建缓存:安装完软件后清理包管理器缓存
  5. 使用 .dockerignore:排除不需要的文件

    node_modules
    npm-debug.log
    .git
    .DS_Store
    *.log

四、Docker Compose 多容器编排

实际项目通常需要多个容器配合(比如 Nginx + MySQL + Redis),Docker Compose 可以一键管理多个容器。

4.1 安装 Docker Compose

# 下载(版本号可以去 GitHub 查最新版)
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 加执行权限
sudo chmod +x /usr/local/bin/docker-compose

# 验证
docker-compose --version

4.2 WordPress 部署示例

创建 docker-compose.yml

version: '3.8'

services:
  # MySQL 数据库
  db:
    image: mysql:8.0
    container_name: wp-db
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root123456
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wpuser
      MYSQL_PASSWORD: wp123456
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/conf:/etc/mysql/conf.d
    networks:
      - wp-network

  # WordPress 应用
  wordpress:
    image: wordpress:6.3-php8.2-fpm-alpine
    container_name: wp-app
    restart: always
    depends_on:
      - db
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wpuser
      WORDPRESS_DB_PASSWORD: wp123456
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./wordpress/html:/var/www/html
    networks:
      - wp-network

  # Nginx 反向代理
  nginx:
    image: nginx:1.25-alpine
    container_name: wp-nginx
    restart: always
    depends_on:
      - wordpress
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf:/etc/nginx/conf.d
      - ./nginx/cert:/etc/nginx/cert
      - ./wordpress/html:/var/www/html
    networks:
      - wp-network

# 自定义网络
networks:
  wp-network:
    driver: bridge

# 数据卷(也可以用上面的绑定挂载方式)
# volumes:
#   mysql-data:

启动所有服务:

# 前台启动(看日志)
docker-compose up

# 后台启动
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f nginx

# 停止所有服务
docker-compose stop

# 停止并删除容器(数据卷不会删)
docker-compose down

五、生产环境注意事项

5.1 数据持久化

永远不要把数据存在容器内部! 容器删除后数据就没了。一定要用:

  • 绑定挂载(Bind Mount):把宿主机目录映射到容器
  • 数据卷(Volume):Docker 管理的存储,更好用

5.2 容器资源限制

防止某个容器吃光宿主机资源:

services:
  mysql:
    image: mysql:8.0
    deploy:
      resources:
        limits:
          cpus: '2.0'       # 最多用 2 核
          memory: 4G         # 最多用 4G 内存
        reservations:
          cpus: '0.5'       # 预留 0.5 核
          memory: 1G         # 预留 1G 内存

5.3 安全配置

  1. 不要用 root 用户运行容器:Dockerfile 里创建普通用户,用 USER 切换
  2. 不要映射特权端口到 0.0.0.0:除非真的需要公网访问
  3. 不要把敏感信息写在 Dockerfile 里:用环境变量或者 Secrets 管理
  4. 定期更新基础镜像:修复安全漏洞
  5. 不要在生产环境跑 --privileged 容器:除非你知道自己在做什么

5.4 日志管理

配置 Docker 日志轮转,防止日志文件把磁盘占满:

# /etc/docker/daemon.json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}

每个容器最多 3 个日志文件,每个 100M,超过自动轮转。

六、常用服务部署示例

6.1 Redis

redis:
  image: redis:7-alpine
  container_name: redis
  restart: always
  command: redis-server --requirepass yourpassword
  ports:
    - "6379:6379"
  volumes:
    - ./redis/data:/data

6.2 MySQL

mysql:
  image: mysql:8.0
  container_name: mysql
  restart: always
  environment:
    MYSQL_ROOT_PASSWORD: rootpassword
  ports:
    - "3306:3306"
  volumes:
    - ./mysql/data:/var/lib/mysql
    - ./mysql/conf:/etc/mysql/conf.d
  command:
    - --character-set-server=utf8mb4
    - --collation-server=utf8mb4_unicode_ci

总结

Docker 容器化是现代运维的基础技能:

  1. 先安装 Docker 并配置镜像加速器
  2. 掌握基础的镜像和容器命令
  3. 学会写优化的 Dockerfile(多阶段构建、小镜像、非 root 用户)
  4. 用 Docker Compose 管理多容器应用
  5. 生产环境注意数据持久化、资源限制、安全和日志

Docker 的核心价值是环境一致性,让你的应用"构建一次,到处运行"。