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开始实践,逐步过渡到更复杂的容器编排方案。