Docker 容器化实战指南
原创2024/1/22大约 4 分钟
Docker 容器化实战指南
Docker 彻底改变了应用部署方式,本文介绍 Docker 的核心概念和实战技巧。
Docker 核心概念
镜像 (Image)
镜像是容器的模板,包含应用运行所需的所有内容。
# 拉取镜像
docker pull nginx:latest
# 列出本地镜像
docker images
# 删除镜像
docker rmi nginx:latest
# 构建镜像
docker build -t myapp:1.0 .容器 (Container)
容器是镜像的运行实例。
# 运行容器
docker run -d -p 80:80 --name mynginx nginx
# 列出容器
docker ps # 运行中的容器
docker ps -a # 所有容器
# 停止/启动容器
docker stop mynginx
docker start mynginx
# 删除容器
docker rm mynginx
# 查看日志
docker logs mynginx
# 进入容器
docker exec -it mynginx bashDockerfile
基础示例
# Node.js 应用
FROM node:18-alpine
# 设置工作目录
WORKDIR /app
# 复制 package 文件
COPY package*.json ./
# 安装依赖
RUN npm ci --only=production
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 3000
# 启动命令
CMD ["node", "server.js"]多阶段构建
# 构建阶段
FROM node:18 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;"]最佳实践
# 使用特定版本标签
FROM node:18.17.0-alpine
# 合并 RUN 命令减少层数
RUN apt-get update && apt-get install -y \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
# 利用构建缓存
COPY package*.json ./
RUN npm install
COPY . .
# 使用非 root 用户
USER node
# 添加健康检查
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost/ || exit 1Docker Compose
基础配置
# docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgres://db:5432/myapp
depends_on:
- db
- redis
networks:
- app-network
volumes:
- ./uploads:/app/uploads
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- app-network
redis:
image: redis:7-alpine
networks:
- app-network
networks:
app-network:
driver: bridge
volumes:
postgres-data:常用命令
# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f web
# 停止服务
docker-compose stop
# 删除服务
docker-compose down
# 删除服务和数据卷
docker-compose down -v实战案例
Spring Boot 应用
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
# 复制 jar 文件
COPY target/*.jar app.jar
# 添加用户
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
# 暴露端口
EXPOSE 8080
# JVM 参数优化
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC"
# 启动应用
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/app
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=secret
depends_on:
- mysql
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 3s
retries: 3
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: app
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:React 前端应用
# 多阶段构建
FROM node:18 AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]# nginx.conf
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://backend:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}网络管理
# 创建网络
docker network create my-network
# 连接容器到网络
docker network connect my-network container_name
# 查看网络
docker network ls
# 查看网络详情
docker network inspect my-network数据卷管理
# 创建数据卷
docker volume create mydata
# 列出数据卷
docker volume ls
# 查看数据卷详情
docker volume inspect mydata
# 删除未使用的数据卷
docker volume prune
# 使用数据卷
docker run -v mydata:/data nginx性能优化
镜像优化
# 使用 alpine 基础镜像
FROM node:18-alpine
# 清理缓存
RUN npm ci --only=production && npm cache clean --force
# 使用 .dockerignore
# .dockerignore 文件内容:
# node_modules
# npm-debug.log
# .git
# .DS_Store
# 多阶段构建减小镜像大小资源限制
# 限制内存和 CPU
docker run -m 512m --cpus=1 myapp
# docker-compose.yml
services:
web:
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M监控和日志
# 查看容器资源使用
docker stats
# 查看容器日志
docker logs -f container_name
# 限制日志大小
docker run --log-opt max-size=10m --log-opt max-file=3 myapp最佳实践
- 使用特定版本标签: 避免使用
latest - 最小化镜像大小: 使用 alpine 镜像
- 利用构建缓存: 合理排序 Dockerfile 指令
- 使用 .dockerignore: 排除不需要的文件
- 健康检查: 添加 HEALTHCHECK 指令
- 日志管理: 配置日志驱动和大小限制
- 安全扫描: 定期扫描镜像漏洞
总结
Docker 简化了应用的构建、分发和运行,是现代应用开发的基础设施。掌握 Docker 是每个开发者的必备技能。