1. Docker 入门指南:从零基础到实战部署
作为一名经历过无数次"环境配置地狱"的开发者,我深知Docker对于现代开发流程的重要性。还记得第一次接触Docker时,那种"一次构建,到处运行"的畅快感彻底改变了我对部署的认知。本文将带你从零开始掌握Docker核心概念,并通过Java和Node.js两个典型项目的实战部署,让你真正理解容器化技术的价值。
Docker本质上是一个轻量级的虚拟化解决方案,它通过容器技术将应用及其依赖打包成标准化单元。与传统的虚拟机相比,Docker容器共享主机操作系统内核,这使得它们更加轻量、启动更快(通常只需几秒)。对于Java和Node.js开发者来说,Docker能完美解决"在我机器上能跑"的经典问题,让开发、测试和生产环境保持高度一致。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Docker核心概念与安装配置
2.1 Docker基础架构解析
Docker采用客户端-服务器架构,主要包含三个核心组件:
- Docker Daemon:常驻后台的守护进程,负责管理镜像、容器、网络等核心对象
- Docker Client:命令行工具,通过REST API与Daemon交互
- Registry:镜像仓库(如Docker Hub),用于存储和分发镜像
容器与镜像的关系就像面向对象中的类和实例——镜像是静态的定义文件,而容器是镜像的运行实例。这种设计使得我们可以基于同一个镜像创建多个隔离的容器。
2.2 跨平台安装指南
在不同操作系统上安装Docker有细微差别:
Windows/macOS:
- 下载Docker Desktop安装包(注意:需要开启硬件虚拟化支持)
- 安装后通过系统托盘图标管理服务
- 在终端验证安装:
docker --version
提示:如果遇到"Virtualization support not detected"错误,需进入BIOS启用VT-x/AMD-v技术
Linux(以Ubuntu为例):
bash复制# 卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc
# 设置仓库
sudo apt-get update
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
# 添加Docker官方GPG密钥
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 设置稳定版仓库
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装Docker引擎
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 验证安装
sudo docker run hello-world
2.3 配置优化与权限管理
安装完成后,建议进行以下优化配置:
- 非root用户操作(Linux系统):
bash复制sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker # 立即生效
- 镜像加速(国内用户):
bash复制# 创建/修改daemon.json
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://<你的ID>.mirror.aliyuncs.com"]
}
EOF
# 重启服务
sudo systemctl daemon-reload
sudo systemctl restart docker
- 资源限制(防止单个容器占用过多资源):
bash复制docker run -it --cpus="1.5" --memory="2g" your-image
3. Docker核心操作实战
3.1 镜像管理深度解析
镜像是Docker的构建基石,理解其工作原理至关重要:
镜像分层存储机制:
- 每个Dockerfile指令都会创建一个新的层
- 层是只读的,多个镜像可以共享相同的层
- 写时复制(Copy-on-Write)机制确保高效存储
常用镜像操作:
bash复制# 搜索镜像
docker search nginx
# 拉取镜像(明确指定版本号是好习惯)
docker pull nginx:1.23-alpine
# 查看本地镜像
docker images
docker image ls
# 镜像导出导入
docker save -o nginx.tar nginx:1.23-alpine
docker load -i nginx.tar
# 删除镜像
docker rmi nginx:1.23-alpine
镜像构建最佳实践:
- 使用
.dockerignore文件排除无关文件 - 多阶段构建减小最终镜像体积
- 固定基础镜像版本,避免使用latest
- 合并RUN指令减少层数
- 按变更频率排序指令(把不常变的放在前面)
3.2 容器生命周期管理
容器是镜像的运行实例,掌握其完整生命周期是Docker的核心:
基本操作流程:
bash复制# 启动容器(-d后台运行,--name指定名称)
docker run -d --name my-nginx -p 8080:80 nginx:1.23-alpine
# 查看运行中的容器
docker ps
docker container ls
# 查看所有容器(包括已停止的)
docker ps -a
# 停止/启动容器
docker stop my-nginx
docker start my-nginx
# 进入容器shell
docker exec -it my-nginx sh
# 查看容器日志
docker logs -f my-nginx
# 删除容器
docker rm my-nginx
端口映射与网络配置:
bash复制# 随机映射主机端口
docker run -d -p 80 nginx
# 指定主机IP和端口
docker run -d -p 192.168.1.100:8080:80 nginx
# 创建自定义网络
docker network create my-network
docker run -d --network=my-network --name=my-nginx nginx
资源监控与限制:
bash复制# 查看容器资源使用情况
docker stats
# 限制CPU和内存
docker run -d --cpus="0.5" --memory="512m" nginx
# 限制重启策略
docker run -d --restart=on-failure:5 nginx
4. Dockerfile深度解析与最佳实践
4.1 Dockerfile指令全解
一个典型的Dockerfile包含以下核心指令:
dockerfile复制# 指定基础镜像(推荐使用alpine等轻量版本)
FROM openjdk:17-jdk-alpine
# 设置工作目录
WORKDIR /app
# 复制文件(注意.dockerignore配置)
COPY target/myapp.jar app.jar
COPY config/application.properties config/
# 设置环境变量
ENV JAVA_OPTS="-Xmx512m -Xms256m"
ENV PROFILE="prod"
# 暴露端口(只是文档作用,实际需用-p参数)
EXPOSE 8080
# 定义启动命令(推荐使用exec形式)
ENTRYPOINT ["java", "-jar", "app.jar"]
关键指令详解:
FROM:必须为第一条指令,推荐使用官方镜像COPY vs ADD:优先使用COPY,ADD有自动解压等额外功能RUN:每条RUN都会创建新层,建议合并相关命令CMD vs ENTRYPOINT:组合使用可实现灵活的参数传递
4.2 多阶段构建实战
多阶段构建能显著减小最终镜像体积:
dockerfile复制# 第一阶段:构建环境
FROM maven:3.8.6-amazoncorretto-17 AS builder
WORKDIR /build
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src/ ./src/
RUN mvn package
# 第二阶段:运行环境
FROM openjdk:17-jdk-alpine
WORKDIR /app
COPY --from=builder /build/target/myapp.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
这样最终的镜像只包含运行所需的JDK和JAR文件,去除了Maven等构建工具,镜像体积可减小70%以上。
4.3 安全加固指南
生产环境使用Docker需注意以下安全实践:
- 非root用户运行:
dockerfile复制FROM openjdk:17-jdk-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
WORKDIR /home/appuser
COPY --chown=appuser:appgroup app.jar .
ENTRYPOINT ["java", "-jar", "app.jar"]
- 镜像扫描:
bash复制docker scan my-image
- 签名验证:
bash复制docker trust sign my-image:1.0
- 最小权限原则:
- 避免使用
--privileged - 只挂载必要卷
- 限制内核能力
--cap-drop ALL --cap-add NET_BIND_SERVICE
5. Java项目容器化实战
5.1 Spring Boot应用部署
以典型的Spring Boot项目为例:
- 标准Dockerfile:
dockerfile复制# 构建阶段
FROM maven:3.8.6-amazoncorretto-17 AS build
WORKDIR /workspace
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src src
RUN mvn package -DskipTests
# 运行阶段
FROM openjdk:17-jdk-alpine
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
WORKDIR /app
COPY --from=build /workspace/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
- 构建与运行:
bash复制# 构建镜像
docker build -t my-spring-app .
# 运行容器
docker run -d -p 8080:8080 \
-e "SPRING_PROFILES_ACTIVE=prod" \
-v ./logs:/app/logs \
--name spring-app \
my-spring-app
5.2 生产级优化配置
JVM内存配置:
dockerfile复制ENTRYPOINT ["java", "-XX:+UseContainerSupport", \
"-XX:MaxRAMPercentage=75.0", \
"-XX:InitialRAMPercentage=50.0", \
"-XX:MaxGCPauseMillis=200", \
"-jar", "app.jar"]
健康检查配置:
dockerfile复制HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:8080/actuator/health || exit 1
日志收集方案:
bash复制docker run -d \
--log-driver=json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
my-spring-app
6. Node.js项目容器化实战
6.1 Express应用部署
Node.js项目的容器化有其特殊考量:
- 基础Dockerfile:
dockerfile复制# 开发阶段
FROM node:18-alpine AS development
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 生产阶段
FROM node:18-alpine AS production
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY --from=development /usr/src/app/dist ./dist
COPY --from=development /usr/src/app/public ./public
USER node
EXPOSE 3000
CMD ["node", "dist/main.js"]
- 多环境配置技巧:
dockerfile复制ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
- 构建与运行:
bash复制# 开发构建
docker build --target development -t my-node-app:dev .
# 生产构建
docker build -t my-node-app:prod .
# 运行开发容器(带热更新)
docker run -it -p 3000:3000 \
-v $(pwd):/usr/src/app \
-v /usr/src/app/node_modules \
my-node-app:dev
# 运行生产容器
docker run -d -p 3000:3000 \
--env-file .env.production \
my-node-app:prod
6.2 性能优化方案
Node.js特定优化:
- 使用
node:18-alpine基础镜像 - 生产环境去掉devDependencies
- 使用PM2进程管理:
dockerfile复制RUN npm install -g pm2
CMD ["pm2-runtime", "dist/main.js"]
多阶段构建优化:
dockerfile复制FROM node:18-alpine AS builder
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
RUN npm run build
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/package.json .
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/main.js"]
7. Docker Compose编排实战
7.1 多服务编排示例
典型的Java+MySQL+Redis项目编排:
yaml复制version: '3.8'
services:
app:
build: .
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- DB_URL=jdbc:mysql://db:3306/mydb
- REDIS_HOST=redis
depends_on:
- db
- redis
networks:
- backend
db:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=mydb
volumes:
- mysql_data:/var/lib/mysql
networks:
- backend
redis:
image: redis:7-alpine
ports:
- "6379:6379"
networks:
- backend
volumes:
mysql_data:
networks:
backend:
driver: bridge
7.2 生产级配置要点
资源限制与部署策略:
yaml复制services:
app:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
restart_policy:
condition: on-failure
max_attempts: 3
健康检查与依赖管理:
yaml复制healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
环境变量管理:
yaml复制env_file:
- .env.production
8. 常见问题排查与优化
8.1 典型错误解决方案
1. 端口冲突问题:
bash复制# 查看端口占用
netstat -tuln | grep 8080
# 或使用lsof
lsof -i :8080
# 解决方案:
# 1. 更改应用端口
# 2. 停止占用端口的进程
# 3. 使用不同主机端口映射
2. 存储空间不足:
bash复制# 查看Docker磁盘使用
docker system df
# 清理无用对象
docker system prune -a --volumes
3. 容器启动失败:
bash复制# 查看容器日志
docker logs -f container_name
# 以交互模式运行排查
docker run -it --entrypoint=/bin/sh your-image
8.2 性能调优指南
Java应用调优:
- 确保使用
-XX:+UseContainerSupport参数 - 合理设置堆内存比例:
bash复制-XX:InitialRAMPercentage=50.0
-XX:MaxRAMPercentage=75.0
Node.js应用调优:
- 使用
--max-old-space-size限制内存 - 集群模式提升性能:
bash复制npm install -g pm2
pm2-runtime start app.js -i max
数据库容器优化:
- 使用专用数据卷
- 调整内核参数:
bash复制sysctl -w vm.swappiness=0
8.3 监控与日志方案
基础监控命令:
bash复制# 实时监控容器状态
docker stats
# 查看容器详细信息
docker inspect container_name
# 查看容器进程
docker top container_name
日志管理策略:
bash复制# 查看日志
docker logs -f --tail=100 container_name
# 日志驱动配置
docker run --log-driver=json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
your-image
进阶监控方案:
- Prometheus + Grafana
- cAdvisor容器监控
- ELK日志收集系统
9. 进阶技巧与最佳实践
9.1 CI/CD集成方案
GitHub Actions示例:
yaml复制name: Build and Push Docker Image
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v3
with:
context: .
push: true
tags: your-username/your-image:latest
9.2 多架构构建支持
构建支持AMD64和ARM64的镜像:
bash复制docker buildx create --use
docker buildx build --platform linux/amd64,linux/arm64 -t your-image:multi-arch .
9.3 安全扫描与漏洞管理
bash复制# 使用Snyk扫描
docker scan your-image
# 使用Trivy扫描
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image your-image
9.4 本地开发优化技巧
开发模式热重载:
yaml复制services:
app:
build:
context: .
target: development
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=development
调试Java应用:
bash复制docker run -p 5005:5005 -e JAVA_TOOL_OPTIONS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005" your-image
快速进入容器:
bash复制# 创建别名方便使用
alias dc-exec='docker-compose exec'
alias d-ps='docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Ports}}"'
