Skip to content

容器化打包

概念

镜像

镜像包含了编译后的文件Jar包,以及它们运行所需要的所有基础环境,镜像是只读的。

容器

容器是镜像运行的实例,应用跑在容器里,彼此隔离,互不干扰。

Dockerfile

通过指令进行镜像生成。

Docker Compose

一键启动、停止所有服务,并让它们处于同一个局域网内互相通信

镜像分层

联合文件系统(UFS):

  • 基础层: 通常是极其精简的操作系统
  • 环境层: JDK或Node.js环境
  • 依赖层: 项目依赖
  • 代码层: 代码 当只修改代码层时,docker打包会对底层直接使用缓存,只重新构建代码层,加快了打包速度

容器网络

Docker里的每个容器之间都是隔离的,有自己的虚拟IP,Docker通过虚拟网桥实现容器之间的通信。使用docker-compose.yml启动项目时,Docker Compose会在后台创建一个项目的专属虚拟局域网,将所有容器拉进局域网里。
在同一个Docker网络下,将容器的名字作为域名,Docker内置的DNS服务会自动将域名解析为容器内 网IP。

数据持久化

容器是不持久化保留的,为了保留数据,使用数据卷(volumes),数据卷将容器内部的目录与宿主机的真实硬盘目录相连通,数据卷直接保存在硬盘上,永久保存。当旧的容器被销毁,启动新的容器时,可以直接读取之前的数据

Dockerfile

# 1. 基础环境层 (FROM)
# 告诉 Docker:以含有 JDK 17 的极简 Linux (Alpine) 为基础制作镜像
FROM eclipse-temurin:17-jre-alpine

# 2. 设置工作目录 (WORKDIR)
# 相当于在 Linux 里执行了 `mkdir /app` 和 `cd /app`
WORKDIR /app

# 3. 拷贝文件 (COPY)
# 把你在本地/CI环境中打包好的 jar 包,拷贝到容器的 /app 目录下,并重命名为 app.jar
COPY target/my-springboot-project-1.0.jar app.jar

# 4. 声明端口 (EXPOSE)
# 告诉使用这个镜像的人,这个容器运行时会监听 8080 端口(这只是一个声明,不代表直接对外开放)
EXPOSE 8080

# 5. 启动命令 (CMD 或 ENTRYPOINT)
# 容器启动时默认执行的指令
ENTRYPOINT ["java", "-jar", "app.jar"]

docker-compose.yml

version: '3.8' # Compose 语法的版本号

services: # 下面定义了三个服务:mysql, redis, 和你的 springboot 后端

  # 1. 数据库服务
  db-mysql:
    image: mysql:8.0 # 直接使用官方现成的镜像
    container_name: my_mysql # 给容器起个固定的名字,方便辨认
    restart: always # 如果容器意外崩溃或服务器重启,自动拉起它
    environment:
      MYSQL_ROOT_PASSWORD: my_strong_password # 注入环境变量设置密码
      MYSQL_DATABASE: my_database # 启动时自动创建一个库
    ports:
      - "3306:3306" # 端口映射:把宿主机的 3306 映射到容器的 3306
    volumes:
      - mysql_data:/var/lib/mysql # 数据持久化:把数据挂载到宿主机,防止丢失

  # 2. 缓存服务
  cache-redis:
    image: redis:7.0-alpine
    container_name: my_redis
    restart: always
    ports:
      - "6379:6379"

  # 3. 后端服务
  api-springboot:
    build: ./backend # 告诉 Compose:去 backend 目录找 Dockerfile 现场构建镜像
    image: my-springboot-app:latest # 构建出来的镜像叫什么名字
    container_name: my_springboot
    restart: always
    ports:
      - "8080:8080"
    depends_on:
      - db-mysql # 依赖关系:确保 mysql 启动后再启动 backend,防止报错
      - cache-redis

# 声明数据卷(刚才在 mysql 服务里用到的卷,必须在这里注册一下)
volumes:
  mysql_data: