java - cf run-task 是否需要在运行前上传环境/脚本?优雅的方式?
问题描述
我正在与云代工合作。我需要在我的应用程序之外运行数据库迁移,以便我可以在需要时以某种方式(cf 命令、api 调用等)触发迁移。
我被推荐使用cf run-task
. 经过检查,我的理解是,cf run-task 是 cf 空间的“SSH 客户端”接口,因为我们甚至可以"echo 1"
作为 cf 任务运行。我在官方 cf CLI 文档或一些在线指南上看到了这样的例子cf run-task my-app "bin/rails db:migrate" --name my-task
。
但我还是很困惑。我的问题是:
铁路环境是否需要手动设置?如何设置?我知道我们可以通过 SSH 运行类似的东西
sudo apt install xxx
,但我认为这在生产中有点奇怪。我们可以用更优雅的方式来完成它,比如 withcf push
或另一个 cf 任务吗?所以我需要使用flyway db迁移但是我们如何上传脚本(作为文件)或将.sql文件保存到CF空间?SSH?
我在我的 cf 空间上进行了测试。我只能运行 java,因为它带有一个 java 构建包。所以问题就变成了:我如何在推送的 jar 中运行 java 脚本(与问题 2 相同的问题)或 java 类来运行 db 迁移?
我是 CF 的新手,这可能真的很愚蠢,但我已经花了好几天的时间,还没有得到正确的答案。我的临时解决方案是在控制器中公开一个“/dbmigration”api。然后在服务中实现db迁移。然后我可以cf run-task APP_NAME -c "curl https://xxxxx.xxx.xxx/dbmigration"
在需要时运行以触发数据库迁移。但是我仍然需要在应用程序服务中处理数据库名称、用户、密码等,这不是首选。提前谢谢。
解决方案
我被推荐使用 cf run-task。经过检查,我的理解是,cf run-task 是 cf 空间的“SSH 客户端”接口,因为我们甚至可以将“echo 1”作为 cf 任务运行。
这不太对。任务是附加到应用程序的资源。它会根据用于您的应用程序的液滴触发创建单独的容器,您设置的命令将在其中执行。一个任务应该有一个有限的生命周期(即它会运行,然后退出),而不是一个预期会运行并永远继续运行的应用程序。
该任务将在与应用程序完全相同配置的容器中运行,这还包括设置环境变量和绑定服务,就像您的应用程序一样。
- 铁路环境是否需要手动设置?如何设置?我知道我们可以通过 SSH 运行类似 sudo apt install xxx 的东西,但我认为这在生产中有点奇怪。我们可以用更优雅的方式来完成它,比如 cf push 或其他 cf 任务吗?
第一步是你需要cf push
你的 Rails 应用程序。当您cf push
使用应用程序时,Ruby buildpack 将运行并安装运行您的应用程序所需的一切。然后,生成的 droplet 将可用于运行您的应用程序或其他任务。
如果你想确保你的任务在你的应用程序启动之前运行,那就有点棘手了,这通常是你想要的数据库迁移。
下面是你如何做到这一点:
- 运行
cf push --no-start
。该论点确保您的应用程序不会启动。不幸的是,这也意味着应用程序没有暂存,所以我们还不能运行任务。 - 运行
cf v3-packages my-cool-app
(v6 cf cli) 或cf packages my-cool-app
(v7 cf cli)。复制最新的包 guid,如果这是您的第一次推送,则只有一个。 - 运行
cf v3-stage my-cool-app --package-guid <package-guid>
(v6 cf cli) 或cf stage my-cool-app --package-guid <package-guid>
(v7 cf cli)。您将看到类似于 的输出cf push
,它是正在运行的 buildpack 和正在创建的 droplet。输出会说Packaged staged
并有一个droplet guid: <guid>
列表。复制那个指南。 - 然后运行
cf v3-set-droplet my-cool-app -d <droplet-guid>
(v6 cf cli) 或cf set-droplet my-cool-app -d <droplet-guid>
(v7 cf cli)。这会将创建的液滴设置为当前活动的液滴。 - 你现在可以
cf run-task
。
- 所以我需要使用flyway db迁移但是我们如何上传脚本(作为文件)或将.sql文件保存到CF空间?SSH?
如前所述,您首先要推送您的应用程序。暂存应用程序后,您可以运行可以是任何命令的任务。在您的情况下,您将指定运行迁移的命令。
命令将从中运行的当前工作目录将是您的应用程序的根目录(即您cf push
的目录或 的-p
参数cf push
)。
- 我在我的 cf 空间上进行了测试。我只能运行 java,因为它带有一个 java 构建包。所以问题变成了:我如何运行 java 脚本(与问题 2 相同的问题)或
您只能运行基本映像中存在的内容或已由 buildpack 安装的内容。如果您正在运行 Java buildpack,您将拥有可用的 java(特别是 JRE)。默认情况下它不在 $PATH 上,但您可以运行.java-buildpack/open_jdk_jre/bin/java
.
例如:cf run-task my-cool-app '.java-buildpack/open_jdk_jre/bin/java -version'
如果您需要其他工具,则可以运行多个 buildpack。例如,如果您需要执行 Javascript 代码,您可以运行 Node.js buildpack。还有一个apt-buildpack可用于安装可通过 apt 或.deb
文件获得的附加软件包。
请注意,Java buildpack必须是列出的最后一个 buildpack。它仅作为最终的 buildpack 工作。
我推送的 jar 中的 java 类来运行数据库迁移?
如前所述,当前工作目录是您推送的内容的根目录(对于 Java,它是您的 JAR/WAR 的根目录)。java -cp . com.example.Main
因此,您可以-cp .
设置类路径以包含当前目录,即您的类文件所在的位置。如果您查看 Java buildpack 生成的用于运行您的应用程序的命令,它会很相似。有$PWD/.
,基本一样。
推荐阅读
- r - 基于多个条件的标志
- javascript - 将 If/Else 转换为三元 React Typescript
- java - 如何将现有的 Maven 项目作为多模块 Maven 项目的一部分?
- powershell - 在 PowerShell 中运行 PowerShell 脚本运行正确,但从调度程序运行时出错
- r - 使用 pagedown 创建的 xaringan PDF 中不需要的边距
- java - 参数化 Java JPA ALTER SESSION SQL
- mysql - 通过计算返回 2 个额外的查询列
- xslt - 如何从 XLST 中排除节点
- javascript - 展开/折叠所有数据
- javascript - Vue:在 Function.[Symbol.hasInstance] 处超出了最大调用堆栈大小