Azure Blob Storage for Images
Azure Blob Storage for Images
Section titled “Azure Blob Storage for Images”This guide provides a comprehensive step-by-step approach to using Azure Blob Storage for image storage, including security configurations and integration with GitHub Static Web Apps.
📋 Prerequisites
Section titled “📋 Prerequisites”Before you begin, ensure you have:
- An active Azure subscription
 - Azure CLI installed and configured
 - Basic understanding of Azure Resource Groups
 - Node.js installed (for GitHub Actions integration)
 
🚀 Step 1: Create Azure Storage Account
Section titled “🚀 Step 1: Create Azure Storage Account”1.1 Using Azure Portal
Section titled “1.1 Using Azure Portal”- Navigate to Azure Portal
 - Click Create a resource > Storage > Storage account
 - Fill in the required details:
- Subscription: Select your subscription
 - Resource group: Create new or use existing
 - Storage account name: Must be globally unique (3-24 characters, lowercase, numbers only)
 - Region: Choose closest to your users
 - Performance: Standard (for most use cases)
 - Redundancy: LRS (Locally Redundant Storage) for cost-effective option
 
 
1.2 Using Azure CLI
Section titled “1.2 Using Azure CLI”# Set variablesRESOURCE_GROUP="rg-image-storage"STORAGE_ACCOUNT="myimagestore$(openssl rand -hex 4)"LOCATION="eastus"
# Create resource groupaz group create \  --name $RESOURCE_GROUP \  --location $LOCATION
# Create storage accountaz storage account create \  --name $STORAGE_ACCOUNT \  --resource-group $RESOURCE_GROUP \  --location $LOCATION \  --sku Standard_LRS \  --kind StorageV2 \  --https-only true \  --allow-blob-public-access true🗂️ Step 2: Create Blob Container
Section titled “🗂️ Step 2: Create Blob Container”2.1 Using Azure Portal
Section titled “2.1 Using Azure Portal”- Navigate to your Storage Account
 - Go to Data Storage > Containers
 - Click + Container
 - Configure container:
- Name: 
images(or your preferred name) - Public access level: Choose based on your needs:
- Private: No anonymous access
 - Blob: Anonymous read access for blobs only
 - Container: Anonymous read access for container and blobs
 
 
 - Name: 
 
2.2 Using Azure CLI
Section titled “2.2 Using Azure CLI”# Get storage account keySTORAGE_KEY=$(az storage account keys list \  --resource-group $RESOURCE_GROUP \  --account-name $STORAGE_ACCOUNT \  --query '[0].value' -o tsv)
# Create container for public imagesaz storage container create \  --name images \  --account-name $STORAGE_ACCOUNT \  --account-key $STORAGE_KEY \  --public-access blob
# Create container for private imagesaz storage container create \  --name private-images \  --account-name $STORAGE_ACCOUNT \  --account-key $STORAGE_KEY \  --public-access off📤 Step 3: Upload Images
Section titled “📤 Step 3: Upload Images”3.1 Using Azure CLI
Section titled “3.1 Using Azure CLI”# Upload a single imageaz storage blob upload \  --account-name $STORAGE_ACCOUNT \  --account-key $STORAGE_KEY \  --container-name images \  --name "logo.png" \  --file "./local-logo.png" \  --content-type "image/png"
# Upload multiple imagesfor file in ./images/*; do    filename=$(basename "$file")    az storage blob upload \      --account-name $STORAGE_ACCOUNT \      --account-key $STORAGE_KEY \      --container-name images \      --name "$filename" \      --file "$file" \      --overwritedone3.2 Using Azure Storage SDKs
Section titled “3.2 Using Azure Storage SDKs”JavaScript/Node.js Example:
const { BlobServiceClient } = require('@azure/storage-blob');
async function uploadImage() {  const connectionString = "DefaultEndpointsProtocol=https;AccountName=...";  const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
  const containerClient = blobServiceClient.getContainerClient('images');  const blockBlobClient = containerClient.getBlockBlobClient('logo.png');
  // Upload from file  await blockBlobClient.uploadFile('./local-logo.png', {    blobHTTPHeaders: {      blobContentType: 'image/png'    }  });
  console.log('Image uploaded successfully!');  console.log(`Image URL: ${blockBlobClient.url}`);}🌐 Step 4: Configure Custom Domain (Optional)
