第11天:Docker容器化 - 微服务住进"集装箱",一次构建处处运行🐳
一、先白话白话Docker为啥牛X
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。
经典问题:"在我本地是好的!"
开发说:"我本地跑得好好的!" 测试说:"测试环境为啥报错?" 运维说:"生产环境又挂了!"
根本原因:
- 开发:Windows + JDK 11 + MySQL 8.0
- 测试:Linux + JDK 8 + MySQL 5.7
- 生产:Linux + JDK 17 + MySQL 8.0
环境不一致,问题百出!
Docker解决方案:"集装箱思维"
把应用+依赖+环境打包成一个集装箱(镜像)
- 开发:打好包
- 测试:直接运行
- 生产:直接运行
一次构建,处处运行!
二、Docker核心概念(5分钟搞懂)
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。
1. 镜像(Image)📦
- 模板:就像虚拟机镜像
- 只读:不能修改,只能基于它创建新镜像
- 分层存储:每层都可复用,节省空间
2. 容器(Container)🚢
- 运行实例:镜像运行起来就是容器
- 可写层:在镜像基础上加一层可写层
- 隔离环境:有自己的文件系统、网络、进程
3. 仓库(Registry)🏢
- 存放镜像的地方:Docker Hub、阿里云、私有仓库
- 类似Git:可以push/pull镜像
4. Dockerfile📝
- 构建脚本:告诉Docker怎么构建镜像
- 指令集:FROM、RUN、COPY、CMD等
5. Docker Compose🚀
- 多容器管理:一键启动所有服务
- 定义服务依赖:数据库、Redis、应用服务
三、先安装Docker(5分钟搞定)
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。
Windows/Mac:Docker Desktop
- 官网下载:www.docker.com/products/do…
- 一键安装,傻瓜式操作
- 启动后右下角看到🐳图标就OK
Linux:命令行安装
# 1. 卸载旧版本
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
# 2. 安装依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 3. 设置仓库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 4. 安装Docker
sudo yum install docker-ce docker-ce-cli containerd.io
# 5. 启动Docker
sudo systemctl start docker
sudo systemctl enable docker
# 6. 验证安装
docker --version
docker run hello-world
配置镜像加速(国内必须!)
// Docker Desktop:Settings -> Docker Engine
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
],
"insecure-registries": [],
"debug": true,
"experimental": false
}
四、把user-service做成镜像
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。
步骤1:准备项目结构
user-service/
├── src/
├── target/
│ └── user-service-0.0.1-SNAPSHOT.jar
├── Dockerfile # Docker构建文件
├── docker-entrypoint.sh # 启动脚本
└── docker-compose.yml # 多服务编排
步骤2:写Dockerfile(核心!)
# 第一阶段:构建
FROM maven:3.8.6-openjdk-17-slim AS builder
# 设置工作目录
WORKDIR /app
# 复制pom文件(利用缓存)
COPY pom.xml .
# 下载依赖(利用缓存,只要pom没变就不重复下载)
RUN mvn dependency:go-offline -B
# 复制源码
COPY src ./src
# 打包
RUN mvn clean package -DskipTests
# 第二阶段:运行
FROM openjdk:17-jdk-slim
# 时区设置(中文环境必须!)
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo 'Asia/Shanghai' > /etc/timezone
# 创建非root用户(安全!)
RUN groupadd -r spring && useradd -r -g spring spring
USER spring:spring
# 设置工作目录
WORKDIR /app
# 从构建阶段复制jar包
COPY --from=builder --chown=spring:spring /app/target/user-service-*.jar app.jar
# JVM参数优化
ENV JAVA_OPTS="-Xms512m -Xmx512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/app/heapdump.hprof"
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
CMD curl -f http://localhost:8080/actuator/health || exit 1
# 暴露端口
EXPOSE 8080
# 启动命令
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /app/app.jar"]
步骤3:写启动脚本(可选但推荐)
#!/bin/bash
# docker-entrypoint.sh
set -e
# 等待依赖服务(比如数据库)
wait_for_host() {
local host="$1"
local port="$2"
local max_attempts=30
local attempt=1
echo "等待 $host:$port 就绪..."
while ! nc -z "$host" "$port"; do
if [ $attempt -eq $max_attempts ]; then
echo "$host:$port 没有响应,退出"
exit 1
fi
echo "尝试 $attempt/$max_attempts: $host:$port 还未就绪,等待2秒..."
sleep 2
attempt=$((attempt + 1))
done
echo "$host:$port 已就绪"
}
# 等待MySQL
if [ -n "$DB_HOST" ] && [ -n "$DB_PORT" ]; then
wait_for_host "$DB_HOST" "$DB_PORT"
fi
# 等待Redis
if [ -n "$REDIS_HOST" ] && [ -n "$REDIS_PORT" ]; then
wait_for_host "$REDIS_HOST" "$REDIS_PORT"
fi
# 等待Nacos
if [ -n "$NACOS_HOST" ] && [ -n "$NACOS_PORT" ]; then
wait_for_host "$NACOS_HOST" "$NACOS_PORT"
fi
# 执行Java命令
exec java $JAVA_OPTS -jar /app/app.jar "$@"
步骤4:构建镜像
# 进入项目目录
cd user-service
# 构建镜像(注意最后有个点)
docker build -t user-service:1.0.0 .
# 查看镜像
docker images | grep user-service
# 输出:user-service 1.0.0 abc123def456 2分钟前 245MB
# 运行容器测试
docker run -d \
--name user-service \
-p 8081:8080 \
-e NACOS_HOST=host.docker.internal \
-e NACOS_PORT=8848 \
user-service:1.0.0
# 查看日志
docker logs -f user-service
# 查看容器状态
docker ps | grep user-service
五、Dockerfile高级技巧(镜像从1GB瘦身到100MB)
技巧1:多阶段构建(瘦身关键!)
# 第一阶段:构建(用完整JDK)
FROM maven:3.8.6-openjdk-17 AS builder
WORKDIR /app
COPY . .
RUN mvn clean package -DskipTests
# 第二阶段:运行(用最小JRE)
FROM openjdk:17-jre-slim # 比JDK小100MB!
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
# 进一步瘦身:用alpine版本
# FROM openjdk:17-jre-alpine # 再小50MB!
技巧2:分层优化(利用缓存)
# 错误的顺序(每次代码变更都重新下载依赖)
COPY . . # 这一行变了,下面所有缓存都失效
RUN mvn clean package
# 正确的顺序(利用缓存)
COPY pom.xml . # 依赖很少变,优先复制
RUN mvn dependency:go-offline -B # 下载依赖,这层被缓存
COPY src ./src # 代码经常变,最后复制
RUN mvn clean package -DskipTests # 这层经常变
技巧3:删除无用文件
# 清理Maven缓存
RUN mvn clean package -DskipTests && \
rm -rf /root/.m2 # 删除Maven缓存,节省200MB!
# 或者用专门的清理层
RUN --mount=type=cache,target=/root/.m2 \
mvn clean package -DskipTests
# 清理apt缓存(如果用了apt)
RUN apt-get update && \
apt-get install -y curl && \
rm -rf /var/lib/apt/lists/* # 清理包管理器缓存
技巧4:使用.dockerignore(重要!)
# .dockerignore文件
.git
.gitignore
README.md
*.log
target/
*.iml
.idea/
*.jar
*.war
*.tar.gz
.DS_Store
**/node_modules
**/.gradle
**/build
**/.settings
**/.classpath
**/.project
技巧5:最终极瘦身方案
# 使用distroless镜像(Google出品,极简)
FROM gcr.io/distroless/java17-debian11
# 或者用jlink制作自定义JRE
FROM openjdk:17 AS jlink
RUN jlink \
--add-modules java.base,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument \
--strip-debug \
--no-man-pages \
--no-header-files \
--compress=2 \
--output /jre-minimal
FROM debian:bullseye-slim
COPY --from=jlink /jre-minimal /opt/jre
ENV JAVA_HOME=/opt/jre
ENV PATH="$JAVA_HOME/bin:$PATH"
COPY --from=builder /app/target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
六、Docker Compose一键启动所有服务
docker-compose.yml
version: '3.8'
services:
# Nacos服务注册中心
nacos:
image: nacos/nacos-server:v2.1.0
container_name: nacos
environment:
- MODE=standalone # 单机模式
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=mysql
- MYSQL_SERVICE_PORT=3306
- MYSQL_SERVICE_USER=root
- MYSQL_SERVICE_PASSWORD=123456
- MYSQL_SERVICE_DB_NAME=nacos
ports:
- "8848:8848"
- "9848:9848"
depends_on:
mysql:
condition: service_healthy
networks:
- microservice-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8848/nacos"]
interval: 30s
timeout: 10s
retries: 3
# MySQL数据库
mysql:
image: mysql:8.0
container_name: mysql
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=nacos
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
- ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --default-authentication-plugin=mysql_native_password
networks:
- microservice-network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p123456"]
interval: 10s
timeout: 5s
retries: 3
# Redis缓存
redis:
image: redis:7-alpine
container_name: redis
ports:
- "6379:6379"
volumes:
- redis-data:/data
command: redis-server --appendonly yes --requirepass "redis123"
networks:
- microservice-network
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
# 用户服务
user-service:
build:
context: ./user-service
dockerfile: Dockerfile
args:
- APP_VERSION=1.0.0
container_name: user-service
environment:
- SPRING_PROFILES_ACTIVE=docker
- NACOS_SERVER_ADDR=nacos:8848
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- REDIS_HOST=redis
- REDIS_PORT=6379
ports:
- "8081:8080"
depends_on:
nacos:
condition: service_healthy
mysql:
condition: service_healthy
redis:
condition: service_healthy
networks:
- microservice-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
memory: 512M
reservations:
memory: 256M
restart: unless-stopped # 自动重启
# 订单服务
order-service:
build: ./order-service
container_name: order-service
environment:
- SPRING_PROFILES_ACTIVE=docker
- NACOS_SERVER_ADDR=nacos:8848
- USER_SERVICE_HOST=user-service
- USER_SERVICE_PORT=8080
ports:
- "8082:8080"
depends_on:
- nacos
- user-service
networks:
- microservice-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
# 商品服务
product-service:
build: ./product-service
container_name: product-service
environment:
- SPRING_PROFILES_ACTIVE=docker
- NACOS_SERVER_ADDR=nacos:8848
ports:
- "8083:8080"
depends_on:
- nacos
- mysql
networks:
- microservice-network
# API网关
api-gateway:
build: ./api-gateway
container_name: api-gateway
environment:
- SPRING_PROFILES_ACTIVE=docker
- NACOS_SERVER_ADDR=nacos:8848
ports:
- "9000:9000"
depends_on:
- nacos
- user-service
- order-service
- product-service
networks:
- microservice-network
# Spring Boot Admin监控
admin-server:
build: ./admin-server
container_name: admin-server
environment:
- SPRING_PROFILES_ACTIVE=docker
- NACOS_SERVER_ADDR=nacos:8848
ports:
- "8888:8888"
depends_on:
- nacos
networks:
- microservice-network
# Zipkin链路追踪
zipkin:
image: openzipkin/zipkin:latest
container_name: zipkin
ports:
- "9411:9411"
environment:
- STORAGE_TYPE=mem
networks:
- microservice-network
# 端口ainer管理工具
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
ports:
- "9001:9000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer-data:/data
networks:
- microservice-network
restart: unless-stopped
# 网络配置
networks:
microservice-network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
# 数据卷配置
volumes:
mysql-data:
redis-data:
portainer-data:
环境变量配置文件
# docker-compose.env
# 通用配置
SPRING_PROFILES_ACTIVE=docker
NACOS_SERVER_ADDR=nacos:8848
# 数据库配置
MYSQL_HOST=mysql
MYSQL_PORT=3306
MYSQL_DATABASE=user_db
MYSQL_USERNAME=root
MYSQL_PASSWORD=123456
# Redis配置
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=redis123
# 服务配置
USER_SERVICE_HOST=user-service
USER_SERVICE_PORT=8080
ORDER_SERVICE_HOST=order-service
ORDER_SERVICE_PORT=8080
PRODUCT_SERVICE_HOST=product-service
PRODUCT_SERVICE_PORT=8080
# JVM参数
JAVA_OPTS=-Xms512m -Xmx512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+HeapDumpOnOutOfMemoryError
启动命令
# 一键启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f user-service
# 查看所有日志
docker-compose logs -f
# 重启单个服务
docker-compose restart user-service
# 停止所有服务
docker-compose down
# 停止并删除数据卷
docker-compose down -v
# 重新构建镜像
docker-compose build --no-cache
# 水平扩展(启动3个user-service实例)
docker-compose up -d --scale user-service=3
七、生产环境最佳实践
1. 镜像安全扫描
# 使用Trivy扫描镜像漏洞
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image user-service:1.0.0
# 使用Docker Scout(Docker官方)
docker scout quickview user-service:1.0.0
# 扫描结果输出到HTML报告
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image \
--format template \
--template "@contrib/html.tpl" \
-o report.html \
user-service:1.0.0
2. 镜像签名和验证
# 启用Docker Content Trust
export DOCKER_CONTENT_TRUST=1
# 构建并推送签名镜像
docker build -t myregistry.com/user-service:1.0.0 .
docker push myregistry.com/user-service:1.0.0
# 拉取时验证签名
docker pull myregistry.com/user-service:1.0.0
3. 使用多阶段构建减少攻击面
# 生产环境Dockerfile
FROM --platform=$BUILDPLATFORM maven:3.8.6-eclipse-temurin-17 AS builder
WORKDIR /workspace
COPY . .
RUN mvn clean package -DskipTests -Pprod
FROM --platform=$TARGETPLATFORM eclipse-temurin:17-jre-alpine AS runtime
# 安全:使用非root用户
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
# 安全:创建不可变目录
RUN mkdir -p /app && chown spring:spring /app
WORKDIR /app
# 从构建阶段复制
COPY --from=builder --chown=spring:spring /workspace/target/*.jar app.jar
# 安全:设置只读文件系统
RUN chmod -R 555 /app && \
chmod 755 /app/app.jar
# 安全:设置资源限制
ENV JAVA_OPTS="-XX:MaxRAMPercentage=75.0 -XX:+UseContainerSupport"
# 安全:健康检查
HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["java", "-jar", "app.jar"]
4. 镜像仓库管理
# 推送到私有仓库
docker tag user-service:1.0.0 registry.mycompany.com/microservices/user-service:1.0.0
docker push registry.mycompany.com/microservices/user-service:1.0.0
# 拉取特定版本
docker pull registry.mycompany.com/microservices/user-service:1.0.0
# 查看仓库中的镜像
curl -u username:password https://registry.mycompany.com/v2/microservices/user-service/tags/list
# 删除旧镜像(保留最近5个版本)
docker images --filter "reference=registry.mycompany.com/microservices/user-service" --format "{{.Tag}}" | \
sort -V | \
head -n -5 | \
xargs -I {} docker rmi registry.mycompany.com/microservices/user-service:{}
5. 使用BuildKit加速构建
# 启用BuildKit
export DOCKER_BUILDKIT=1
# 使用缓存镜像
docker build \
--cache-from registry.mycompany.com/microservices/user-service:latest \
-t registry.mycompany.com/microservices/user-service:1.0.0 \
-t registry.mycompany.com/microservices/user-service:latest \
.
# 并行构建多阶段
docker build \
--build-arg BUILDKIT_INLINE_CACHE=1 \
--cache-from registry.mycompany.com/microservices/user-service:latest \
-t user-service:1.0.0 \
.
八、Docker监控和调试
1. 容器监控
# 查看容器资源使用
docker stats
# 查看容器详情
docker inspect user-service
# 查看容器日志
docker logs -f --tail 100 user-service
# 查看容器进程
docker top user-service
# 查看容器资源限制
docker container inspect user-service --format='{{.HostConfig.Memory}}'
# 性能分析
docker run --rm -it --pid=container:user-service --net=container:user-service --cap-add sys_ptrace alpine sh
# 在容器内执行:top, ps, netstat等
2. 进入容器调试
# 进入容器shell
docker exec -it user-service sh
# 在容器内查看Java进程
ps aux | grep java
# 查看Java堆内存
jmap -heap 1
# 生成堆转储
jmap -dump:live,format=b,file=/app/heapdump.hprof 1
# 查看GC情况
jstat -gc 1 1000 10
# 线程转储
jstack 1 > /app/threaddump.txt
# 退出容器
exit
3. 容器网络调试
# 查看容器网络
docker network ls
docker network inspect microservice-network
# 容器间网络测试
docker exec user-service ping order-service
docker exec user-service curl http://order-service:8080/actuator/health
# 查看端口映射
docker port user-service
# 查看容器IP
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' user-service
4. 使用Docker Compose调试
# 查看服务依赖图
docker-compose config --services
# 验证配置文件
docker-compose config
# 调试模式运行
docker-compose up --build --force-recreate --abort-on-container-exit
# 查看服务日志
docker-compose logs --tail=100 -f user-service order-service
# 执行命令
docker-compose exec user-service sh
docker-compose exec mysql mysql -uroot -p123456
# 查看资源使用
docker-compose top
九、常见问题解决方案
1. 镜像构建慢
# 使用国内镜像源
# 创建或修改~/.docker/daemon.json
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com"
]
}
# 使用构建缓存
docker build --cache-from user-service:latest -t user-service:1.0.0 .
# 使用多阶段构建,减少层数
2. 容器启动报错
# 查看详细错误
docker logs user-service --details
# 调试模式启动
docker run -it --rm user-service:1.0.0 sh
# 在容器内手动启动
java -jar app.jar
# 检查环境变量
docker exec user-service env
# 检查端口冲突
netstat -tulpn | grep 8081
3. 容器内存泄漏
# 限制容器内存
docker run -d --name user-service --memory=512m --memory-swap=1g user-service:1.0.0
# 监控内存使用
docker stats user-service
# 进入容器分析
docker exec -it user-service sh
jmap -histo:live 1 | head -20
4. 容器网络问题
# 检查网络连通性
docker exec user-service curl -v http://order-service:8080
# 查看DNS解析
docker exec user-service cat /etc/resolv.conf
docker exec user-service nslookup order-service
# 创建自定义网络
docker network create --driver=bridge --subnet=172.25.0.0/16 microservice-net
docker run --network=microservice-net user-service:1.0.0
5. 数据持久化问题
# 使用数据卷
docker volume create mysql-data
docker run -d --name mysql -v mysql-data:/var/lib/mysql mysql:8.0
# 查看数据卷
docker volume inspect mysql-data
# 备份数据卷
docker run --rm -v mysql-data:/source -v $(pwd):/backup alpine tar czf /backup/mysql-backup.tar.gz -C /source .
# 恢复数据卷
docker run --rm -v mysql-data:/target -v $(pwd):/backup alpine tar xzf /backup/mysql-backup.tar.gz -C /target
十、Docker在CI/CD中的使用
GitHub Actions示例
# .github/workflows/docker-build.yml
name: Docker Build and Push
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v4
with:
images: myorg/user-service
tags: |
type=ref,event=branch
type=sha,prefix={{branch}}-
type=semver,pattern={{version}}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: ./user-service
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=myorg/user-service:latest
cache-to: type=inline
Jenkins Pipeline示例
// Jenkinsfile
pipeline {
agent any
environment {
DOCKER_REGISTRY = 'registry.mycompany.com'
IMAGE_NAME = 'microservices/user-service'
}
stages {
stage('Build') {
steps {
script {
docker.build("${IMAGE_NAME}:${env.BUILD_ID}")
}
}
}
stage('Test') {
steps {
script {
docker.image("${IMAGE_NAME}:${env.BUILD_ID}").inside {
sh 'mvn test'
}
}
}
}
stage('Security Scan') {
steps {
script {
sh """
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image \
--exit-code 1 \
--severity HIGH,CRITICAL \
${IMAGE_NAME}:${env.BUILD_ID}
"""
}
}
}
stage('Push') {
steps {
script {
docker.withRegistry("https://${DOCKER_REGISTRY}", 'docker-credentials') {
docker.image("${IMAGE_NAME}:${env.BUILD_ID}").push()
docker.image("${IMAGE_NAME}:${env.BUILD_ID}").push('latest')
}
}
}
}
stage('Deploy') {
steps {
script {
sh """
docker-compose -f docker-compose.prod.yml pull
docker-compose -f docker-compose.prod.yml up -d
"""
}
}
}
}
}
十一、今儿个总结
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。
学会了啥?
- ✅ Docker核心概念:镜像、容器、仓库
- ✅ Dockerfile编写技巧和多阶段构建
- ✅ Docker Compose多服务编排
- ✅ 镜像优化:从1GB瘦身到100MB
- ✅ 生产环境最佳实践和安全
- ✅ 容器监控和调试技巧
- ✅ CI/CD集成
关键点
- 多阶段构建是瘦身关键
- .dockerignore能加速构建
- 非root用户运行更安全
- 健康检查保证服务可用性
- 数据卷实现持久化存储
- 网络隔离保证服务安全
十二、明儿个学啥?
明天咱学Kubernetes!
- Docker是集装箱,Kubernetes是集装箱货轮
- 自动扩缩容:流量大了自动加机器
- 自愈能力:容器挂了自动重启
- 服务发现:自动发现和负载均衡
- 配置管理:ConfigMap和Secret
明天咱从"手工部署"升级到"自动驾驶"!🚢
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。
Docker容器化深度实战:SpringCloud微服务镜像优化从1GB到100MB,附生产环境完整配置
【关注】
🔥 本文收录于《SpringCloud企业级实战》专栏,持续更新微服务架构系列
💡 关注+点赞,获取完整Dockerfile模板和docker-compose.yml配置
🚀 评论区留下你的Docker问题,24小时内必回
📚 配套GitHub项目:包含10+微服务Docker化完整示例
👨💻 下篇预告:Kubernetes实战,带你从Docker Compose平滑迁移到K8S
**