Skip to content

Docker 容器化

一、为什么用 Docker

"我这能跑" → "你环境里也能跑":Docker 把应用 + 运行环境打包成镜像,在任何装了 Docker 的机器上行为一致。

┌─────────────────────────────┐
│ Dockerfile(构建配方)        │
│  基础镜像 + 复制代码 + 启动命令 │
└─────────────┬───────────────┘
              │ build

      镜像 image(只读模板)
              │ run

      容器 container(运行实例)

核心概念:

概念类比说明
镜像安装包只读模板
容器运行的程序镜像的运行实例,可启停
Dockerfile安装说明书描述怎么构建镜像
Docker Hub应用商店公共镜像仓库

二、后端 Dockerfile

dockerfile
# server/Dockerfile
# 阶段 1:用 Maven 构建 jar
FROM maven:3.9-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline          # 预下载依赖,利用缓存
COPY src ./src
RUN mvn package -DskipTests

# 阶段 2:运行(多阶段构建,镜像更小)
FROM eclipse-temurin:17-jre
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENV SPRING_PROFILES_ACTIVE=prod        # 生产配置
ENTRYPOINT ["java", "-jar", "app.jar"]

多阶段构建:第一阶段带 Maven 编译,第二阶段只要 JRE 运行,最终镜像小、安全。

三、前端 Dockerfile(Vue / React 通用)

dockerfile
# web-vue/Dockerfile(web-react 相同)
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 运行阶段:把静态文件交给 Nginx 托管
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80

前端最终产物是纯静态文件,运行时只需要 Nginx,不需要 Node。

四、docker-compose:一键编排全部服务

开发/测试环境用 compose 把后端 + 前端 + MySQL 一键拉起:

yaml
# docker-compose.yml(仓库根目录)
version: "3.8"

services:
  mysql:
    image: mysql:8.0
    container_name: mall-mysql
    environment:
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: mall
      TZ: Asia/Shanghai
    ports: ["3306:3306"]
    volumes:
      - mysql-data:/var/lib/mysql     # 数据持久化
      - ./server/sql:/docker-entrypoint-initdb.d  # 启动时自动执行建表 SQL
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

  server:
    build: ./server
    container_name: mall-server
    depends_on: [mysql]
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/mall?serverTimezone=Asia/Shanghai
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: root123
    ports: ["8080:8080"]

  web-vue:
    build: ./web-vue
    container_name: mall-web-vue
    depends_on: [server]
    ports: ["80:80"]

volumes:
  mysql-data:
bash
docker-compose up -d --build     # 构建并后台启动
docker-compose logs -f server    # 看后端日志
docker-compose down              # 停止(数据卷保留)

五、常用命令

bash
docker images                  # 查看镜像
docker ps                      # 查看运行中的容器
docker ps -a                   # 所有容器
docker logs -f mall-server     # 容器日志
docker exec -it mall-server sh # 进入容器
docker rm -f mall-server       # 强制删除容器

六、数据卷与网络(两个必懂点)

  • 卷 volumes:容器删除数据不丢。MySQL 数据放卷里,重启/重建容器数据仍在。
  • 自定义网络:compose 里 mysqlserverweb-vue 通过服务名互访(后端连数据库写 jdbc:mysql://mysql:3306 而不是 localhost)。

七、本地验证

bash
docker-compose up -d --build
curl http://localhost:8080/api/product/list    # 后端通
curl http://localhost/                         # 前端页面通

常见坑

  1. MYSQL_DATABASE 与后端 URL 的库名要一致。
  2. 后端连数据库用服务名 mysql,不是 localhost
  3. 端口冲突:本机已跑 MySQL 时,把 compose 的 3306 映射改成 3307:3306

基于 MIT 协议发布,可自由学习与修改