为 Azure 应用服务配置 Linux Ruby 应用

本文介绍 Azure 应用服务如何在 Linux 容器中运行 Ruby 应用,以及如何按需自定义应用服务的行为。 Ruby 应用必须与所有必需的 gem 一起部署。

对于在应用服务中使用内置 Linux 容器的 Ruby 开发人员,本指南为其提供了关键概念和说明。 若从未使用过 Azure 应用服务,则首先应按照 Ruby 快速入门以及将 Ruby 与 PostgreSQL 配合使用教程进行操作。

显示 Ruby 版本

若要显示当前的 Ruby 版本,请在 Azure CLI 中运行以下命令:

az webapp config show --resource-group <resource-group-name> --name <app-name> --query linuxFxVersion

若要显示所有受支持的 Ruby 版本,请在 Azure CLI 中运行以下命令:

az webapp list-runtimes --os linux | grep RUBY

设置 Ruby 版本

在 Azure CLI 中运行以下命令,将 Ruby 版本设置为 2.7:

az webapp config set --resource-group <resource-group-name> --name <app-name> --linux-fx-version "RUBY:2.7"

注意

如果在部署期间看到与以下类似的错误:

Your Ruby version is 2.7.3, but your Gemfile specified 2.3.1

rbenv: version `2.3.1' is not installed

这意味着项目中配置的 Ruby 版本与正在运行的容器中安装的版本不同(在上面的示例中为 2.7.3)。 在上面的示例中,检查 Gemfile 和 .ruby-version 并验证是否未设置 Ruby 版本,或者是否设置为正在运行的容器中安装的版本(在上面的示例中为 2.7.3) 。

访问环境变量

在应用服务中,可以在应用代码外部设置应用设置。 然后,可以使用标准的 ENV['<path-name>'] 模式访问这些设置。 例如,若要访问名为 WEBSITE_SITE_NAME 的应用设置,请使用以下代码:

ENV['WEBSITE_SITE_NAME']

自定义部署

部署 Git 存储库或者部署启用了生成自动化Zip 包时,部署引擎 (Kudu) 会默认运行以下后期部署步骤:

  1. 检查 Gemfile 是否存在。
  2. 运行 bundle clean
  3. 运行 bundle install --path "vendor/bundle"
  4. 运行 bundle package,将 gems 打包到 vendor/cache 文件夹中。

使用 --without 标志

要使用 --without 标志运行 bundle install,请将 BUNDLE_WITHOUT应用设置设置为以逗号分隔的组列表。 例如,使用以下命令将其设置为 development,test

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings BUNDLE_WITHOUT="development,test"

如果定义了此设置,那么部署引擎将使用 --without $BUNDLE_WITHOUT 运行 bundle install

预编译资产

默认情况下,后期部署步骤不会预编译资产。 要启用资产预编译,请将 ASSETS_PRECOMPILE应用设置设置为 true。 然后在后期部署步骤结束时运行命令 bundle exec rake --trace assets:precompile。 例如:

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings ASSETS_PRECOMPILE=true

有关详细信息,请参阅提供静态资产

自定义启动

默认情况下,Ruby 容器按以下顺序启动 Rails 服务器(有关详细信息,请参阅启动脚本):

  1. 生成 secret_key_base 值(如果尚不存在)。 应用在生产模式下运行时需要此值。
  2. RAILS_ENV 环境变量设置为 production
  3. 在 tmp / pids 目录中,删除先前运行 Rails 服务器留下的任何 .pid 文件 。
  4. 检查是否安装了所有依赖项。 如果没有,请尝试从本地 vendor/cache 目录安装 gems。
  5. 运行 rails server -e $RAILS_ENV

可按以下方式自定义启动进程:

提供静态资产

默认情况下,Ruby 容器中的 Rails 服务器在生产模式下运行,假定资产已进行预编译并由 Web 服务器提供。 要从 Rails 服务器提供静态资产,需完成两个操作:

在非生产模式下运行

默认情况下,Rails 服务器在生产模式下运行。 例如,要在开发模式下运行,请将 RAILS_ENV应用设置设置为 development

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings RAILS_ENV="development"

但是,仅此设置会导致 Rails 服务器在开发模式下启动,该模式仅接受 localhost 请求,并且在容器外部无法访问。 要接受远程客户端请求,请将 APP_COMMAND_LINE应用设置设置为 rails server -b 0.0.0.0。 此应用设置使你可在 Ruby 容器中运行自定义命令。 例如:

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings APP_COMMAND_LINE="rails server -b 0.0.0.0"

手动设置 secret_key_base

要使用自己的 secret_key_base 值而不是让应用服务生成一个值,请使用想要的值设置 SECRET_KEY_BASE应用设置。 例如:

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings SECRET_KEY_BASE="<key-base-value>"

访问诊断日志

若要访问应用服务中的应用程序代码内生成的控制台日志,请在 Azure CLI 中运行以下命令以打开诊断日志记录:

az webapp log config --resource-group <resource-group-name> --name <app-name> --docker-container-logging filesystem --level Verbose

--level 的可能值为:ErrorWarningInfoVerbose。 每个后续级别包括上一个级别。 例如:Error 仅包含错误消息,Verbose 则包含所有消息。

启用诊断日志记录功能以后,请运行以下命令来查看日志流:

az webapp log tail --resource-group <resource-group-name> --name <app-name>

如果没有立即看到控制台日志,请在 30 秒后重新查看。

注意

也可通过浏览器在 https://<app-name>.scm.chinacloudsites.cn/api/logs/docker 中检查日志文件。

若要随时停止日志流式处理,请键入 Ctrl+C

在浏览器中打开 SSH 会话

若要通过容器打开直接的 SSH 会话,应用应该处于正在运行状态。

将以下 URL 粘贴到浏览器中,将 <app-name> 替换为应用名称:

https://<app-name>.scm.chinacloudsites.cn/webssh/host

如果尚未进行身份验证,则需通过要连接的 Azure 订阅进行身份验证。 完成身份验证以后,可以看到一个浏览器内 shell,可以在其中的容器中运行命令。

SSH connection

注意

/home 目录之外进行的任何更改均存储在容器本身中,在应用重启后不保留。

若要从本地计算机打开远程 SSH 会话,请参阅从远程 shell 打开 SSH 会话

日志中的 robots933456

你可能会在容器日志中看到以下消息:

2019-04-08T14:07:56.641002476Z "-" - - [08/Apr/2019:14:07:56 +0000] "GET /robots933456.txt HTTP/1.1" 404 415 "-" "-"

可以放心忽略此消息。 /robots933456.txt 是一个虚拟 URL 路径,应用服务使用它来检查容器能否为请求提供服务。 404 响应只是指示该路径不存在,但它让应用服务知道容器处于正常状态并已准备就绪,可以响应请求。

更多资源