Tutorial: Compilación de una aplicación PHP (Laravel) y de servidor flexible de MySQL en Azure App Service
[SE APLICA A:
Azure Database for MySQL: Servidor flexible
Azure App Service proporciona un servicio de hospedaje web muy escalable y con aplicación automática de revisiones con el sistema operativo Linux. En este tutorial, se muestra cómo crear una aplicación PHP en Azure y conectarla a una base de datos MySQL. Cuando haya terminado, tendrá una aplicación de Laravel que se ejecuta en Azure App Service en Linux.
En este tutorial, aprenderá a:
- Configurar una aplicación PHP (Laravel) con MySQL local
- Creación de un servidor flexible MySQL
- Conexión de una aplicación PHP al servidor flexible de MySQL
- Implementar la aplicación en Azure App Service
- Actualizar el modelo de datos y volver a implementar la aplicación
- Administrar la aplicación en Azure Portal
Si no tiene una suscripción a Azure, cree una cuenta gratuita de Azure antes de empezar. Con una cuenta gratuita de Azure, ahora puede probar Azure Database for MySQL: servidor flexible de forma gratuita durante 12 meses. Para más información, consulte Prueba gratuita de un servidor flexible.
Prerrequisitos
Para completar este tutorial:
- Instalación de Git
- Instalación de PHP 5.6.4, o cualquier versión posterior
- Instalación de Composer
- Habilite las siguientes extensiones de PHP que Laravel necesita: OpenSSL, PDO-MySQL, Mbstring, Tokenizer, XML
- Instalación e inicio de MySQL
Preparación de MySQL local
En este paso, creará una base de datos en el servidor MySQL local para usarlo en este tutorial.
Conexión a un servidor MySQL local
En una ventana de terminal, conéctese al servidor MySQL local. Esta ventana de terminal se puede usar para ejecutar todos los comandos de este tutorial.
mysql -u root -p
Si se le pide una contraseña, escriba la de la cuenta root. Si no recuerda la contraseña de la cuenta raíz, consulte MySQL: How to Reset the Root Password (MySQL: Instrucciones de restablecimiento de la contraseña de la cuenta raíz).
Si el comando se ejecuta correctamente, significa que el servidor MySQL está en ejecución. De lo contrario, siga los pasos posteriores a la instalación de MySQL para asegurarse de iniciar el servidor local de MySQL.
Creación de una base de datos local
En el símbolo del sistema de mysql, cree una base de datos.
CREATE DATABASE sampledb;
Escriba quit para salir de la conexión del servidor.
quit
Creación de una aplicación PHP local
En este paso, obtendrá una aplicación Laravel de ejemplo, configurará la conexión a base de datos correspondiente y la ejecutará de forma local.
Clonación del ejemplo
En la ventana de terminal, vaya a un directorio vacío en el que pueda clonar la aplicación de ejemplo. Ejecute el comando siguiente para clonar el repositorio de ejemplo.
git clone https://github.com/Azure-Samples/laravel-tasks
cd en el directorio clonado.
Instale los paquetes requeridos.
cd laravel-tasks
composer install
Configuración de la conexión a MySQL
En la raíz del repositorio, cree un archivo llamado .env. Copie las siguientes variables en el archivo .env. Reemplace el marcador de posición <root_password> por la contraseña del usuario raíz de MySQL.
APP_ENV=local
APP_DEBUG=true
APP_KEY=
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=sampledb
DB_USERNAME=root
DB_PASSWORD=<root_password>
Para obtener información sobre la forma en que Laravel usa el archivo .env, consulte Laravel Environment Configuration (Configuración del entorno de Laravel).
Ejecución local del código
Ejecute las migraciones de la base de datos Laravel para crear las tablas que necesita la aplicación. Para ver qué tablas se crean en las migraciones, mire en el directorio database/migrations del repositorio de Git.
php artisan migrate
Genere una nueva clave de aplicación Laravel.
php artisan key:generate
Ejecute la aplicación.
php artisan serve
Vaya a http://localhost:8000 en un explorador. Agregue algunas tareas a la página.
Para detener PHP, escriba Ctrl + C en el terminal.
Creación de un servidor flexible MySQL
En este paso, creará una base de datos MySQL en Azure Database for MySQL: servidor flexible. Posteriormente, configurará la aplicación PHP para que se conecte a esta base de datos. En Azure Cloud Shell, cree un servidor mediante el comando az flexible-server create.
az mysql flexible-server create --resource-group myResourceGroup --public-access <IP-Address>
Importante
- Tome nota del nombre del servidor y la cadena de conexión para usarlos en el paso siguiente para conectarse y ejecutar la migración de datos de Laravel.
- En el argumento IP-Address, proporcione la dirección IP del equipo cliente. El servidor se bloquea cuando se crea y es necesario que permita el acceso a su equipo cliente para administrar el servidor de forma local.
Configuración del firewall del servidor para permitir que la aplicación web se conecte al servidor
En Cloud Shell, cree una regla de firewall para que el servidor MySQL permita conexiones de clientes con el comando az mysql server firewall-rule create. Cuando la dirección IP inicial y la dirección IP final se establecen en 0.0.0.0, el firewall solo se habilita para otros servicios de Azure que no tienen una dirección IP estática para conectarse al servidor.
az mysql flexible-server firewall-rule create --name allanyAzureIPs --server <mysql-server-name> --resource-group myResourceGroup --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
Conexión al servidor MySQL de producción local
En la ventana del terminal local, conéctese al servidor MySQL de Azure. Use el valor que especificó anteriormente para <admin-user> y <mysql-server-name>. Cuando se le solicite una contraseña, utilice la contraseña que especificó al crear la base de datos en Azure.
mysql -u <admin-user> -h <mysql-server-name>.mysql.database.azure.com -P 3306 -p
Creación de una base de datos de producción
En el símbolo del sistema de mysql, cree una base de datos.
CREATE DATABASE sampledb;
Creación de un usuario con permisos
Cree un usuario de base de datos denominado phpappuser y concédale todos los privilegios de la base de datos sampledb. Para simplificar el tutorial, use MySQLAzure2020 como contraseña.
CREATE USER 'phpappuser' IDENTIFIED BY 'MySQLAzure2020';
GRANT ALL PRIVILEGES ON sampledb.* TO 'phpappuser';
Escriba quit para salir de la conexión del servidor.
quit
Conexión de una aplicación PHP a un servidor flexible de MySQL
En este paso, conectará la aplicación PHP a la base de datos MySQL que creó en Azure Database for MySQL.
Configuración de la conexión de base de datos
En la raíz del repositorio, cree un archivo .env.production y copie en él las siguientes variables. Reemplace el marcador de posición <mysql-server-name> en DB_HOST y DB_USERNAME.
APP_ENV=production
APP_DEBUG=true
APP_KEY=
DB_CONNECTION=mysql
DB_HOST=<mysql-server-name>.mysql.database.azure.com
DB_DATABASE=sampledb
DB_USERNAME=phpappuser
DB_PASSWORD=MySQLAzure2017
MYSQL_SSL=true
Guarde los cambios.
Sugerencia
Para proteger la información de conexión de MySQL, este archivo ya se ha excluido del repositorio de Git (vea .gitignore en la raíz del repositorio). Más adelante, aprenderá a configurar variables de entorno en App Service para conectarse a la base de datos en Azure Database for MySQL. Con las variables de entorno, no es preciso el archivo .env en App Service.
Configuración del certificado TLS/SSL
De manera predeterminada, el servidor flexible de MySQL aplica las conexiones TLS de los clientes. Para conectarse a la base de datos MySQL en Azure, debe usar el certificado .pem proporcionado por el servidor flexible de Azure Database for MySQL. Descargue este certificado) y colóquelo en la carpeta SSL de la copia local del repositorio de la aplicación de ejemplo.
Abra config/database.php y agregue los parámetros sslmode y options a connections.mysql, como se muestra en el código siguiente.
'mysql' => [
...
'sslmode' => env('DB_SSLMODE', 'prefer'),
'options' => (env('MYSQL_SSL') && extension_loaded('pdo_mysql')) ? [
PDO::MYSQL_ATTR_SSL_KEY => '/ssl/DigiCertGlobalRootCA.crt.pem',
] : []
],
Prueba de la aplicación de forma local
Ejecute migraciones de base de datos Laravel con .env.production como archivo de entorno para crear las tablas de la base de datos MySQL en Azure Database for MySQL. Recuerde que . env.production tiene la información de conexión a su base de datos MySQL de Azure.
php artisan migrate --env=production --force
El archivo .env.production aún no cuenta con una clave de aplicación válida. Genere una nueva para él en el terminal.
php artisan key:generate --env=production --force
Ejecute la aplicación de ejemplo con .env.production como archivo de entorno.
php artisan serve --env=production
Vaya a http://localhost:8000. Si la página se carga sin errores, significa que la aplicación PHP se está conectado a la base de datos MySQL de Azure.
Agregue algunas tareas a la página.
Para detener PHP, escriba Ctrl + C en el terminal.
Confirmación de los cambios
Ejecute los siguientes comandos de Git para confirmar los cambios:
git add .
git commit -m "database.php updates"
La aplicación está lista para implementarse.
Implementar en Azure
En este paso se implementará la aplicación PHP conectada a MySQL en Azure App Service.
Configuración de un usuario de implementación
Se puede implementar FTP y Git local en una aplicación web de Azure mediante un usuario de implementación. Una vez configurado este usuario de implementación, podrá usarlo en todas las implementaciones de Azure. El nombre de usuario y la contraseña en el nivel de cuenta son diferentes de las credenciales de suscripción de Azure.
Para configurar el usuario de implementación, ejecute el comando az webapp deployment user set en Azure Cloud Shell. Reemplace <username> y <password> por su nombre de usuario y contraseña de implementación.
El nombre de usuario debe ser único dentro de Azure y, en el caso de inserciones Git, no debe contener el símbolo "@". La contraseña debe tener al menos ocho caracteres y dos de los tres elementos siguientes: letras, números y símbolos.
az appservice plan create --name myAppServicePlan --resource-group myResourceGroup --sku F1 --is-linux
La salida JSON muestra la contraseña como NULL. Si recibe un error de "conflicto". Detalles: error 409, cambie el nombre de usuario. Si recibe un error de "solicitud incorrecta". Detalles: error 400, use una contraseña más segura. Anote el nombre de usuario y la contraseña que se usarán para implementar las aplicaciones web.
Creación de un plan de App Service
En Cloud Shell, cree un plan de App Service en el grupo de recursos con el comando az appservice plan create. En el ejemplo siguiente se crea un plan de App Service denominado myAppServicePlan en el plan de tarifa Gratis (--sku F1) en un contenedor Linux (--is-linux).
az appservice plan create --name myAppServicePlan --resource-group myResourceGroup --sku F1 --is-linux
Creación de una aplicación web
Cree una aplicación web en el plan de App Service myAppServicePlan.
En Cloud Shell, puede usar el comando az webapp create. En el siguiente ejemplo, reemplace <app-name> por un nombre único global de aplicación (los caracteres válidos son a-z, 0-9 y -). El tiempo de ejecución se establece en PHP|7.0. Para ver todos los runtime admitidos, ejecute az webapp list-runtimes --linux.
az webapp create --resource-group myResourceGroup --plan myAppServicePlan --name <app-name> --runtime "PHP|7.3" --deployment-local-git
Cuando se haya creado la aplicación web, la CLI de Azure mostrará información similar a la del ejemplo siguiente:
Local git is configured with url of 'https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git'
{
"availabilityState": "Normal",
"clientAffinityEnabled": true,
"clientCertEnabled": false,
"cloningInfo": null,
"containerSize": 0,
"dailyMemoryTimeQuota": 0,
"defaultHostName": "<app-name>.azurewebsites.net",
"deploymentLocalGitUrl": "https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git",
"enabled": true,
< JSON data removed for brevity. >
}
Ha creado una nueva aplicación web vacía, con la implementación de Git habilitada.
Nota
La dirección URL del Git remoto se muestra en la propiedad deploymentLocalGitUrl, con el formato https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git. Guarde esta dirección URL, ya que la necesitará más adelante.
Configuración de la base de datos
En App Service, las variables de entorno se establecen como valores de aplicación mediante el comando az webapp config appsettings set.
El siguiente comando permite configurar los valores de aplicación DB_HOST, DB_DATABASE, DB_USERNAME y DB_PASSWORD. Reemplace los marcadores de posición <app-name> y <mysql-server-name> .
az webapp config appsettings set --name <app-name> --resource-group myResourceGroup --settings DB_HOST="<mysql-server-name>.mysql.database.azure.com" DB_DATABASE="sampledb" DB_USERNAME="phpappuser" DB_PASSWORD="MySQLAzure2017" MYSQL_SSL="true"
Para acceder a la configuración puede usar el método getenv de PHP. El código de Laravel usa un contenedor env sobre el elemento getenv de PHP. Por ejemplo, la configuración de MySQL de config/database.php es como el código siguiente:
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
...
],
Configuración de las variables de entorno de Laravel
Laravel necesita una clave de aplicación en App Service. Puede configurarlo con valores de aplicación.
En la ventana del terminal local, use php artisan para generar una clave de aplicación sin guardarla en .env.
php artisan key:generate --show
En Cloud Shell, establezca la clave de aplicación en la aplicación App Service, para lo que hay que usar el comando az webapp config appsettings set. Reemplace los marcadores de posición <app-name> y <outputofphpartisankey:generate> .
az webapp config appsettings set --name <app-name> --resource-group myResourceGroup --settings APP_KEY="<output_of_php_artisan_key:generate>" APP_DEBUG="true"
APP_DEBUG="true" indica a Laravel que devuelva información de depuración si la aplicación implementada encuentra errores. Al ejecutar una aplicación de producción, establézcala en false, que es más seguro.
Establecimiento de la ruta de acceso de la aplicación virtual
El ciclo de vida de la aplicación de Laravel comienza en el directorio public en lugar de en el directorio raíz de la aplicación. La imagen de Docker PHP predeterminada para App Service utiliza Apache y no le permite personalizar DocumentRoot para Laravel. Sin embargo, puede usar .htaccess para volver a escribir todas las solicitudes para que apunten a /public en lugar de al directorio raíz. En la raíz del repositorio, ya se ha agregado .htaccess con este fin. Con él, la aplicación Laravel está preparada para implementarse.
Para más información, consulte Change site root (Cambio de la raíz del sitio).
Inserción en Azure desde Git
En la ventana del terminal local, agregue una instancia remota de Azure al repositorio de Git local. Reemplace <deploymentLocalGitUrl-from-create-step> por la dirección URL del repositorio de Git remoto que guardó en Creación de una aplicación web.
git remote add azure <deploymentLocalGitUrl-from-create-step>
Realice la insercion en la instancia remota de Azure para implementar la aplicación con el comando siguiente. Cuando el Administrador de credenciales de Git le solicite las credenciales, asegúrese de que especifica las que creó en Configuración de un usuario de implementación, no las que se usan para iniciar sesión en Azure Portal.
git push azure main
Este comando puede tardar varios minutos en ejecutarse. Durante la ejecución, muestra información similar a la del ejemplo siguiente:
Counting objects: 3, done. Delta compression using up to 8 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 291 bytes | 0 bytes/s, done. Total 3 (delta 2), reused 0 (delta 0) remote: Updating branch 'main'. remote: Updating submodules. remote: Preparing deployment for commit id 'a5e076db9c'. remote: Running custom deployment command... remote: Running deployment command... ... < Output has been truncated for readability >
Navegación hasta la aplicación de Azure
Vaya a http://<app-name>.azurewebsites.net y agregue algunas tareas a la lista.
Ya está ejecutando una aplicación PHP orientada a datos en Azure App Service.
Actualización local del modelo y nueva implementación
En este paso, se realiza un cambio sencillo en el modelo de datos task y en la aplicación web y, después, se publica la actualización en Azure.
Para el escenario de las tareas, modifique la aplicación de forma que pueda marcar una tarea como completada.
Adición de una columna
En la ventana del terminal local, vaya a la raíz del repositorio de Git.
Generar una migración de base de datos nueva para la tabla tasks:
php artisan make:migration add_complete_column --table=tasks
Este comando muestra el nombre del archivo de migración generado. Busque este archivo en database/migrations y ábralo.
Reemplace el método up por el código siguiente:
public function up()
{
Schema::table('tasks', function (Blueprint $table) {
$table->boolean('complete')->default(False);
});
}
El código anterior agrega una columna booleana a la tabla tasks denominada complete.
Reemplace el método down por el siguiente código para la acción de reversión:
public function down()
{
Schema::table('tasks', function (Blueprint $table) {
$table->dropColumn('complete');
});
}
En la ventana del terminal local, ejecute las migraciones de base de datos Laravel para realizar el cambio en la base de datos local.
php artisan migrate
En función de la convención de nomenclatura de Laravel, el modelo Task (consulte app/Task.php) se asigna a la tabla tasks de manera predeterminada.
Actualización de la lógica de aplicación
Abra el archivo routes/web.php. La aplicación define aquí tanto sus rutas como su lógica de negocios.
Al final del archivo, agregue una ruta con el siguiente código:
/**
* Toggle Task completeness
*/
Route::post('/task/{id}', function ($id) {
error_log('INFO: post /task/'.$id);
$task = Task::findOrFail($id);
$task->complete = !$task->complete;
$task->save();
return redirect('/');
});
El código anterior lleva a cabo una sencilla actualización en el modelo de datos, para lo que alterna el valor de complete.
Actualización de la vista
Abra el archivo resources/views/tasks.blade.php. Busque la etiqueta de apertura <tr> y reemplácela por:
<tr class="{{ $task->complete ? 'success' : 'active' }}" >
El código anterior cambia el color de la fila en función de si la tarea se ha completado.
En la siguiente línea, tiene el siguiente código:
<td class="table-text"><div>{{ $task->name }}</div></td>
Reemplace esta línea al completo por el siguiente código:
<td>
<form action="{{ url('task/'.$task->id) }}" method="POST">
{{ csrf_field() }}
<button type="submit" class="btn btn-xs">
<i class="fa {{$task->complete ? 'fa-check-square-o' : 'fa-square-o'}}"></i>
</button>
{{ $task->name }}
</form>
</td>
El código anterior agrega el botón de envío que hace referencia a la ruta que definió previamente.
Prueba local de los cambios
En la ventana del terminal local, ejecute el servidor de desarrollo desde el directorio raíz del repositorio de Git.
php artisan serve
Para ver cómo cambia el estado de la tarea, navegue hasta http://localhost:8000 y active la casilla.
Para detener PHP, escriba Ctrl + C en el terminal.
Publicación de los cambios en Azure
En la ventana del terminal local, ejecute las migraciones de base de datos Laravel con la cadena de conexión de producción para realizar el cambio en la base de datos de Azure.
php artisan migrate --env=production --force
Confirme todos los cambios en Git y, después, inserte los cambios en el código en Azure.
git add .
git commit -m "added complete checkbox"
git push azure main
Una vez que git push esté completo, vaya a la aplicación de Azure y pruebe la nueva funcionalidad.
Si ha agregado tareas, estas se conservarán en la base de datos. Las actualizaciones que efectúe en el esquema de datos dejan los datos existentes intactos.
Limpieza de recursos
En los pasos anteriores, creó recursos de Azure en un grupo de recursos. Si prevé que no necesitará estos recursos en el futuro, elimine el grupo de recursos ejecutando el siguiente comando en Cloud Shell:
az group delete --name myResourceGroup