首页 > 解决方案 > 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

但我还是很困惑。我的问题是:

  1. 铁路环境是否需要手动设置?如何设置?我知道我们可以通过 SSH 运行类似的东西sudo apt install xxx,但我认为这在生产中有点奇怪。我们可以用更优雅的方式来完成它,比如 withcf push或另一个 cf 任务吗?

  2. 所以我需要使用flyway db迁移但是我们如何上传脚本(作为文件)或将.sql文件保存到CF空间?SSH?

  3. 我在我的 cf 空间上进行了测试。我只能运行 java,因为它带有一个 java 构建包。所以问题就变成了:我如何在推送的 jar 中运行 java 脚本(与问题 2 相同的问题)或 java 类来运行 db 迁移?

我是 CF 的新手,这可能真的很愚蠢,但我已经花了好几天的时间,还没有得到正确的答案。我的临时解决方案是在控制器中公开一个“/dbmigration”api。然后在服务中实现db迁移。然后我可以cf run-task APP_NAME -c "curl https://xxxxx.xxx.xxx/dbmigration" 在需要时运行以触发数据库迁移。但是我仍然需要在应用程序服务中处理数据库名称、用户、密码等,这不是首选。提前谢谢。

标签: javadevopsdatabase-migrationcloud-foundryflyway

解决方案


我被推荐使用 cf run-task。经过检查,我的理解是,cf run-task 是 cf 空间的“SSH 客户端”接口,因为我们甚至可以将“echo 1”作为 cf 任务运行。

这不太对。任务是附加到应用程序的资源。它会根据用于您的应用程序的液滴触发创建单独的容器,您设置的命令将在其中执行。一个任务应该有一个有限的生命周期(即它会运行,然后退出),而不是一个预期会运行并永远继续运行的应用程序。

该任务将在与应用程序完全相同配置的容器中运行,这还包括设置环境变量和绑定服务,就像您的应用程序一样。

  1. 铁路环境是否需要手动设置?如何设置?我知道我们可以通过 SSH 运行类似 sudo apt install xxx 的东西,但我认为这在生产中有点奇怪。我们可以用更优雅的方式来完成它,比如 cf push 或其他 cf 任务吗?

第一步是你需要cf push你的 Rails 应用程序。当您cf push使用应用程序时,Ruby buildpack 将运行并安装运行您的应用程序所需的一切。然后,生成的 droplet 将可用于运行您的应用程序或其他任务。

如果你想确保你的任务在你的应用程序启动之前运行,那就有点棘手了,这通常是你想要的数据库迁移。

下面是你如何做到这一点:

  1. 运行cf push --no-start。该论点确保您的应用程序不会启动。不幸的是,这也意味着应用程序没有暂存,所以我们还不能运行任务。
  2. 运行cf v3-packages my-cool-app(v6 cf cli) 或cf packages my-cool-app(v7 cf cli)。复制最新的包 guid,如果这是您的第一次推送,则只有一个。
  3. 运行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>列表。复制那个指南。
  4. 然后运行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)。这会将创建的液滴设置为当前活动的液滴。
  5. 你现在可以cf run-task
  1. 所以我需要使用flyway db迁移但是我们如何上传脚本(作为文件)或将.sql文件保存到CF空间?SSH?

如前所述,您首先要推送您的应用程序。暂存应用程序后,您可以运行可以是任何命令的任务。在您的情况下,您将指定运行迁移的命令。

命令将从中运行的当前工作目录将是您的应用程序的根目录(即您cf push的目录或 的-p参数cf push)。

  1. 我在我的 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/.,基本一样。


推荐阅读