Section titled “🌐 Step 4: Configure Custom Domain (Optional)”4.1 Add Custom Domain
Section titled “4.1 Add Custom Domain”# Add custom domain to storage accountaz storage account update \  --name $STORAGE_ACCOUNT \  --resource-group $RESOURCE_GROUP \  --custom-domain "images.yourdomain.com"4.2 Configure DNS
Section titled “4.2 Configure DNS”Add a CNAME record in your DNS provider:
- Name: 
images - Value: 
mystorageaccount.blob.core.windows.net 
📊 Step 5: Monitor Usage and Costs
Section titled “📊 Step 5: Monitor Usage and Costs”5.1 Enable Storage Analytics
Section titled “5.1 Enable Storage Analytics”# Enable storage analyticsaz storage logging update \  --account-name $STORAGE_ACCOUNT \  --account-key $STORAGE_KEY \  --services b \  --log rwd \  --retention 75.2 Set up Alerts
Section titled “5.2 Set up Alerts”# Create action group for notificationsaz monitor action-group create \  --name "storage-alerts" \  --resource-group $RESOURCE_GROUP \  --action email admin admin@yourdomain.com
# Create alert rule for high storage usageaz monitor metrics alert create \  --name "High Storage Usage" \  --resource-group $RESOURCE_GROUP \  --scopes "/subscriptions/YOUR_SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Storage/storageAccounts/$STORAGE_ACCOUNT" \  --condition "avg UsedCapacity > 50000000000" \  --action "storage-alerts"🔗 Getting Image URLs
Section titled “🔗 Getting Image URLs”Public Images
Section titled “Public Images”For public containers, images are accessible via direct URLs:
https://<storage-account>.blob.core.windows.net/<container>/<blob-name>Example:
https://myimagestore1234.blob.core.windows.net/images/logo.pngPrivate Images
Section titled “Private Images”For private containers, you’ll need to generate SAS (Shared Access Signature) tokens:
# Generate SAS token for specific blobaz storage blob generate-sas \  --account-name $STORAGE_ACCOUNT \  --account-key $STORAGE_KEY \  --container-name private-images \  --name "private-logo.png" \  --permissions r \  --expiry "2024-12-31T23:59:59Z" \  --https-only🎯 Best Practices
Section titled “🎯 Best Practices”Performance Optimization
Section titled “Performance Optimization”- Use CDN: Enable Azure CDN for global distribution
 - Optimize Image Formats: Use WebP, AVIF for modern browsers
 - Implement Caching: Set appropriate cache headers
 - Use Proper Naming: Use consistent, descriptive blob names
 
Cost Management
Section titled “Cost Management”- Choose Right Storage Tier: Hot, Cool, or Archive based on access patterns
 - Lifecycle Management: Automatically move old images to cheaper tiers
 - Monitor Costs: Set up cost alerts and budgets
 - Delete Unused Images: Regular cleanup of unused assets
 
Security Considerations
Section titled “Security Considerations”- Use Private Containers: When possible, keep images private
 - Implement SAS Tokens: For controlled access to private content
 - Enable Encryption: All data is encrypted at rest by default
 - Regular Access Reviews: Monitor who has access to storage accounts
 
🔗 Next Steps
Section titled “🔗 Next Steps”- Learn how to integrate these images with GitHub Static Web Apps
 - Explore comprehensive security configurations
 - Set up automated image processing workflows
 
🛠️ Troubleshooting
Section titled “🛠️ Troubleshooting”Common Issues
Section titled “Common Issues”Error: Storage account name not available
- Solution: Try a different name; storage account names must be globally unique
 
Error: Cannot access blob
- Check container public access settings
 - Verify SAS token hasn’t expired for private containers
 
Slow image loading
- Enable Azure CDN
 - Optimize image sizes and formats
 - Check network connectivity
 
Useful Commands
Section titled “Useful Commands”# List all blobs in containeraz storage blob list \  --account-name $STORAGE_ACCOUNT \  --account-key $STORAGE_KEY \  --container-name images \  --output table
# Get blob propertiesaz storage blob show \  --account-name $STORAGE_ACCOUNT \  --account-key $STORAGE_KEY \  --container-name images \  --name logo.png
# Copy blob between containersaz storage blob copy start \  --source-container images \  --source-blob logo.png \  --destination-container backup \  --destination-blob logo-backup.png \  --account-name $STORAGE_ACCOUNT \  --account-key $STORAGE_KEY