Docker容器化部署实践


Docker容器化部署实践

Docker通过容器化技术,将应用及其所有依赖打包成一个标准化的可移植单元,彻底解决了"在我电脑上能运行"的环境一致性问题。本文将从Docker基础概念讲起,逐步深入到多容器编排、生产环境部署和性能优化,帮助你全面掌握Docker的实际应用。

一、Docker核心概念

理解Docker需要先掌握三个核心概念:

  • 镜像(Image):只读模板,包含运行应用所需的所有内容(代码、运行时、库、配置)
  • 容器(Container):镜像的运行实例,是一个隔离的进程
  • Dockerfile:构建镜像的蓝图,包含一系列指令

二、编写高效Dockerfile

PHP应用的Dockerfile示例

FROM php:8.2-fpm-alpine

# 安装系统依赖
RUN apk add --no-cache 
    libpng-dev 
    libzip-dev 
    icu-dev

# 安装PHP扩展
RUN docker-php-ext-install 
    pdo_mysql 
    gd 
    zip 
    intl 
    opcache

# 配置OPcache
RUN echo "opcache.enable=1" >> /usr/local/etc/php/conf.d/opcache.ini 
    && echo "opcache.memory_consumption=256" >> /usr/local/etc/php/conf.d/opcache.ini

# 复制应用代码
COPY . /var/www/html

# 设置权限
RUN chown -R www-data:www-data /var/www/html 
    && chmod -R 755 /var/www/html/storage

WORKDIR /var/www/html

EXPOSE 9000
CMD ["php-fpm"]

多阶段构建减小镜像体积

# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
RUN npm run build

# 运行阶段 - 只包含构建产物
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80

三、Docker Compose多服务编排

version: "3.8"
services:
  # PHP应用
  app:
    build: .
    container_name: myapp-php
    volumes:
      - ./:/var/www/html
      - ./php.ini:/usr/local/etc/php/php.ini
    depends_on:
      - mysql
      - redis
    networks:
      - app-network

  # Nginx
  nginx:
    image: nginx:alpine
    container_name: myapp-nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./:/var/www/html
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - app
    networks:
      - app-network

  # MySQL
  mysql:
    image: mysql:8.0
    container_name: myapp-mysql
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: myapp
    volumes:
      - mysql-data:/var/lib/mysql
      - ./my.cnf:/etc/mysql/conf.d/my.cnf
    ports:
      - "3306:3306"
    networks:
      - app-network

  # Redis
  redis:
    image: redis:7-alpine
    container_name: myapp-redis
    command: redis-server --requirepass redispassword --maxmemory 256mb
    volumes:
      - redis-data:/data
    ports:
      - "6379:6379"
    networks:
      - app-network

volumes:
  mysql-data:
  redis-data:

networks:
  app-network:
    driver: bridge

四、数据持久化

Docker容器是无状态的,删除容器后数据会丢失。数据持久化有三种方式:

# 1. Volume(推荐)
docker volume create mydata
docker run -v mydata:/data myimage

# 2. Bind Mount(开发环境)
docker run -v /host/path:/container/path myimage

# 3. tmpfs(临时数据,只存内存)
docker run --tmpfs /tmp myimage

五、网络配置

# 创建自定义网络
docker network create mynetwork

# 容器间通信(使用容器名作为主机名)
# 在app容器中可以用 mysql:3306 访问MySQL
docker run --network mynetwork --name app myimage
docker run --network mynetwork --name mysql mysql:8.0

# 端口映射
docker run -p 8080:80 nginx    # 宿主机8080->容器80
docker run -p 127.0.0.1:3306:3306 mysql  # 仅本机访问

六、生产环境最佳实践

  • 使用多阶段构建减小镜像体积
  • 不要在镜像中存储敏感信息,使用环境变量
  • 使用健康检查确保服务可用性
  • 设置合理的资源限制(CPU、内存)
  • 使用日志驱动收集容器日志
  • 定期更新基础镜像修复安全漏洞
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s 
    CMD curl -f http://localhost/ || exit 1

# 资源限制
docker run --memory=512m --cpus=1 myimage

# Docker Compose中的健康检查
services:
  app:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 30s
      timeout: 3s
      retries: 3

Docker已经彻底改变了软件的部署方式。掌握Docker不仅能提高开发和运维效率,还能为后续学习Kubernetes等容器编排工具打下坚实的基础。建议从Docker Compose开始实践,逐步过渡到更复杂的容器编排方案。


0.068545s