If you’re moving from shared hosting or “one droplet” setups into a real cloud platform, hosting Laravel on Azure is a solid option—especially if your team already uses Microsoft tooling (Azure AD, GitHub/Azure DevOps, SQL Server, Windows endpoints, etc.). Azure gives you multiple ways to run Laravel, from fully managed PaaS to full-control VMs to container orchestration. The best choice depends on how much control you need over the OS/runtime, how you deploy, and how you handle scaling and background workers.
Visit here to see fully managed cloud hosting solution for this.
This guide is built to be practical: real CLI commands, configuration files, and decisions you’ll actually face in production. You’ll learn three deployment paths:
- Azure App Service (PaaS): Fastest to ship, easiest to operate, strong for typical Laravel web apps.
- Azure Virtual Machines (IaaS): Full control for custom Nginx/PHP tuning, special PHP extensions, advanced networking, or strict compliance needs.
- Azure Kubernetes Service (AKS): Best when you’re already container-first, need multi-service orchestration, or want standardized workloads across teams.
Azure makes the most sense when you want enterprise-grade platform features (identity, policy, governance, networking, monitoring, CI/CD integration) without building everything from scratch. It’s not automatically “better” than AWS or GCP—just a different set of tradeoffs. If you want minimal ops and predictable deployment, go App Service. If you need total control, go VM. If you want container orchestration, go AKS.
Hosting Laravel on Azure: Why Choose Azure for Laravel Applications?
Azure is attractive for Laravel for reasons that are practical, not hype:
- Enterprise reliability and governance
- Strong IAM and identity story (Azure AD / Entra ID).
- Policy, role-based access control, resource locks, and structured resource management.
- Global footprint and managed services
- Wide regional availability and managed databases/caches/storage.
- Microsoft ecosystem integration
- Fits naturally if your org already uses Microsoft services and enterprise controls.
- Native DevOps options
- Azure DevOps pipelines and GitHub Actions both integrate cleanly with App Service/VM/AKS.
- Hybrid capability
- If you have on-prem constraints (VPN/ExpressRoute), Azure’s networking model is often convenient.
Balanced reality check (vs AWS/GCP):
- AWS often has the deepest service catalog and mature ecosystem.
- GCP is strong for data/analytics and certain managed offerings.
- Azure shines when governance + enterprise integration + managed hosting choices matter.
Azure Hosting Options for Laravel (Choose the Right Architecture)
Azure App Service (PaaS)
What you get
- Managed platform for web hosting (Linux or Windows).
- Simple deployment options (Git, ZIP package, CI/CD).
- Built-in scaling and deployment slots.
Where it can bite you
- Some runtime customization is constrained unless you use a custom container.
- Background workers aren’t “first-class” the way they are on a VM—you usually run a separate worker app.
Azure Virtual Machines (IaaS)
What you get
- Full OS control: Nginx/Apache, PHP-FPM tuning, kernel/network settings, any extensions.
- Flexible architecture: multiple servers, custom load balancers, custom security baselines.
Cost
- More operations work: patching, monitoring, backups, scaling logic, failover design.
Azure Kubernetes Service (Advanced)
What you get
- Container orchestration: horizontal pod autoscaling, rolling updates, service discovery.
- Strong fit for microservices and standardized deployment patterns.
Tradeoff
- AKS adds operational complexity and cost overhead. Don’t choose AKS “because Kubernetes”—choose it because you need Kubernetes.
Quick comparison table
| Option | Cost | Control | Scalability | Maintenance | Best For |
|---|---|---|---|---|---|
| App Service | $ | Medium | High | Low | Most Laravel web apps that want fast shipping + low ops |
| Virtual Machines | $–$$ | High | Medium–High | Medium–High | Custom stacks, special extensions, full tuning, strict constraints |
| AKS | $$ | High | Very High | High | Container-first orgs, multi-service platforms, complex scaling needs |
Rule of thumb:
- Start with App Service unless you can name a specific limitation that forces VM/AKS.
Step-by-Step Guide: Hosting Laravel on Azure App Service
This section is intentionally detailed. The goal: deploy a Laravel app to production with sane defaults, predictable deployments, proper env config, storage considerations, workers, and TLS.
1) Create an Azure account
If you’re new to Azure:
- Create an account and enable billing.
- Install the Azure CLI locally and sign in:
az login
az account show
If you manage multiple subscriptions:
az account list –output table
az account set –subscription “SUBSCRIPTION_NAME_OR_ID”
2) Create a Resource Group
Resource groups keep related infrastructure together.
az group create </span>
–name rg-laravel-prod </span>
–location eastus
Pick the region closest to your users and data requirements.
3) Create an App Service Plan
For production, use a paid tier that supports:
- Custom domains + TLS
- “Always On”
- Scaling features
Create a Linux plan:
az appservice plan create </span>
–name asp-laravel-prod </span>
–resource-group rg-laravel-prod </span>
–is-linux </span>
–sku P1v3
Notes:
- SKU choice matters for performance, scaling, and features.
- For cost control, start smaller and scale up/out when you can justify it with metrics.
4) Create a Web App (select PHP runtime)
Create the web app:
az webapp create </span>
–resource-group rg-laravel-prod </span>
–plan asp-laravel-prod </span>
–name my-laravel-web-prod </span>
–runtime “PHP|8.2”
Why this matters:
- The runtime defines your PHP version and base environment.
- You should match your local/CI PHP version as closely as possible.
Related Post: How to Host Laravel Backend
5) Deploy Laravel (Git, ZIP, or Azure DevOps)
You have three realistic paths. Choose one and stick to it.
Option A: Deploy via Git (simple but less controlled)
Set up deployment from a repo (works best with deployment center in the portal). For CLI-based flow, most teams prefer CI/CD (Azure DevOps or GitHub Actions) instead of direct Git deployments.
Use Git deployment when:
- You’re small, moving fast, and accept less repeatability.
Option B: ZIP deployment (fast, atomic, easy rollback mindset)
ZIP deploy works well when you build artifacts in CI and ship a package.
Enable “run from package” for atomic startup:
az webapp config appsettings set </span>
–resource-group rg-laravel-prod </span>
–name my-laravel-web-prod </span>
–settings WEBSITE_RUN_FROM_PACKAGE=1
Deploy:
zip -r release.zip . -x “vendor/“ “node_modules/” “.git/*”
az webapp deployment source config-zip </span>
–resource-group rg-laravel-prod </span>
–name my-laravel-web-prod </span>
–src release.zip
“
Best practice:
- Build in CI (including
composer install --no-dev) and zip the built output, so production doesn’t compile dependencies at deploy time.
Option C: Deploy via Azure DevOps (recommended for teams)
Why Azure DevOps:
- Controlled pipelines
- Approvals
- Secrets integration
- Repeatable releases
High-level pipeline steps (Linux App Service):
- Checkout code
- Install PHP + Composer
composer install --no-dev --optimize-autoloader- (Optional)
npm ci && npm run build - Run tests
- Package artifact
- Release to App Service
Core build commands:
composer install –no-dev –prefer-dist –optimize-autoloader
php artisan config:cache
php artisan route:cache
php artisan view:cache
“
Why caching matters:
- It reduces per-request config parsing and speeds up bootstrapping in production.
6) Configure environment variables (App Settings)
Never store .env in the repo for production. Use App Settings instead.
Set Laravel essentials:
az webapp config appsettings set </span>
–resource-group rg-laravel-prod </span>
–name my-laravel-web-prod </span>
–settings </span>
APP_NAME=”My App” </span>
APP_ENV=production </span>
APP_DEBUG=false </span>
APP_KEY=”base64:PUT_REAL_KEY_HERE” </span>
LOG_CHANNEL=stack </span>
LOG_LEVEL=info
“
Database example (MySQL):
az webapp config appsettings set </span>
–resource-group rg-laravel-prod </span>
–name my-laravel-web-prod </span>
–settings </span>
DB_CONNECTION=mysql </span>
DB_HOST=”your-mysql-host.mysql.database.azure.com” </span>
DB_PORT=3306 </span>
DB_DATABASE=”yourdb” </span>
DB_USERNAME=”dbuser” </span>
DB_PASSWORD=”strong-password”
Important:
- APP_KEY must be stable. Generate locally once:
php artisan key:generate –show
Then paste into App Settings.
7) Set storage permissions (Laravel storage/cache)
On App Service, your writable area is usually under storage/ and bootstrap/cache/. You want to ensure:
- Logs can be written
- Cache files can be created
If you use App Service storage (shared storage), ensure the platform supports writes. In many production setups, you should use:
- Blob Storage for user uploads
- Redis for cache/session
- Minimal local disk dependence
At minimum, confirm you’re not relying on ephemeral local storage for critical files.
8) Configure queue workers (do not skip this)
Most Laravel production apps need queue processing. App Service web app processes are not the same as a managed background worker environment. The clean approach:
Run a separate “worker” App Service:
- Create a second Web App in the same App Service Plan (or its own).
- Configure it with the same codebase.
- Set startup command to run the worker.
Create worker app:
az webapp create </span>
–resource-group rg-laravel-prod </span>
–plan asp-laravel-prod </span>
–name my-laravel-worker-prod </span>
–runtime “PHP|8.2”
Set its startup command (conceptually) to:
php artisan queue:work –sleep=3 –tries=3 –timeout=90
Also enable “Always On” (via portal or CLI depending on plan/support).
Why separate worker:
- Worker scaling is independent from web traffic.
- You can scale workers out without scaling the frontend.
If you use Horizon (Redis queues), your worker strategy becomes even more important.
9) Configure SSL (TLS)
Production must enforce HTTPS.
Typical flow:
- Add a custom domain to the App Service.
- Bind a certificate:
- Use an App Service managed certificate (simplest) or upload your own.
- Force HTTPS:
- Enable HTTPS only in App Service settings.
- Set Laravel
APP_URL=https://yourdomain.com.
Also set proxy trust (important behind Azure’s front ends). In Laravel, configure trusted proxies if needed (depends on your setup).
Hosting Laravel on Azure Virtual Machine (Full Server Setup)
This is for when you want full control: custom Nginx, PHP-FPM tuning, special extensions, nonstandard requirements, or predictable “traditional server” operations.
1) Create an Ubuntu VM
Create a VM (example):
az group create –name rg-laravel-vm-prod –location eastus
az vm create </span>
–resource-group rg-laravel-vm-prod </span>
–name vm-laravel-prod-01 </span>
–image Ubuntu2204 </span>
–size Standard_B2s </span>
–admin-username azureuser </span>
–generate-ssh-keys
Open HTTP/HTTPS:
az vm open-port –resource-group rg-laravel-vm-prod –name vm-laravel-prod-01 –port 80
az vm open-port –resource-group rg-laravel-vm-prod –name vm-laravel-prod-01 –port 443
“
SSH in:
ssh azureuser@YOUR_VM_PUBLIC_IP
2) Install Nginx
sudo apt update
sudo apt install -y nginx
sudo systemctl enable nginx
sudo systemctl start nginx
3) Install PHP 8.x + extensions
Laravel commonly needs: mbstring, xml, curl, zip, mysql, bcmath, intl.
sudo apt install -y </span>
php8.2-fpm php8.2-cli </span>
php8.2-mbstring php8.2-xml php8.2-curl php8.2-zip </span>
php8.2-mysql php8.2-bcmath php8.2-intl </span>
unzip git
Why this matters:
- Missing extensions are a top cause of “works locally, fails in prod”.
4) Install Composer
cd ~
php -r “copy(‘https://getcomposer.org/installer‘, ‘composer-setup.php’);”
php composer-setup.php –install-dir=/usr/local/bin –filename=composer
composer –version
5) Clone your Laravel project
sudo mkdir -p /var/www/myapp
sudo chown -R $USER:$USER /var/www/myapp
cd /var/www/myapp
git clone https://github.com/yourorg/yourrepo.git .
Install dependencies:
composer install –no-dev –prefer-dist –optimize-autoloader
Set up env:
cp .env.example .env
php artisan key:generate
Edit .env for production (or pull secrets from a secure store). Set:
APP_ENV=productionAPP_DEBUG=falseLOG_LEVEL=info- DB/Redis/Cache settings
6) Configure Nginx (sample production config)
Create a site config:
sudo nano /etc/nginx/sites-available/myapp
Paste:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
root /var/www/myapp/public;
index index.php;
add_header X-Frame-Options “SAMEORIGIN”;
add_header X-Content-Type-Options “nosniff”;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ </span>.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /</span>.(?!well-known).* {
deny all;
}
}
Enable it:
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Why this config is “Laravel-correct”:
try_filesroutes all unmatched paths toindex.php- Blocks hidden files
- Uses PHP-FPM socket for performance
7) Set file permissions
You want storage/ and bootstrap/cache/ writable by the web user:
sudo chown -R www-data:www-data /var/www/myapp/storage /var/www/myapp/bootstrap/cache
sudo chmod -R 775 /var/www/myapp/storage /var/www/myapp/bootstrap/cache
Avoid chmod 777. That’s lazy and dangerous.
8) Setup Supervisor for queues
Install Supervisor:
sudo apt install -y supervisor
Create config:
sudo nano /etc/supervisor/conf.d/laravel-worker.conf
Example:
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/myapp/artisan queue:work –sleep=3 –tries=3 –timeout=90
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/myapp/storage/logs/worker.log
stopwaitsecs=3600
Apply:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl status
Why Supervisor matters:
- Keeps workers alive after crashes/reboots
- Lets you run multiple worker processes reliably
9) Configure firewall
UFW basics:
sudo ufw allow OpenSSH
sudo ufw allow “Nginx Full”
sudo ufw enable
sudo ufw status
Also consider Azure NSG rules—treat both OS firewall and NSG as part of the security boundary.
10) Enable HTTPS
Use Let’s Encrypt with Certbot:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot –nginx -d yourdomain.com -d www.yourdomain.com
Auto-renewal is typically installed automatically; confirm:
sudo systemctl status certbot.timer
Database Setup for Laravel on Azure
Azure SQL
Laravel supports SQL Server via the sqlsrv driver. This is useful when:
- Your org standardizes on Microsoft SQL Server.
- You need SQL Server features or tooling integration.
Reality check:
pdo_sqlsrvisn’t always available on every managed PHP runtime without customization.- If you must use Azure SQL with PHP, you often end up with VM or custom container where you can install SQL Server drivers.
On Ubuntu VM, you’d install the SQL Server ODBC driver and PHP extension (high-level concept):
- Install Microsoft ODBC packages
- Install
php-sqlsrvandphp-pdo-sqlsrv - Set
DB_CONNECTION=sqlsrv
Laravel .env example:
DB_CONNECTION=sqlsrv
DB_HOST=your-server.database.windows.net
DB_PORT=1433
DB_DATABASE=yourdb
DB_USERNAME=youruser
DB_PASSWORD=yourpassword
Also:
- Configure Azure SQL firewall to allow your VM outbound IP or use private networking (preferred for production).
MySQL Flexible Server
This is the common “just works” path for Laravel.
Laravel .env example:
DB_CONNECTION=mysql
DB_HOST=your-mysql.mysql.database.azure.com
DB_PORT=3306
DB_DATABASE=yourdb
DB_USERNAME=dbuser
DB_PASSWORD=strong-password
Production considerations:
- Use TLS for DB connections when available.
- Use a private endpoint/VNet integration where possible.
- Size the DB based on real workload: CPU, memory, IOPS matter more than “storage size”.
Firewall rules:
- For public access, restrict to known outbound IPs (App Service outbound addresses or VM IP).
- For better security, prefer private networking.
Storage & Caching Options
Azure Blob Storage (for user uploads + shared files)
Do not store user uploads on a single VM disk if you plan to scale horizontally. Use Blob Storage.
Laravel uses Flysystem for storage. Configure a disk to point to Blob Storage using an Azure adapter (implementation varies by package). Conceptually, you will:
- Install the adapter package for Azure Blob.
- Add disk config in
config/filesystems.php. - Store credentials in env / Key Vault.
Example .env variables:
AZURE_STORAGE_ACCOUNT=youraccount
AZURE_STORAGE_KEY=yourkey
AZURE_STORAGE_CONTAINER=uploads
FILESYSTEM_DISK=azure
Then, in config/filesystems.php (conceptual pattern):
‘disks’ => [
‘azure’ => [
‘driver’ => ‘azure’,
‘name’ => env(‘AZURE_STORAGE_ACCOUNT’),
‘key’ => env(‘AZURE_STORAGE_KEY’),
‘container’ => env(‘AZURE_STORAGE_CONTAINER’),
‘url’ => env(‘AZURE_STORAGE_URL’),
],
],
Why this matters:
- Blob storage gives you durable, scalable storage independent of compute instances.
Azure Cache for Redis (cache, sessions, queues)
Use Redis for:
- Cache driver
- Session driver
- Horizon queues (if you use Horizon)
.env:
CACHE_STORE=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
REDIS_HOST=your-redis.redis.cache.windows.net
REDIS_PASSWORD=your_redis_access_key
REDIS_PORT=6380
REDIS_SCHEME=tls
Production note:
- Use TLS where supported.
- Keep sessions out of local files if you scale beyond one instance.
Hosting Laravel on Azure: Scaling Laravel on Azure
Scaling is not only “add more servers.” It’s also eliminating single-instance assumptions.
App Service scaling
- Scale up: bigger instance size (more CPU/RAM).
- Scale out: multiple instances behind Azure’s front end.
Key requirements for scale-out:
- Sessions in Redis (not local files)
- User uploads in Blob Storage (not local disk)
- Cache in Redis
- Queue workers scaled separately
Autoscale rules:
- CPU threshold (example: > 70% for N minutes)
- Memory threshold (if available)
- HTTP queue length / requests per second (depending on plan/telemetry)
VM scaling (horizontal)
For multiple VMs:
- Put VMs behind an Azure Load Balancer or Application Gateway.
- Use a shared datastore for sessions and cache (Redis).
- Use shared storage for uploads (Blob Storage).
- Use CI/CD to deploy consistently across instances.
Zero-downtime deployments
App Service (best experience):
- Use deployment slots:
- Deploy to staging slot
- Warm it up
- Swap to production
VM approach:
- Blue/green with two VM sets
- Or rolling deployments behind a load balancer
- Ensure migrations are backward-compatible during rollout
Migration strategy:
- Prefer additive changes first (add columns/tables), deploy code, then cleanup later.
Hosting Laravel on Azure: Security Best Practices for Laravel on Azure
Use Azure Key Vault (do this early)
Stop scattering secrets across pipelines, .env files, and random portal settings.
Patterns:
- CI/CD pulls secrets from Key Vault and injects into App Service settings at release time.
- App Service Key Vault references: store a reference string in App Settings so the platform resolves the secret.
Even if you start small:
- Put DB password, Redis key, and any third-party API keys in Key Vault.
HTTPS enforcement
- App Service: enable HTTPS only and set
APP_URLcorrectly. - VM: enforce redirect to HTTPS in Nginx after certbot setup.
Firewall and network restrictions
- Restrict DB firewall to only the app’s outbound addresses.
- Prefer private networking (VNet integration/private endpoints) for production.
DDoS protection
- If you’re a serious SaaS, evaluate Azure DDoS protection options and WAF (Application Gateway/Front Door) depending on threat model.
Environment variable protection
- Do not expose
phpinfo(). - Ensure
APP_DEBUG=false. - Ensure logs don’t dump secrets (watch exception reporting).
Cost Breakdown – What Does Hosting Laravel on Azure Really Cost?
Costs vary by:
- Region
- Instance type
- Scale (instance count)
- Database size and IOPS
- Redis tier
- Outbound bandwidth
- Logging/monitoring retention
How to think about costs (without fake precision):
App Service costs
- You pay per instance in the App Service Plan.
- Scaling out multiplies cost.
- Production-friendly tiers cost more but reduce ops time and improve stability.
VM costs
- VM + disk + bandwidth.
- Add load balancer/application gateway costs if used.
- More engineering hours (patching, uptime, scaling, backups) are the hidden cost.
Database costs
- Often the largest long-term cost driver.
- Under-sizing causes performance issues; over-sizing burns cash.
- Optimize queries, indexes, and connection pooling early.
Storage costs
- Blob storage is usually cheap.
- Bandwidth egress can surprise you if you serve lots of media directly.
Hidden costs to watch
- Logging ingestion/retention (Application Insights / monitoring)
- Backups + retention policies
- Extra environments (staging, QA, preview) doubling base spend
Cost control discipline:
- Start with minimal production-safe sizing.
- Add autoscale only when you have baseline metrics.
- Use budgets/alerts in Azure to catch spikes early.
Common Mistakes When Hosting Laravel on Azure
- Forgetting queue workers
- Jobs pile up, user workflows stall, “random timeouts” appear.
- Not configuring cache/session for scale
- It works on one instance, breaks on two.
- Running production in debug mode
- Security risk and performance killer.
- Not optimizing Composer for production
- You want
--no-devand optimized autoload.
- You want
- Not enabling/opting into opcode caching
- On VMs, ensure OPcache is configured properly. On managed platforms, understand what’s enabled by default.
- Storing uploads on local disk
- Scaling becomes painful or impossible.
- Treating deployments as “copy files and pray”
- Use CI/CD, artifacts, and repeatable steps.
Azure vs Other Hosting Providers for Laravel
Neutral decision points:
Versus DigitalOcean
- DigitalOcean can be simpler and cheaper for small apps.
- Azure offers broader enterprise services, governance, and integrated tooling.
- If you want “one VM and done,” DO is fine. If you want managed services + policy + scale options, Azure tends to win.
Versus AWS
- AWS has enormous service depth and ecosystem.
- Azure can be smoother in Microsoft-heavy orgs and often aligns well with enterprise governance expectations.
- Both can host Laravel well; choice often comes down to org alignment and operational preferences.
Practical rule:
- Pick the platform your team can operate confidently with strong CI/CD and monitoring. Cloud complexity punishes weak ops more than it rewards “feature lists.”
Final Verdict – Is Azure Good for Laravel?
Yes—hosting laravel on azure is a strong, production-capable choice when you pick the right architecture and avoid the common traps (workers, statefulness, storage, and secrets).
Use this decision framework:
Azure makes sense if:
- You want managed hosting with scaling and good DevOps integration (App Service).
- You need enterprise controls (RBAC, policy, Key Vault, governance).
- You’re standardizing on Microsoft ecosystem tools.
Azure might not be ideal if:
- You want the absolute simplest low-cost VM hosting and nothing else.
- Your team is already deeply invested in another cloud’s ecosystem and tooling and there’s no business reason to switch.
Who should avoid it (for now):
- Teams that can’t commit to learning basic Azure resource management and cost controls.
- Projects where the cheapest possible hosting is the primary goal (not reliability, security, or scalability).
If you want the most practical path: start with App Service + MySQL Flexible Server + Redis + Blob Storage, run a separate worker app, and use CI/CD for repeatable releases. That setup is production-ready, scales cleanly, and keeps operations manageable—exactly what most Laravel teams need when hosting laravel on azure.
Read Could Hosting Solutions Resource Hub.


