This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Download Microsoft Edge
More info about Internet Explorer and Microsoft Edge
APPLIES TO:
Azure Database for 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.
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
Prerequisites
An Azure subscription If you don't have an Azure subscription, create an
Azure free account
before you begin.
With an Azure free account, you can now try Azure Database for MySQL - Flexible Server for free for 12 months. For more information, see
Try Flexible Server for free
.
Sample application
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
, and DB_PASSWORD
) using settings in your local MySQL database. You need a local MySQL server 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
1 - Create App Service and MySQL resources
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
In the Azure portal:
Enter "web app database" in the search bar at the top of the Azure portal.
Select the item labeled Web App + Database under the Marketplace heading.
You can also navigate to the creation wizard directly.
In the Create Web App + Database page, fill out the form as follows.
Resource Group → Select Create new and use a name of msdocs-laravel-mysql-tutorial.
Region → Any Azure region near you.
Name → msdocs-laravel-mysql-XYZ where XYZ is any three random characters. This name must be unique across Azure.
Runtime stack → PHP 8.0.
MySQL - Flexible Server is selected for you by default as the database engine. Azure Database for MySQL is a fully managed MySQL database as a service on Azure, compatible with the latest community editions.
Note the database name that's generated for you (<app-name>-database). You'll need it later.
Click Review + create.
After validation completes, click Create.
The deployment takes a few minutes to complete, and creates the following resources:
Resource group → The container for all the created resources.
App Service plan → Defines the compute resources for App Service. A Linux plan in the P1v2 tier is created.
App Service → Represents your app and runs in the App Service plan.
Virtual network → Integrated with the App Service app and isolates back-end network traffic.
Azure Database for MySQL - Flexible Server → Accessible only from the virtual network. A database and a user are created for you on the server.
Private DNS zone → Enables DNS resolution of the MySQL database server in the virtual network.
Once deployment completes, click the Go to resource button. You're taken directly to the App Service app.
In the Application settings tab of the Configuration page, create a DB_DATABASE
setting:
Click New application setting.
In the Name field, enter DB_DATABASE.
In the Value field, enter the automatically generated database name from the creation wizard, which looks like msdocs-docs-laravel-mysql-XYZ-database.
Click OK.
Back in the Application settings tab:
Scroll to the bottom and select the connection string defaultConnection. It was generated by the creation wizard and contains the username and password you need.
In the Value field, select the Copy button and paste the value in a text file for later. It's in the following format (line breaks for clarity):
Database=mysql;
Server=<database-server-domain-name>;
User Id=<username>;
Password=<password>
Select Cancel.
Create the following extra app settings by following the same steps for creating an app setting.
DB_HOST: Use the <database-server-domain-name> from the copied connection string as the value.
DB_USERNAME: Use the <username> from the copied connection string as the value.
DB_PASSWORD: Use the <password> from the copied connection string as the value.
MYSQL_ATTR_SSL_CA: Use /home/site/wwwroot/ssl/DigiCertGlobalRootCA.crt.pem as the value.
This app setting points to the path of the TLS/SSL certificate you need to access the MySQL server. It's included in the sample repository for convenience.
APP_DEBUG: Use true as the value. This is a Laravel debugging variable.
APP_KEY: Use base64:Dsz40HWwbCqnq0oxMsjq7fItmKIeBfCBGORfspaI1Kw= as the value. This is a Laravel encryption variable.
Important
This APP_KEY
value is used here for convenience. For production scenarios, it should be generated specifically for your deployment using php artisan key:generate --show
in the command line.
3 - Deploy sample code
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
Sign in to your GitHub account.
Navigate to https://github.com/Azure-Samples/laravel-tasks.
Click Fork.
Click Create fork.
In the Deployment Center page:
In Source, select GitHub. By default, GitHub Actions is selected as the build provider.
Sign in to your GitHub account and follow the prompt to authorize Azure.
In Organization, select your account.
In Repository, select laravel-tasks.
In Branch, select main.
In the top menu, click Save.
App Service commits a workflow file into the selected GitHub repository, in the .github/workflows
directory.
Select Logs. A deployment run is already started.
In the log item for the deployment run, select Build/Deploy Logs.
You're taken to your GitHub repository and see that the GitHub action is running. The workflow file defines two separate stages, build and deploy.
To make any changes to your code, go to Visual Studio Code in the browser:
Select the Source Control extension.
Next to the changed file, for example database.php, select + to stage your changes.
In the textbox, type a commit message, for example add certificate
.
Select the checkmark to commit and push to GitHub.
If you go back to the Deployment Center page, you'll see a new log entry because another run is started. Wait for the run to complete. It takes about 15 minutes.
The GitHub action is defined by the file in your GitHub repository, in .github/workflow. You can make it faster by customizing the file.
4 - Generate database schema
The creation wizard puts the MySQL database server 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
5 - Change site root
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
In the General settings tab:
In the Startup Command box, enter the following command: cp /home/site/wwwroot/default /etc/nginx/sites-available/default && service nginx reload.
It replaces the Nginx configuration file in the PHP 8.0 container and restarts Nginx. This configuration ensures that this change is made to the container each time it starts.
Select Save.
How much does this setup cost?
How do I connect to the MySQL database that's secured behind the virtual network with other tools?
How does local app development work with GitHub Actions?
Why is the GitHub Actions deployment so slow?
How much does this setup cost?
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 MySQL flexible server 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 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.
For basic access from a commmand-line tool, you can run mysql
from the app's SSH terminal.
To connect from a desktop tool like MySQL Workbench, your machine must be within the virtual network. For example, it could be an Azure VM that's connected to one of the subnets, or a machine in an on-premises network that has a site-to-site VPN connection with the Azure virtual network.
You can also integrate Azure Cloud Shell with the virtual network.
How does local app development work with GitHub Actions?
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
Why is the GitHub Actions deployment so slow?
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.
Summary
In this tutorial, you learned how to:
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
Next steps
Tutorial: Map custom DNS name to your app
How to manage your resources in Azure portal
How to manage your server