用docker启动一个项目的过程:
先是获取项目源码(github找一个开源项目),再将项目构建成一个镜像(构建镜像用到的文件是Dockerfile),最后对该镜像进行部署(部署用到的文件是docker-compose.yml
),下面先详细解释一下 Dockerfile 和 docker-compose.yml
类比角色 | Docker 对应组件 | 说明 |
---|---|---|
菜谱 | Dockerfile | 说明怎么做出一个“镜像” |
做好的一盘菜 | 镜像(image) | 用 Dockerfile 构建出来的结果 |
摆好饭桌开饭 | docker-compose.yml | 定义“吃饭时要上哪些菜、几个人吃、哪张桌子” |
说说docker中镜像、容器、仓库三者的概念:
一个镜像就代表一个软件;而基于某个镜像运行就是生成一个程序实例,这个程序实例就是容器;而仓库是用来存储 Docker 中所有镜像的。(来自JavaGuide)
-
拉一个 开源项目到本机:https://github.com/bezkoder/docker-compose-spring-boot-mysql(这个项目中作者已经写好了docker的配置文件)
-
提前下载好docker,配置 Docker 的 镜像加速器,配置完后重开docker
// 重点是 registry-mirrors { "builder": { "gc": { "defaultKeepStorage": "20GB", "enabled": true } }, "experimental": false, "registry-mirrors": [ "https://docker.m.daocloud.io", "https://docker.imgdb.de", "https://docker-0.unsee.tech", "https://docker.hlmirror.com", "https://docker.1ms.run", "https://func.ink", "https://lispy.org", "https://docker.xiaogenban1993.com" ] }
💡 加速器的作用:
Docker 默认从官方的 Docker Hub 拉取镜像,但这个速度在中国大陆地区可能比较慢甚至失败。
镜像加速器是第三方的中转服务器,它们缓存了 Docker Hub 的镜像,可以大大加快镜像拉取速度,减少下载失败的几率。🧱 如何工作:
当你执行:docker pull ubuntu
Docker 会按顺序尝试从这些 registry mirrors 下载镜像。如果第一个可用且响应快,就用它;如果失败就尝试下一个。
-
接下来看看此github项目的结构,包括了两个主要的文件:Dockerfile 和 docker-compose.yml
-
Dockerfile是一个将项目构建成镜像的文件,我们先看看 Dockerfile 文件里面的代码是什么意思
# 使用官方 Maven 镜像作为基础镜像,并自带 OpenJDK 8 环境 FROM maven:3.8.2-openjdk-8 # 设置容器中的工作目录为 /bezkoder-app(相当于 cd 到这个目录) WORKDIR /bezkoder-app # 将当前宿主机目录下的所有文件复制到容器的 /bezkoder-app 目录中 COPY . . # 在容器中运行 Maven 构建命令,编译并打包 Spring Boot 项目 RUN mvn clean install # 启动容器时默认执行 spring-boot:run,启动 Spring Boot 应用 CMD mvn spring-boot:run
Docker 官方的公共镜像仓库 Docker Hub 提供的镜像
# 构建命令: docker bulid -t your-image-name . docker build :打包的命令 -t your-image-name :项目镜像名称 . :Dockerfile在当前目录下
看看构建好的镜像在哪里:docker images
-
docker-compose.yml 是将已有的镜像运行起来的配置文件
# 声明使用的是 Docker Compose 文件的版本 3.8 version: "3.8" # services: 定义两个服务(containers):mysqldb 和 app services: mysqldb: image: mysql:5.7 # 使用官方的 mysql:5.7 镜像启动一个数据库容器 restart: unless-stopped # 表示除非手动停止,否则容器会自动重启 env_file: ./.env #使用当前目录下的 .env 文件,提供环境变量值 environment: # 设置 MySQL 的 root 密码和要创建的数据库名称,值从 .env 文件中读取 - MYSQL_ROOT_PASSWORD=${MYSQLDB_ROOT_PASSWORD} - MYSQL_DATABASE=${MYSQLDB_DATABASE} ports: #把主机的 ${MYSQLDB_LOCAL_PORT} 映射到容器中的 ${MYSQLDB_DOCKER_PORT} - ${MYSQLDB_LOCAL_PORT}:${MYSQLDB_DOCKER_PORT} volumes: # 使用名为 db 的持久卷来保存数据库文件,避免数据因容器销毁而丢失。 - db:/var/lib/mysql app: image: test-image # ← 直接使用你构建的镜像 depends_on: # 表示该服务依赖 mysqldb 服务,会在它之后启动 - mysqldb restart: on-failure # 发生崩溃时重启,但不会一直重启。 env_file: ./.env # 同样使用 .env 文件中定义的变量 ports: # 把主机的端口映射到容器内部 Spring Boot 的端口 - ${SPRING_LOCAL_PORT}:${SPRING_DOCKER_PORT} environment: # 用 SPRING_APPLICATION_JSON 来注入 Spring Boot 的配置信息,如数据库连接地址、用户名密码等。它是一种将配置信息注入到 application.properties 的替代方法。 SPRING_APPLICATION_JSON: '{ "spring.datasource.url" : "jdbc:mysql://mysqldb:$MYSQLDB_DOCKER_PORT/$MYSQLDB_DATABASE?useSSL=false", "spring.datasource.username" : "$MYSQLDB_USER", "spring.datasource.password" : "$MYSQLDB_ROOT_PASSWORD", "spring.jpa.properties.hibernate.dialect" : "org.hibernate.dialect.MySQL5InnoDBDialect", "spring.jpa.hibernate.ddl-auto" : "update" }' volumes: # 挂载 Maven 的缓存目录到容器中,避免每次构建都重新下载依赖 - .m2:/root/.m2 stdin_open: true #开启标准输入和伪终端 tty: true #开启伪终端 volumes: db: #定义了名为 db 的 Docker 卷,用于持久化 mysqldb 容器的数据库数据
.env 文件,可理解成存储系统数据的文件:
项目部署命令,切到 docker-compose.yml 的目录下:docker compose up
-
测试我们的服务是否正确开启,打开postman,新开一个 post 请求:
http://localhost:6868/api/tutorials
header 加上这一行:
Content-Type: application/json
body 加上入参:
{ "title": "Spring Boot + Docker", "description": "测试描述内容:你好,世界!", "published": false }
点击发送,服务就会将我们的入参添加到数据库中,感兴趣的可以去看代码中的 Controller层,里面有编写逻辑 -
再新增一个get请求,header 和 body 都无需设置,点击 send,即可获取刚刚我们添加的数据
有疑问的话,可留言。