Greetings! I'm Aneesh Sreedharan, CEO of 2Hats Logic Solutions. At 2Hats Logic Solutions, we are dedicated to providing technical expertise and resolving your concerns in the world of technology. Our blog page serves as a resource where we share insights and experiences, offering valuable perspectives on your queries.
Developers often face a tough choice between complex deployment solutions and hands-on server management. This blog is for those who don’t want complex infrastructure but still want to benefit from automated code deployment. One of the reasons for creating this guide is that, while there are many resources available for deploying Laravel to Azure App Services or containerized environments like Docker or Kubernetes, there is limited documentation specifically addressing how to deploy a Laravel application directly to Azure Virtual Machines (VMs). Most guides focus on these more managed or containerized environments, which handle much of the server management for you.
However, deploying to an Azure VM offers greater control over your server and software environment, which can be an advantage for teams that don’t need or want to manage more complex infrastructure. By using an Azure DevOps pipeline, you can automate the deployment while still managing the underlying server manually.
In this blog, we aim to fill that gap by providing a step-by-step guide to deploy Laravel applications to Azure VMs using Azure DevOps. This setup gives you a balance between automation and full server control.
Why Deploy with a Compressed Package?
Many deployment guides suggest copying files one by one to the server, which can take up to 30 minutes or longer for large projects. Instead, by compressing the files into a single package (archive) and transferring that package, we reduce the time it takes to deploy your code significantly. Once transferred, the package can be extracted (opened) on the server in just a few seconds. This method keeps things simple and efficient.
Prerequisites
Before getting started, make sure you have the following:
1. Laravel Application: Your Laravel project is ready and stored in a Git repository (e.g., GitHub, Azure Repos).
2. Azure VM: You have an Ubuntu VM set up and ready for deployment with SSH access enabled.
3. Azure DevOps: You have an Azure DevOps account and your Laravel project is part of an active Azure DevOps project.
4. Service Connection: An SSH service connection is set up in Azure DevOps to connect securely to your VM.
Step-by-Step Guide to Deploy Laravel to Azure VM with Azure DevOps Pipeline
Step 1: Setting Up the SSH Service Connection in Azure DevOps
To deploy your Laravel application to an Azure VM, you need to set up a secure SSH connection in Azure DevOps,
which allows the pipeline to connect to the VM.
1. Log in to Azure DevOps and go to your project.
2. In the sidebar, click on Project Settings.
3. Under Pipelines, choose Service connections.
4. Click New service connection, then select SSH.
5. Fill in the details like your VM’s IP address, username, and SSH private key (used for secure server connection).
6. Save the connection with a name like ‘sshServiceConnection’.
Step 2: Creating a Pipeline in Azure DevOps
In Azure DevOps, a pipeline is a series of steps that automate your deployment process.
We’ll create a pipeline that:
- Compresses the Laravel application files into a package (archive).
- Transfers the package to the Azure VM.
- Extracts the files on the VM and prepares the application for use.
Instructions for Creating the Pipeline in Azure DevOps:
- Log in to Azure DevOps and navigate to your project.
- In the sidebar, click on Pipelines.
- Select New Pipeline.
- Choose where your code is hosted (e.g., GitHub, Azure Repos, etc.).
- Select the repository that contains your Laravel project.
- When asked to configure your pipeline, select YAML (since you will define the steps with a YAML file).
- In the YAML editor, paste the following YAML configuration (explained below):
Step 3: Define the YAML Deployment Pipeline
Here’s a simple YAML file that automates the deployment process. You can paste this directly into your pipeline editor in Azure DevOps:
trigger:
branches:
include:
– main # The pipeline runs when changes are pushed to the ‘main’ branch
pool:
vmImage: ‘ubuntu-latest’
stages:
– stage: Deploy
displayName: ‘Deploy Stage’
jobs:
– job: DeployJob
displayName: ‘Deploy Job’
steps:
– checkout: self
displayName: ‘Checkout Code’
– script: |
# Compress the Laravel application files
tar –exclude=’archive.tar.gz’ -czf $(Build.SourcesDirectory)/archive.tar.gz -C $(Build.SourcesDirectory) .
displayName: ‘Archive Files’
– task: CopyFilesOverSSH@0
displayName: ‘Copy Archive to Server’
inputs:
sshEndpoint: $(sshServiceConnection)
sourceFolder: ‘$(Build.SourcesDirectory)’
contents: ‘archive.tar.gz’
targetFolder: $(targetDirectory)
– task: SSH@0
displayName: ‘Extract Archive’
inputs:
sshEndpoint: ‘$(sshServiceConnection)’
runOptions: ‘commands’
commands: |
# Extract the compressed file on the server
tar -xzf $(targetDirectory)/archive.tar.gz -C $(targetDirectory)
rm $(targetDirectory)/archive.tar.gz
readyTimeout: ‘20000’
– task: SSH@0
displayName: ‘Clear Cache’
inputs:
sshEndpoint: ‘$(sshServiceConnection)’
runOptions: ‘commands’
commands: |
# Use the target directory variable to hide the full application path
php $(targetDirectory)/artisan cache:clear
php $(targetDirectory)/artisan config:clear
php $(targetDirectory)/artisan route:clear
php $(targetDirectory)/artisan view:clear
readyTimeout: ‘20000’
– task: SSH@0
displayName: ‘Set Permissions and Ownership’
inputs:
sshEndpoint: ‘$(sshServiceConnection)’
runOptions: ‘commands’
commands: |
# Set proper permissions for Laravel’s storage and cache directories
chown -R <user>:<group> $(targetDirectory)
chmod -R 775 $(targetDirectory)/storage
chmod -R 775 $(targetDirectory)/bootstrap/cache
readyTimeout: ‘20000’
Explanation of Key Parts
1. Trigger
The pipeline is set to run whenever there’s a new change (commit) to the ‘main’ branch, which typically contains your production code.
2. Checkout Code
This step pulls the latest version of your code from the repository.
3. Archive Files
This compresses all of your Laravel files into a ‘.tar.gz’ file. This method is faster than copying files individually, which can take up to 30 minutes or more.
4. Copy Archive to Server
The compressed file is securely transferred to your VM using SSH. The target folder is where the file will be placed on the server.
5. Extract Archive
Once the file is on the server, it is extracted (unzipped) into the target directory. After that, the archive file is removed to save space.
6. Clear Cache
Laravel uses caches for configuration, routing, and views. This step clears those caches to make sure the application is fresh and ready to run.
7. Set Permissions and Ownership
Laravel’s ‘storage’ and ‘bootstrap/cache’ directories must be writable by the server. This step sets the correct file permissions and ownership to ensure the application runs properly.
Step 4: Configure Pipeline Variables
To make the pipeline work correctly, you’ll need to configure a few variables in Azure DevOps:
1. Go to the Variables section in your pipeline editor.
2. Add the following variables:
Variable Name | Value | Description |
sshServiceConnection | The SSH connection name | The name you used when creating the SSH service connection. |
targetDirectory | /var/www/html or /path/to/your/laravel/app | The directory where the Laravel app will be deployed. |
<user> and <group> | The user and group on your VM | For example, www-data:www-data (typical for web servers). |
Sensitive values like SSH keys can be added as secret variables for better security.
Step 5: Running the Pipeline
Once your pipeline is set up:
1. Push your latest changes to the ‘main’ branch in your repository.
2. Azure DevOps will automatically trigger the pipeline and start the deployment process.
3. You can monitor the progress of the deployment from the Azure DevOps interface.
Post-Deployment Checklist
Check Environment Configuration
Ensure that the ‘.env’ file in your Laravel application has the correct settings (like database credentials and production environment settings).
Verify File Permissions
Confirm that Laravel’s ‘storage’ and ‘bootstrap/cache’ directories have the correct permissions, allowing the app to write logs and cache files.
Monitor Application
Consider setting up logging or monitoring tools (e.g., Laravel Telescope, Azure Monitor) to track the performance and health of your application after deployment.
Conclusion
By following this guide, you can simplify the process of deploying a Laravel application to an Azure Virtual Machine using an Azure DevOps pipeline. This approach gives you the best of both worlds: the automation benefits of a continuous integration pipeline, while still maintaining full control over your server environment. Compressing your application into a single package before transferring it ensures faster and more efficient deployments, saving valuable time.
For businesses looking to streamline their deployment process while managing their infrastructure, contact an expert DevOps service to get the necessary tools and expertise to achieve efficient, reliable results.