本教程介绍如何在 Azure 应用服务中创建安全的 PHP 应用连接到 MySQL 数据库(使用 Azure Database for MySQL 灵活服务器)。 你还将部署 Azure Cache for Redis 以在应用程序中启用缓存代码。 Azure 应用服务是一种可缩放程度高、支持自修补的 Web 托管服务,可轻松地在 Windows 或 Linux 上部署应用。 完成本教程后,Linux 上的 Azure 应用服务中将会运行一个 Laravel 应用。
- 具有活动订阅的 Azure 帐户。 如果没有 Azure 帐户, 可以创建一个帐户。
- GitHub 帐户。 你也可以免费获得一个。
- 了解 PHP 与 Laravel 开发。
- (可选)若要试用 GitHub Copilot,请创建一个 GitHub Copilot 帐户。 提供 30 天试用期。
首先,将示例数据驱动的应用设置为起点。 为方便起见,示例存储库包含一个开发容器配置。 开发容器包含开发应用程序所需的所有内容,包括示例应用程序所需的数据库、缓存和所有环境变量。 开发容器可以在 GitHub codespace 中运行,这意味着可使用 Web 浏览器在任何计算机上运行示例。
步骤 1:在新浏览器窗口中:
- 登录到 GitHub 帐户。
- 导航到 https://github.com/Azure-Samples/laravel-tasks/fork。
- 选择“创建分支”。
步骤 2:在 GitHub 分支中:
- 选择“代码”“在主分支上创建 codespace”。>
要设置好 codespace 需要几分钟时间。 此外,提供的 .env 文件已包含 Laravel 需要在本地运行的虚拟
APP_KEY
变量。
步骤 3:在 codespace 终端中:
- 运行
composer install
。 - 使用
php artisan migrate
运行数据库迁移。 - 使用
php artisan serve
运行应用。 - 看到通知
Your application running on port 80 is available.
时,选择“在浏览器中打开”。 应在新的浏览器选项卡中看到该示例应用程序。若要停止应用程序,请键入Ctrl
+C
。
遇到问题? 检查故障排除部分。
在此步骤中,将创建 Azure 资源并将示例应用部署到 Linux 上的应用服务。 本教程中使用的步骤创建一组默认安全的资源,其中包括应用服务和 Azure Database for MySQL。
GitHub codespace 已具有 Azure 开发人员 CLI (AZD)。
使用
php artisan key:generate --show
: 生成 Laravel 加密密钥:php artisan key:generate --show
通过运行
azd auth login
命令并按照提示登录到 Azure:azd auth login
使用
azd up
命令创建必要的 Azure 资源并部署应用代码。 按照提示为 Azure 资源选择所需的订阅和位置。azd up
出现提示时,请提供以下答案:
问题 答案 输入新环境名称 键入唯一名称。 AZD 模板将此名称用作 Azure 中 Web 应用的 DNS 名称的一部分 ( <app-name>-<hash>.chinacloudsites.cn
)。 允许使用字母数字字符和下划线。选择要使用的 Azure 订阅 选择订阅。 选择要使用的 Azure 位置 选择一个位置。 输入“appKey”基础结构安全参数的值 在此处使用 php artisan key:generate --show
的输出。 AZD 模板会为此创建一个可在应用中使用的 Key Vault 密钥。输入“databasePassword”基础结构安全参数的值 MySQL 的数据库密码。 它长度必须至少为 8 个字符,并且包含大写字母、小写字母、数字和特殊字符。 azd up
命令需要大约 15 分钟来完成(Redis 缓存需要的时间最长)。 它还会编译和部署应用程序代码,但你稍后将修改代码以使用应用服务。 在运行时,该命令会提供有关预配和部署过程的消息,包括指向 Azure 中部署的链接。 完成后,命令还会显示指向部署应用程序的链接。此 AZD 模板包含使用以下 Azure 资源生成安全默认体系结构的文件(azure.yaml 和 infra 目录):
- 资源组:所有已创建资源的容器。
- 应用服务计划:为应用服务定义计算资源。 在 B1 层中创建了一个 Linux 计划。
- 应用服务:表示应用并在应用服务计划中运行。
- 虚拟网络:与应用服务应用集成,并隔离后端网络流量。
- Azure Database for MySQL 灵活服务器:只能通过 DNS 区域集成从虚拟网络访问。 将在服务器上为你创建数据库。
- Azure Cache for Redis:只能从虚拟网络中访问。
- 专用终结点:虚拟网络中密钥保管库和 Redis 缓存的访问终结点。
- 专用 DNS 区域:启用虚拟网络中的密钥保管库、数据库服务器和 Redis 缓存的 DNS 解析。
- Log Analytics 工作区:充当应用日志传送的目标容器,还可以在其中查询日志。
- 密钥保管库:使用 AZD 重新部署时,用于保留数据库密码。
遇到问题? 检查故障排除部分。
你使用的 AZD 模板已为你生成了连接变量作为应用设置,并将它们输出到终端,以方便你使用。 使用应用设置可以将连接机密保留在代码存储库之外。
在 AZD 输出中,找到以
AZURE_MYSQL_
和AZURE_REDIS_
. 开头的应用设置。 仅显示设置名称。 它们在 AZD 的输出中呈现如下:App Service app has the following app settings: - AZURE_KEYVAULT_RESOURCEENDPOINT - AZURE_KEYVAULT_SCOPE - AZURE_MYSQL_DBNAME - AZURE_MYSQL_FLAG - AZURE_MYSQL_HOST - AZURE_MYSQL_PASSWORD - AZURE_MYSQL_PORT - AZURE_MYSQL_USERNAME - AZURE_REDIS_DATABASE - AZURE_REDIS_HOST - AZURE_REDIS_PASSWORD - AZURE_REDIS_PORT - AZURE_REDIS_SSL
开头
AZURE_MYSQL_
的设置是 MySQL 数据库的连接变量,开头AZURE_REDIS_
的设置是 Redis 缓存的设置。 稍后需要在代码中使用它们。 为方便起见,AZD 模板会显示 Azure 门户中应用的应用设置页的直接链接。从资源管理器中,打开 config/database.php。 这是数据库和 Redis 缓存连接的配置文件。
找到定义
mysql
连接(第46至64行)的部分,并将DB_HOST
、DB_PORT
、DB_DATABASE
、DB_USERNAME
和DB_PASSWORD
替换为来自AZD输出的AZURE_MYSQL_
应用设置。 连接mysql
应类似于以下代码。'mysql' => [ 'driver' => 'mysql', 'url' => env('DATABASE_URL'), 'host' => env('AZURE_MYSQL_HOST', '127.0.0.1'), 'port' => env('AZURE_MYSQL_PORT', '3306'), 'database' => env('AZURE_MYSQL_DBNAME', 'forge'), 'username' => env('AZURE_MYSQL_USERNAME', 'forge'), 'password' => env('AZURE_MYSQL_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'prefix_indexes' => true, 'strict' => true, 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), ]) : [], ],
有关 Laravel 中的数据库配置的详细信息,请参阅 Laravel 文档。
找到定义 Redis 缓存连接(第 140-147 行)的部分,并用 AZD 输出中的
REDIS_HOST
应用设置替换REDIS_PASSWORD
、REDIS_PORT
、REDIS_CACHE_DB
和Azure_REDIS_
。 此外,请将'scheme' => 'tls',
添加到连接中。 缓存连接应类似于以下代码:'cache' => [ 'scheme' => 'tls', 'url' => env('REDIS_URL'), 'host' => env('AZURE_REDIS_HOST', '127.0.0.1'), 'username' => env('REDIS_USERNAME'), 'password' => env('AZURE_REDIS_PASSWORD'), 'port' => env('AZURE_REDIS_PORT', '6379'), 'database' => env('AZURE_REDIS_DATABASE', '1'), ],
有关 Laravel 中的 Redis 缓存配置的详细信息,请参阅 Laravel 文档。
备注
请记住,你的更改尚未部署。 在下一步结束时,将部署更改。
在资源管理器中打开 infra/resources.bicep。 这是定义创建的 Azure 资源的 Bicep 模板文件。
找到定义应用设置的部分(第 510 到 514 行),然后取消注释。 这些应用设置包括:
设置 DESCRIPTION CACHE_DRIVER
告知 Laravel 使用 Redis 作为其缓存(请参阅 Laravel 文档)。 MYSQL_ATTR_SSL_CA
需要在 Azure 中打开与 MySQL 的 TLS 连接。 为了方便起见,证书文件包含在示例存储库中。 此变量由 config/database.php 中的 mysql 连接使用 LOG_CHANNEL
告知 Laravel 通过管道将日志传递给 stderr
,这使它可用于应用服务日志(请参阅 Laravel 文档)。APP_DEBUG
在 Laravel 中启用调试模式页面(请参阅 Laravel 文档)。 APP_KEY
Laravel 加密变量。 AZD 模板已经创建了 Key Vault 密钥(第 212-217 行),因此可以通过 Key Vault 引用来访问它。 在 infra/resources.bicep 中,查找应用服务应用的资源定义并取消注释第 315 行:
appCommandLine: 'cp /home/site/wwwroot/default /etc/nginx/sites-available/default && service nginx reload'
Laravel 应用程序生命周期 从 /public 目录中开始,而不是应用程序根目录。 应用服务的默认 PHP 容器使用 Nginx,该容器在应用程序根目录中启动。 若要更改站点根路径,需要在 PHP 容器中更改 Nginx 配置文件 (/etc/nginx/sites-available/default)。 为方便起见,示例存储库包含名为 default 的替换配置文件,它告知 Nginx 在 /public 目录中查找。 每次应用启动时,
appCommandLine
中的此自定义命令都会运行,以便在从干净状态重新加载 Linux 容器时应用文件替换。返回 codespace 终端,再次运行
azd up
。azd up
提示
azd up
、azd package
、azd provision
和 azd deploy
一起运行,这很合理,因为你正在进行基础设施和应用程序的更改。 若要仅进行基础结构更改,请运行 azd provision
。 若要仅将更改部署到应用程序代码,请运行 azd deploy
。
遇到问题? 检查故障排除部分。
使用受虚拟网络保护的 MySQL 数据库,运行 Laravel 数据库迁移的最简单方法是在应用服务中与 Linux 容器建立 SSH 会话。
在 AZD 输出中,找到 SSH 会话的 URL,并在浏览器中导航到该 URL。 它在输出中看起来像这样:
Open SSH session to App Service container at: https://<app-name>-<hash>.scm.chinacloudsites.cn/webssh/host
在 SSH 会话中,从 /home/site/wwwroot 目录运行数据库迁移:
cd /home/site/wwwroot php artisan migrate --force
如果该命令成功,则应用服务会成功连接到数据库。
备注
只有对 /home
中文件的更改才能在应用重启之后持久保存。
遇到问题? 检查故障排除部分。
在 AZD 输出中,找到应用的 URL 并在浏览器中导航到该 URL。 该 URL 在 AZD 输出中如下所示:
Deploying services (azd deploy) (✓) Done: Deploying service web - Endpoint: https://<app-name>-<hash>.chinacloudsites.cn/
将一些任务添加到列表。
恭喜,你已在 Azure 应用服务中运行了一个 Web 应用,并安全连接到了 Azure Database for MySQL。
遇到问题? 检查故障排除部分。
Azure 应用服务捕获已记录到控制台的所有消息,以帮助你诊断应用程序的问题。 为方便起见,AZD 模板已启用对本地文件系统的日志记录以及将日志传送到 Log Analytics 工作区。
示例应用在其每个终结点中输出控制台日志消息,以演示此功能。 默认情况下,Laravel 的日志记录功能(例如 Log::info()
)会输出到本地文件。 之前的 LOG_CHANNEL
应用设置使日志条目可从应用服务日志流访问。
Route::get('/', function () {
Log::info("Get /");
$startTime = microtime(true);
// Simple cache-aside logic
if (Cache::has('tasks')) {
$data = Cache::get('tasks');
} else {
$data = Task::orderBy('created_at', 'asc')->get();
Cache::add('tasks', $data);
}
return view('tasks', ['tasks' => $data, 'elapsed' => microtime(true) - $startTime]);
});
在 AZD 输出中,找到流式传输应用服务日志的链接,并在浏览器中导航到该链接。 该链接在 AZD 输出中如下所示:
Stream App Service logs at: https://portal.azure.cn/#@/resource/subscriptions/<subscription-guid>/resourceGroups/<group-name>/providers/Microsoft.Web/sites/<app-name>/logStream
遇到问题? 检查故障排除部分。
若要删除当前部署环境中的所有 Azure 资源,请运行 azd down
并按照提示进行操作。
azd down
在数据库迁移过程中出现错误 php_network_getaddresses: getaddrinfo for mysqldb failed: No address associated with hostname...
它指示未正确配置 MySQL 连接变量。 验证 AZURE_MYSQL_
是否已在 3 中正确配置应用设置。在应用程序代码中使用 Azure 连接字符串。
它指示应用服务在 /public 中找不到 PHP 启动文件。 按照 4. 在 Web 应用中配置 Laravel 设置 中的步骤进行。
它表明 APP_KEY
被设置为无效键。 运行 azd up
时,请确保将 appKey
设置为 php artisan key:generate --show
的输出。
此错误和类似的错误表示之前未运行composer install
azd up
,或者 /vendor 目录中的包已过时。 运行composer install
和azd deploy
再次。
我在浏览器中获得了一个显示为php_network_getaddresses: getaddrinfo for redishost failed: Name or service not known.
的调试页面。
它指示未正确配置 Redis 连接变量。 验证 AZURE_REDIS_
是否已在 3 中正确配置应用设置。在应用程序代码中使用 Azure 连接字符串。
我在浏览器中获得了一个显示为SQLSTATE[42S02]: Base table or view not found: 1146 Table 'XXXX-XXXXXXXXX-mysql-database.tasks' doesn't exist
的调试页面。
这意味着你尚未运行数据库迁移,或者数据库迁移未成功。 按照步骤 5 生成数据库架构的指引进行操作。
创建资源的定价如下所示:
- 应用服务计划创建在基本层,可以向上或向下扩展。 请参阅应用服务定价。
- MySQL 灵活服务器是在 B1ms 层中创建的,可以纵向扩展或缩减。 使用 Azure 试用版时,B1ms 层免费 12 个月,最高可达每月限额。 查看 Azure Database for MySQL 的定价。
- Azure Cache for Redis 是在缓存大小最小的基本层中创建的。 此层的相关成本很低。 你可将其纵向扩展到更高的性能层,以实现更高的可用性、聚类分析和其他功能。 请参阅 Azure Cache for Redis 定价。
- 除非配置额外的功能(例如对等互连),否则虚拟网络不会产生费用。 请参阅 Azure 虚拟网络定价。
- 专用 DNS 区域会产生少量费用。 请参阅 Azure DNS 定价。
- 要从命令行工具进行基本访问,可以从应用的 SSH 终端运行
mysql
。 - 若要从 MySQL Workbench 等桌面工具进行连接,计算机必须位于虚拟网络中。 例如,它可以是连接到其中一个子网的 Azure VM,也可以是与 Azure 虚拟网络建立了站点到站点 VPN 连接的本地网络中的计算机。
以应用服务自动生成的工作流文件为例,每个 git push
文件都会启动新的生成和部署运行。 从 GitHub 存储库的本地克隆中,将所需的更新推送到 GitHub。 例如:
git add .
git commit -m "<some-message>"
git push origin main
应用服务自动生成的工作流文件定义了先构建后部署的两步作业运行。 由于每个作业都在其自己的干净环境中运行,因此工作流文件可确保 deploy
作业能够访问 build
作业中的文件。
- 在
build
作业结束时,将文件上传为项目。 - 在
deploy
作业开始时,下载项目。
两个作业过程的大部分时间都是花费在上传和下载项目上。 如果需要,可以通过将这两个作业合并为一个作业来简化工作流文件,省去了上传和下载步骤。
请继续学习下一教程,了解如何使用自定义域和证书保护应用。
或者,查看其他资源: