This report maps the current Docker-based LAMP stack (PHP, Apache, MySQL, Redis, phpMyAdmin) to Azure for deployment without Docker, using an Azure VM as the host. UAT and QA run on the same VM as separate sites (Apache vhosts / docroots), with separate databases and config per environment.
Scope: One VM for non-production: UAT + QA (same codebase, separate data and config). Production can be a separate VM or App Service later.
| Component | Current (Docker) | Notes |
|---|---|---|
| Web | PHP 5.6 + Apache | Upgrade to PHP 8.3 on Azure |
| Database | MySQL 5.7 | → Azure Database for MySQL |
| Cache/Session | Redis (latest) | → Azure Cache for Redis |
| DB Admin | phpMyAdmin | Optional: App Service or Azure tools |
| Storage | Local volumes (www, filesystem) | → VM disk + optional Blob Storage |
| SSL | Custom certs in container | → VM: Apache + cert (Let’s Encrypt or Azure) |
Each Azure service replaces one or more parts of the current Docker Compose stack (webserver, database, redis, phpmyadmin, volumes).
| Azure service | Replaces in Docker | Purpose | Ballpark effort |
|---|---|---|---|
| Azure Virtual Machine (Linux, e.g. Ubuntu 22.04) | webserver (PHP + Apache container) | Single VM hosting UAT and QA: Apache + PHP 8.3, two vhosts (e.g. uat.indawo.xxx, qa.indawo.xxx), separate docroots and config. | 2–3 days |
| Azure Database for MySQL – Flexible Server | database (MySQL container) | Managed MySQL. One server with two DBs: indawo_uat and indawo_qa (or MySQL installed on same VM for cost savings). | 1–2 days |
| Azure Cache for Redis (optional) | redis (Redis container) | Session/cache. One cache with key prefix per env (uat_ / qa_) or Redis on VM. | 0.5–1 day |
| Azure Managed Disk | Volumes: DOCUMENT_ROOT, filesystem, LOG_DIR, etc. | OS + data disk for app code, uploads, logs. Separate folders per site: e.g. /var/www/uat, /var/www/qa. | included in VM |
| Azure Blob Storage (optional) | Volume filesystem or uploads under docroot | File uploads / backups if you prefer not to keep all files on VM disk. | 1–2 days |
| Application Insights or VM extensions | — (no direct Docker equivalent) | Logs, metrics. Use Azure Monitor VM extension or App Insights SDK in app. | 0.5 day |
| Azure Key Vault (optional) | Env vars in docker-compose / .env | Secrets (DB, Redis). VM managed identity can read from Key Vault. | 1 day |
| NSG + public IP or Load Balancer | Compose ports: (80, 443, 22) and host networking | Network security group for ports 80/443/22; static public IP or DNS for uat/qa hostnames. | 0.5 day |
| phpMyAdmin on VM (or Azure Data Studio / MySQL Workbench) | phpmyadmin (phpMyAdmin container) | DB admin: install phpMyAdmin on the same VM, or use Azure Data Studio / MySQL Workbench to connect to Azure MySQL. No separate Azure service. | included in VM |
/var/www/uat and /var/www/qa. Same codebase deployed to both (or different branches); config per site via .env or env vars.indawo_uat and indawo_qa on Azure MySQL (or MySQL on the VM). Each site points to its own DB in config.uat_ / qa_ in app config, or Redis on VM with different DB index (0 for UAT, 1 for QA).https://uat.indawo.yourdomain.com and https://qa.indawo.yourdomain.com, both resolving to the VM’s public IP (or use one hostname with path if preferred).Recommendation: Keep UAT and QA on this single VM with separate vhosts and DBs; add a separate Production VM or App Service when you go live.
| Phase | Tasks | Effort |
|---|---|---|
| PHP 8.3 + app compatibility | Code/dep updates, testing (current stack is PHP 5.6) | 1–3 weeks |
| Azure subscription & networking | Resource group, VNet, NSG, public IP or DNS | 0.5–1 day |
| Azure VM + LAMP | Create Linux VM, install Apache, PHP 8.3, optional MySQL/Redis on VM | 2–3 days |
| UAT + QA vhosts | Two Apache vhosts, docroots, SSL (e.g. Let’s Encrypt), env config per site | 1–1.5 days |
| Azure MySQL Flexible Server | Create server, DBs indawo_uat & indawo_qa, firewall, migrate | 1–2 days |
| Redis | Azure Cache for Redis or Redis on VM; app config with prefix/DB index per env | 0.5–1 day |
| Blob Storage (optional) | Account, container(s), app integration for uploads | 1–2 days |
| Secrets & config | Key Vault (optional), .env or env vars per vhost | 0.5–1 day |
| CI/CD | Deploy UAT and QA to VM (e.g. GitHub Actions + SSH or Azure DevOps) | 1–2 days |
| Monitoring & docs | Azure Monitor / Log Analytics, runbook, README/CHANGELOG | 0.5–1 day |
Total ballpark (excluding PHP 8.3 app migration): ~8–12 days (one engineer). Including PHP 5.6 → 8.3: ~3–5 weeks depending on app size and breaking changes.
Assumption: 1 day = 8 hours. Use for planning and internal cost (e.g. hourly rate × hours).
| Phase | Hours (min) | Hours (max) | Notes |
|---|---|---|---|
| PHP 8.3 + app compatibility | 40 | 120 | 1–3 weeks; depends on codebase size |
| Azure subscription & networking | 4 | 8 | Resource group, VNet, NSG, DNS |
| Azure VM + LAMP | 16 | 24 | Create VM, Apache, PHP 8.3, optional MySQL/Redis on VM |
| UAT + QA vhosts | 8 | 12 | Two vhosts, SSL, env config per site |
| Azure MySQL Flexible Server | 8 | 16 | Server, two DBs, firewall, data migrate |
| Redis | 4 | 8 | Azure Cache or on-VM; app config |
| Blob Storage (optional) | 8 | 16 | Account, containers, app integration |
| Secrets & config | 4 | 8 | Key Vault or .env per vhost |
| CI/CD | 8 | 16 | GitHub Actions / Azure DevOps to VM |
| Monitoring & docs | 4 | 8 | Azure Monitor, runbook, README/CHANGELOG |
| Subtotal (excl. PHP 8.3 migration) | 64–116 hrs | ~8–14.5 days | |
| Total (incl. PHP 8.3 migration) | 104–236 hrs | ~13–30 days (3–6 weeks) | |
Use your team’s hourly rate × hours for labour cost (e.g. 80 hrs × $X/hr).
Ballpark monthly cost in USD and ZAR (list price, one region e.g. East US / West Europe). Actual cost depends on region, SKU, reservation, and usage. Use Azure Pricing Calculator for your scenario.
ZAR converted at 1 USD ≈ 18.50 ZAR (indicative; check current rate for billing).
| Resource | SKU / size | Low (USD/mo) | Mid (USD/mo) | Low (ZAR/mo) | Mid (ZAR/mo) | Notes |
|---|---|---|---|---|---|---|
| Azure VM (Linux) | B2s or B1ms | ~15 | ~50 | ~278 | ~925 | B1ms for light UAT/QA; B2s for more headroom |
| Managed Disk (OS + data) | 64–128 GB SSD | ~8 | ~25 | ~148 | ~463 | Included in some VM offers; data disk extra |
| Azure MySQL Flexible Server | Burstable B1ms or B2s | ~15 | ~45 | ~278 | ~833 | Or run MySQL on VM to save |
| Azure Cache for Redis | Basic C0 or on VM | 0 | ~20 | 0 | ~370 | On VM = R0 extra; Basic C0 if managed |
| Static public IP | 1 standard static IP | ~4 | ~5 | ~74 | ~93 | Optional if using dynamic + DNS |
| Bandwidth (egress) | First 5 GB free; then per GB | ~0 | ~15 | ~0 | ~278 | Depends on traffic |
| Key Vault (optional) | Standard, low transaction | ~0 | ~2 | ~0 | ~37 | Minimal operations |
| Blob Storage (optional) | LRS, < 10 GB | ~0 | ~5 | ~0 | ~93 | If used for uploads/backups |
| Application Insights / Log Analytics | First 5 GB free; pay per GB | ~0 | ~10 | ~0 | ~185 | Light usage often within free tier |
| Total (VM + managed MySQL + Redis) | ~45 | ~175 | ~833 | ~3 238 | Typical UAT/QA range | |
| Total (all on VM: MySQL + Redis on same VM) | ~30 | ~95 | ~555 | ~1 758 | Lower cost; you manage MySQL/Redis | |
Summary (USD): Expect roughly ~$30–95/mo if MySQL and Redis run on the same VM, or ~$45–175/mo with Azure Database for MySQL and Azure Cache for Redis.
Summary (ZAR): Roughly ~R555–R1 758/mo (all on VM) or ~R833–R3 238/mo (managed MySQL + Redis). Add reserved instances or savings plans to reduce cost; ZAR will vary with exchange rate.
Current Docker setup uses PHP 5.6. Moving to Azure with “latest PHP” implies PHP 8.3. This typically requires:
mcrypt → OpenSSL or Sodium).Estimate 1–3 weeks for PHP 8.3 migration unless the codebase is already compatible.
/var/www/uat, /var/www/qa; SSL via Let’s Encrypt or Azure).indawo_uat and indawo_qa; migrate schema and data; allow VM IP in firewall.