title | description | author | ms.author | ms.reviewer | ms.date | ms.service | ms.subservice | ms.topic | ms.custom | ms.devlang | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Tutorial: Build a PHP (Laravel) app on Azure App Service |
This tutorial explains how to build and deploy a PHP Laravel app with Azure Database for MySQL - Flexible Server, secured within a VNet. |
shreyaaithal |
shaithal |
maghan |
06/18/2024 |
mysql |
flexible-server |
tutorial |
|
php |
Tutorial: Build a PHP (Laravel) and Azure Database for MySQL - Flexible Server app on Azure App Service
[!INCLUDEapplies-to-mysql-flexible-server]
Azure App Service provides a highly scalable, self-patching web hosting service using the Linux operating system. This tutorial shows how to create a secure PHP app in Azure App Service that's connected to a MySQL database (using Azure Database for MySQL flexible server). When you're finished, you'll have a Laravel app running on Azure App Service on Linux.
:::image type="content" source="./media/tutorial-php-database-app/azure-portal-browse-app-2.png" alt-text="Screenshot of the Azure app example titled Task List showing new tasks added.":::
In this tutorial, you learn how to:
[!div class="checklist"]
- Create a secure-by-default PHP and MySQL app in Azure
- Configure connection secrets to MySQL using app settings
- Deploy application code using GitHub Actions
- Update and redeploy the app
- Run database migrations securely
- Stream diagnostic logs from Azure
- Manage the app in the Azure portal
- An Azure subscription [!INCLUDE flexible-server-free-trial-note]
To follow along with this tutorial, clone or download the sample application from the repository:
git clone https://github.com/Azure-Samples/laravel-tasks.git
If you want to run the application locally, do the following:
-
In .env, configure the database settings (like
DB_DATABASE
,DB_USERNAME
, andDB_PASSWORD
) using settings in your local Azure Database for MySQL flexible server database. You need a local Azure Database for MySQL flexible server instance to run this sample. -
From the root of the repository, start Laravel with the following commands:
composer install php artisan migrate php artisan key:generate php artisan serve
In this step, you create the Azure resources. The steps used in this tutorial create an App Service and Azure Database for MySQL flexible server configuration that's secure by default. For the creation process, you'll specify:
- The Name for the web app. It's the name used as part of the DNS name for your webapp in the form of
https://<app-name>.azurewebsites.net
. - The Runtime for the app. It's where you select the version of PHP to use for your app.
- The Resource Group for the app. A resource group lets you group (in a logical container) all the Azure resources needed for the application.
Sign in to the Azure portal and follow these steps to create your Azure App Service resources.
Instructions | Screenshot |
---|---|
[!INCLUDE Create app service step 1] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-create-app-mysql-1-240px.png" alt-text="A screenshot showing how to use the search box in the top tool bar to find the Web App + Database creation wizard." lightbox="./media/tutorial-php-database-app/azure-portal-create-app-mysql-1.png"::: |
[!INCLUDE Create app service step 2] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-create-app-mysql-2-240px.png" alt-text="A screenshot showing how to configure a new app and database in the Web App + Database wizard." lightbox="./media/tutorial-php-database-app/azure-portal-create-app-mysql-2.png"::: |
[!INCLUDE Create app service step 3] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-create-app-mysql-3-240px.png" alt-text="A screenshot showing the form to fill out to create a web app in Azure." lightbox="./media/tutorial-php-database-app/azure-portal-create-app-mysql-3.png"::: |
The creation wizard generated app settings for you to use to connect to the database, but not in a format that's useable for your code yet. In this step, you edit and update app settings to the format that your app needs.
Instructions | Screenshot |
---|---|
[!INCLUDE Get connection string step 1] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-get-connection-string-1-240px.png" alt-text="A screenshot showing how to open the configuration page in App Service." lightbox="./media/tutorial-php-database-app/azure-portal-get-connection-string-1.png"::: |
[!INCLUDE Get connection string step 2] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-get-connection-string-2-240px.png" alt-text="A screenshot showing how to see the autogenerated connection string." lightbox="./media/tutorial-php-database-app/azure-portal-get-connection-string-2.png"::: |
[!INCLUDE Get connection string step 3] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-get-connection-string-3-240px.png" alt-text="A screenshot showing how to create an app setting." lightbox="./media/tutorial-php-database-app/azure-portal-get-connection-string-3.png"::: |
[!INCLUDE Get connection string step 4] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-get-connection-string-4-240px.png" alt-text="A screenshot showing all the required app settings in the configuration page." lightbox="./media/tutorial-php-database-app/azure-portal-get-connection-string-4.png"::: |
In this step, you'll configure GitHub deployment using GitHub Actions. It's just one of many ways to deploy to App Service, but also a great way to have continuous integration in your deployment process. By default, every git push
to your GitHub repository will kick off the build and deploy action. You'll make some changes to your codebase with Visual Studio Code directly in the browser, then let GitHub Actions deploy automatically for you.
Instructions | Screenshot |
---|---|
[!INCLUDE Deploy sample code step 1] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-deploy-sample-code-1-240px.png" alt-text="A screenshot showing how to create a fork of the sample GitHub repository." lightbox="./media/tutorial-php-database-app/azure-portal-deploy-sample-code-1.png"::: |
[!INCLUDE Deploy sample code step 2] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-deploy-sample-code-2-240px.png" alt-text="A screenshot showing how to open the Visual Studio Code browser experience in GitHub." lightbox="./media/tutorial-php-database-app/azure-portal-deploy-sample-code-2.png"::: |
[!INCLUDE Deploy sample code step 3] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-deploy-sample-code-3-240px.png" alt-text="A screenshot showing Visual Studio Code in the browser and an opened file." lightbox="./media/tutorial-php-database-app/azure-portal-deploy-sample-code-3.png"::: |
[!INCLUDE Deploy sample code step 4] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-deploy-sample-code-4-240px.png" alt-text="A screenshot showing how to open the deployment center in App Service." lightbox="./media/tutorial-php-database-app/azure-portal-deploy-sample-code-4.png"::: |
[!INCLUDE Deploy sample code step 5] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-deploy-sample-code-5-240px.png" alt-text="A screenshot showing how to configure CI/CD using GitHub Actions." lightbox="./media/tutorial-php-database-app/azure-portal-deploy-sample-code-5.png"::: |
[!INCLUDE Deploy sample code step 6] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-deploy-sample-code-6-240px.png" alt-text="A screenshot showing how to open deployment logs in the deployment center." lightbox="./media/tutorial-php-database-app/azure-portal-deploy-sample-code-6.png"::: |
[!INCLUDE Deploy sample code step 7] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-deploy-sample-code-7-240px.png" alt-text="A screenshot showing how to commit your changes in the Visual Studio Code browser experience." lightbox="./media/tutorial-php-database-app/azure-portal-deploy-sample-code-7.png"::: |
The creation wizard puts the Azure Database for MySQL flexible server instance behind a private endpoint, so it's accessible only from the virtual network. Because the App Service app is already integrated with the virtual network, the easiest way to run database migrations with your database is directly from within the App Service container.
Instructions | Screenshot |
---|---|
[!INCLUDE Generate database schema step 1] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-generate-db-schema-1-240px.png" alt-text="A screenshot showing how to open the SSH shell for your app from the Azure portal." lightbox="./media/tutorial-php-database-app/azure-portal-generate-db-schema-1.png"::: |
[!INCLUDE Generate database schema step 2] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-generate-db-schema-2-240px.png" alt-text="A screenshot showing the commands to run in the SSH shell and their output." lightbox="./media/tutorial-php-database-app/azure-portal-generate-db-schema-2.png"::: |
Laravel application lifecycle begins in the /public directory instead. The default PHP 8.0 container for App Service uses Nginx, which starts in the application's root directory. To change the site root, you need to change the Nginx configuration file in the PHP 8.0 container (/etc/nginx/sites-available/default). For your convenience, the sample repository contains a custom configuration file called default. As noted previously, you don't want to replace this file using the SSH shell, because your changes will be lost after an app restart.
Instructions | Screenshot |
---|---|
[!INCLUDE Change site root step 1] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-change-site-root-1-240px.png" alt-text="A screenshot showing how to open the general settings tab in the configuration page of App Service." lightbox="./media/tutorial-php-database-app/azure-portal-change-site-root-1.png"::: |
[!INCLUDE Change site root step 2] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-change-site-root-2-240px.png" alt-text="A screenshot showing how to configure a startup command in App Service." lightbox="./media/tutorial-php-database-app/azure-portal-change-site-root-2.png"::: |
Instructions | Screenshot |
---|---|
[!INCLUDE Browse to app step 1] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-browse-app-1-240px.png" alt-text="A screenshot showing how to launch an App Service from the Azure portal." lightbox="./media/tutorial-php-database-app/azure-portal-browse-app-1.png"::: |
[!INCLUDE Browse to app step 2] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-browse-app-2-240px.png" alt-text="A screenshot of the Laravel app running in App Service." lightbox="./media/tutorial-php-database-app/azure-portal-browse-app-2.png"::: |
Instructions | Screenshot |
---|---|
[!INCLUDE Stream diagnostic logs step 1] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-stream-diagnostic-logs-1-240px.png" alt-text="A screenshot showing how to enable native logs in App Service in the Azure portal." lightbox="./media/tutorial-php-database-app/azure-portal-stream-diagnostic-logs-1.png"::: |
[!INCLUDE Stream diagnostic logs step 2] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-stream-diagnostic-logs-2-240px.png" alt-text="A screenshot showing how to view the log stream in the Azure portal." lightbox="./media/tutorial-php-database-app/azure-portal-stream-diagnostic-logs-2.png"::: |
When you're finished, you can delete all of the resources from your Azure subscription by deleting the resource group.
Instructions | Screenshot |
---|---|
[!INCLUDE Remove resource group Azure portal 1] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-clean-up-resources-1-240px.png" alt-text="A screenshot showing how to search for and navigate to a resource group in the Azure portal." lightbox="./media/tutorial-php-database-app/azure-portal-clean-up-resources-1.png"::: |
[!INCLUDE Remove resource group Azure portal 2] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-clean-up-resources-2-240px.png" alt-text="A screenshot showing the location of the Delete Resource Group button in the Azure portal." lightbox="./media/tutorial-php-database-app/azure-portal-clean-up-resources-2.png"::: |
[!INCLUDE Remove resource group Azure portal 3] | :::image type="content" source="./media/tutorial-php-database-app/azure-portal-clean-up-resources-3-240px.png" alt-text="A screenshot of the confirmation dialog for deleting a resource group in the Azure portal." lightbox="./media/tutorial-php-database-app/azure-portal-clean-up-resources-3.png"::: |
- How much does this setup cost?
- How do I connect to an Azure Database for MySQL flexible server database that's secured behind a virtual network?
- How does local app development work with GitHub Actions?
- Why is the GitHub Actions deployment so slow?
Pricing for the create resources is as follows:
- The App Service plan is created in Premium V2 tier and can be scaled up or down. See App Service pricing.
- The Azure Database for MySQL flexible server instance is created in B1ms tier and can be scaled up or down. With an Azure free account, B1ms tier is free for 12 months, up to the monthly limits. See Azure Database for MySQL flexible server pricing.
- The virtual network doesn't incur a charge unless you configure extra functionality, such as peering. See Azure Virtual Network pricing.
- The private DNS zone incurs a small charge. See Azure DNS pricing.
How do I connect to an Azure Database for MySQL flexible server database that's secured behind a virtual network?
To connect to an Azure Database for MySQL flexible server database, you can use several methods based on the tools and environments at your disposal:
- Command-line tool access:
- Use the
mysql
command from the app's SSH terminal for basic access.
- Use the
- Desktop tools (for example, MySQL Workbench):
- Using SSH tunneling with Azure CLI:
- Create an SSH session to the web app by using the Azure CLI.
- Use the SSH session to tunnel the traffic to MySQL.
- Using site-to-site VPN or Azure VM:
- Your machine must be part of the virtual network.
- Consider using:
- An Azure VM linked to one of the subnets.
- A machine in an on-premises network that has a site-to-site VPN connection to the Azure virtual network.
- Using SSH tunneling with Azure CLI:
- Azure Cloud Shell integration:
- Integrate Azure Cloud Shell with the virtual network for direct access.
Take the autogenerated workflow file from App Service as an example, each git push
kicks off a new build and deployment run. From a local clone of the GitHub repository, you make the desired updates push it to GitHub. For example:
git add .
git commit -m "<some-message>"
git push origin main
The autogenerated workflow file from App Service defines build-then-deploy, two-job run. Because each job runs in its own clean environment, the workflow file ensures that the deploy
job has access to the files from the build
job:
- At the end of the
build
job, upload files as artifacts. - At the beginning of the
deploy
job, download the artifacts.
Most of the time taken by the two-job process is spent uploading and download artifacts. If you want, you can simplify the workflow file by combining the two jobs into one, which eliminates the need for the upload and download steps.
In this tutorial, you learned how to:
[!div class="checklist"]
- Create a secure-by-default PHP and Azure Database for MySQL flexible server app in Azure
- Configure connection secrets to Azure Database for MySQL flexible server using app settings
- Deploy application code using GitHub Actions
- Update and redeploy the app
- Run database migrations securely
- Stream diagnostic logs from Azure
- Manage the app in the Azure portal
[!div class="nextstepaction"] Tutorial: Map custom DNS name to your app [!div class="nextstepaction"] How to manage your resources in Azure portal [!div class="nextstepaction"] How to manage your server