大家好。我们将继续撰写有关编写项目的系列文章。
对分支进行排序
重要的是,为了不迷失分支及其在存储库中的顺序,我决定通过添加STEP_{number}前缀来重命名它们。例如,除了主分支之外,我们还有三个分支:- JRTB-0
- JRTB-2
- JRTB-3
- STEP_1_JRTB-0 - 第一步
- STEP_2_JRTB-2 - 第二步
- STEP_3_JRTB-3 - 第三步
关于 Docker 的一些知识
什么是 Docker?简而言之,它是一个工具,您可以使用它快速、安全地部署(部署)应用程序,为它们创建一个仅对它们来说必要的封闭基础设施。还是很难,我理解。总的来说,Docker可以理解为一个可以快速高效工作的开发平台。Docker可以理解为运行在服务器上的程序。该程序能够存储带有应用程序的容器。什么是容器?这是一个独立的基础设施,您可以在其中添加所需的一切。例如,对于Java应用程序,我们需要一个JRE来运行应用程序,容器将有这个,我们将需要一些其他软件 - 我们可以添加这个。或者也许我们需要 Linux 和 Tomcat servlet 容器。这也是可以做到的。容器是基于镜像创建的:也就是说,这是一个特定的模板,其中包含创建 Docker 容器所需的所有内容。如何创建这个图像?在我们的例子中,我们需要在项目的根目录创建一个 Dockerfile 来描述容器中应该包含的内容。由于我们不想在任何地方公开机器人的令牌,因此每次要部署应用程序时都必须传递它。您可以在此处和此处阅读有关此主题的更多信息。我们写JRTB-13
我们需要为我们的应用程序设置一个快速且简单的部署过程到服务器。也就是说,对于一台 24/7 工作的机器。让我们以 Docker 为基础。但我们的列表中没有任务负责添加此功能。不知何故,我在创建它时错过了它。没问题,我们现在就创建它。转到GitHub 上的问题创建选项卡,然后选择功能请求:添加任务描述、接受标准,设置此问题属于哪个项目,然后您可以创建新问题:现在,显示任务已被接受对于工作,将任务的状态从“进行中”更改为“待办事项”:这将是一篇困难的文章。如果有任何问题,请在评论中写下:我会尽力监控并解答。这将是一个小型的客户支持:D创建 Dockerfile
什么是 dockerfile?对于 Docker,这是一个关于如何为 Docker 容器创建映像的脚本(分步说明)。为了让我们的应用程序正常工作,我们需要 JDK 版本 11。也就是说,我们需要找到 JDK 11 docker 镜像并将其添加到我们的镜像中。这类似于我们向内存添加依赖项的方式。Docker为此提供了DockerHub。要在本地下载图像,您需要在那里注册。注册完成后,我们去寻找JDK11。根据我的发现,这是容器:adoptopenjdk/openjdk11。该容器的描述包含 dockerfile 所需的内容:FROM adoptopenjdk/openjdk11:ubi
RUN mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-jar", "/opt/app/japp.jar"]
让我们修复从中获取 jar 文件的文件夹。运行 mvn package maven 任务后,我们将其放在目标文件夹中。在完成这一切之前,基于更新的主分支,我们为我们的任务创建一个新分支:STEP_4_JRTB-13。现在你可以工作了。在项目的根目录中,创建一个不带Dockerfile扩展名的文件,并在其中添加以下内容:
FROM adoptopenjdk/openjdk11:ubi
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
第一行是镜像所基于的内容 - 采用openjdk/openjdk11。第二行是向名为 JAR_FILE 的映像添加一个参数,该映像位于目标文件夹中。此外,当前文件夹是由 Dockerfile 的位置确定的。第三行 - 将我们项目的 jar 复制到 docker 镜像中。最后一行本质上包含一个根据终端中的命令创建的数组,该数组以空格分隔。也就是说,最终将执行以下命令:“java -jar /app.jar” 为了使机器人令牌保密,在启动容器时,我们需要传递两个变量 - 机器人的名称及其令牌。为此,我们将编写一个查询,该查询应该使用变量启动我们的项目。以及如何做呢?你需要谷歌它:这是第一个带有正常描述的链接。我们想做什么?我们在 application.properties 文件中定义了两个变量:
- 机器人用户名
- 机器人令牌
- 让我们运行 bash 脚本。
- bash 脚本运行 docker-compose。
- Docker-compose 使用我们的应用程序启动一个 docker 容器。
- Docker 容器运行我们的应用程序。
FROM adoptopenjdk/openjdk11:ubi
ARG JAR_FILE=target/*.jar
ENV BOT_NAME=test.javarush_community_bot
ENV BOT_TOKEN=1375780501:AAE4A6Rz0BSnIGzeu896OjQnjzsMEG6_uso
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-Dbot.username=${BOT_NAME}", "-Dbot.token=${BOT_TOKEN}", "-jar", "/app.jar"]
您可以看到我们添加了两行并更新了 ENTRYPOINT。线路:
ENV BOT_NAME=test.javarush_community_bot
ENV BOT_TOKEN=1375780501:AAE4A6Rz0BSnIGzeu896OjQnjzsMEG6_uso
在编码器文件中声明变量。默认情况下,它们有一个指定的值。如果从这个dockerfile创建镜像时,传递了这样名字的环境变量,那么值就会不同。在 ENTRYPOINT 中,我们添加了更多元素来读取这些环境变量:
"-Dbot.username=${BOT_NAME}", "-Dbot.token=${BOT_TOKEN}"
在这里您可以看到,在该行内部,使用 ${} 构造,将传递 BOT_NAME 和 BOT_TOKEN 的值。接下来,我们需要教授如何接收这些变量并将其传递给 docker-compose。
创建 docker-compose.yml
你最好单独阅读 YAML 格式,否则这篇文章已经突飞猛进了。对于我们来说,这只是 .properties 类型变量的另一种描述。仅在属性中,它是通过点编写的,但在 YAML 中,这样做得更漂亮一些。例如,像这样。.properties 中的两个变量: javarush.telegram.bot.name=ivan javarush.telegram.bot.token=pupkin 但在 .yaml 中(与 .yml 相同)它将是这样的:javarush:
telegram:
bot:
name: ivan
token: pupkin
第二种选择更美观、更容易理解。空格应完全如上所示。让我们以某种方式翻译我们的 application.properties 和 application.yml 。首先您需要创建它。在项目的根目录中,创建一个文件docker-compose.yml并在其中写入以下内容:
version: '3.1'
services:
jrtb:
build:
context: .
environment:
- BOT_NAME=${BOT_NAME}
- BOT_TOKEN=${BOT_TOKEN}
restart: always
第一行是 docker-compose 版本。 services:表示此后的所有以下行(将被转移)引用我们正在配置的服务。到目前为止,我们只有其中一个 - 一个名为jrtb的 Java 应用程序。在它的下面已经是它的所有设置。例如,构建:上下文:。表示我们将在与 docker-compose.yml 相同的目录中查找 Dockerfile。但环境:部分将负责确保我们将必要的环境变量传递给 Dockerfile。正是我们所需要的。因此,我们在下面传递变量。Docker-compose 会在服务器运行环境变量中寻找它们。让我们将它们添加到 bash 脚本中。
创建 bash 脚本
最后一步是创建 bash 脚本。在项目的根目录中创建一个名为 start.sh 的文件,并在其中写入以下内容:#!/bin/bash
# Pull new changes
git pull
# Prepare Jar
mvn clean
mvn package
# Ensure, that docker-compose stopped
docker-compose stop
# Add environment variables
export BOT_NAME=$1
export BOT_TOKEN=$2
# Start new deployment
docker-compose up --build -d
所有 bash 脚本都需要第一行:没有它它将无法工作。然后 - 只需在终端中执行一组命令即可。我在每个命令中添加了注释,因此应该很清楚。我唯一想解释的是$1和$2是什么意思。这是启动 bash 脚本时将传递的两个变量。使用导出命令,它们将被添加到服务器变量中并在 docker-compose 中读取。这适用于 Ubuntu,可能不适用于 Windows,但我不确定。现在您需要添加 stop.sh 脚本,这将停止工作。它将包含几行:
#!/bin/bash
# Ensure, that docker-compose stopped
docker-compose stop
# Ensure, that the old application won't be deployed again.
mvn clean
在这里,我们停止 docker-compose 并清理项目 jarnik,该项目自上次构建以来一直存在。我们这样做是为了确保我们的项目能够准确地重建。有先例,这就是我添加的原因)结果,我们最终得到了 4 个新文件:
- Dockerfile - 用于创建应用程序映像的文件;
- docker-compose.yml - 一个文件,其中包含我们如何启动容器的设置;
- start.sh - 用于部署我们的应用程序的 bash 脚本;
- stop.sh 是一个用于停止我们的应用程序的 bash 脚本。
# 发行说明 ## 0.3.0-SNAPSHOT * JRTB-13:向项目添加部署过程 ## 0.2.0-SNAPSHOT * JRTB-3:实现用于处理 Telegram Bot 命令的命令模式 ## 0.1.0-SNAPSHOT * JRTB -2:添加存根电报机器人 * JRTB-0:添加 SpringBoot 骨架项目
在自述文件中,我们将添加一个新段落来描述如何部署我们的应用程序:
## 部署 部署过程尽可能简单: 所需软件: - 用于运行 bash 脚本的终端 - docker - docker-compose 部署应用程序,切换到所需分支并运行 bash 脚本: $ bash start.sh ${bot_username} ${bot_token } 就这样。
当然,一切都是用英文写的。像往常一样,在我们新创建的分支 STEP_4_JRTB-13 中,我们创建一个名为:JRTB-13 的新提交:通过 docker 实现部署过程并推送它。我不再详细讨论我在之前的文章中已经描述过的事情。我不认为重复同样的事情有什么意义。再说了,那些自己想出来并做过的人不会有任何疑问。这是我谈论如何创建新分支,如何创建提交,如何将提交推送到存储库。
GO TO FULL VERSION