RyanCEI
RyanCEI

Reputation: 426

How can I properly set the cache directory for ImageResizer on an Azure WebRole?

ImageResizer's DiskCache plugin works fine locally, but when I deploy the WebRole to Azure the deployment partition is too small to cache a meaningful amount of files.

Specifically, the WebRole partition is around 1GB on a small role. I'd like to point the cache directory to:

  1. The "C:" drive (around 200+GB on a small role).
  2. An attached drive (any size I specify).

The problem is the write privileges necessary for the WebRole. Is there a simple workaround for a temp directory, or do I need a PowerShell script to configure ACLs on a virtual directory and attach it to the WebRole's site?

Before I go down that route I'd like to know if anyone has a reasonable workaround for this.

Upvotes: 3

Views: 354

Answers (2)

RyanCEI
RyanCEI

Reputation: 426

In ServiceDefinition.csdef:

<Task commandLine="makevdir.cmd" executionContext="elevated" taskType="background" />

Makevdir.cmd:

PowerShell -ExecutionPolicy Unrestricted .\makevdir.ps1 >> "%RoleRoot%\makevdir.txt" 2>&1
EXIT /B %errorlevel%

Makevdir.ps1:

# Make Virtual Directory for ImageResizer DiskCache plugin (/imagecache) 
Write-Host "makevdir.ps1 starting"

# $ImageCacheDir = $env:temp + "\imagecache"
#
# The TEMP paths are quota limited to ~100MB, so use a hard coded path:
$ImageCacheDir = "C:\Resources\AspNetTemp\imagecache"

Write-Host "ImageCacheDir = $ImageCacheDir"
md -Path $ImageCacheDir

# Set the ACL to allow IIS access to the new directory
$acl = Get-Acl $ImageCacheDir
$identity = "IIS_IUSRS"
$fileSystemRights = "Modify"
$inheritanceFlags = "ContainerInherit, ObjectInherit"
$propagationFlags = "None"
$accessControlType = "Allow"
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule($identity,          $fileSystemRights, $inheritanceFlags, $propagationFlags, $accessControlType)
$acl.SetAccessRule($rule)
Set-Acl $ImageCacheDir $acl

# Get the AppName by appending _Web/ to the RoleInstanceID environmental variable
$AppName = $env:RoleInstanceID + "_Web/"
Write-Host "AppName = $AppName"

# Retry creating the virtual directory every five seconds for a maximum of 20 tries
$tries = 0
& $Env:WinDir\system32\inetsrv\appcmd.exe add vdir /app.name:$AppName /path:/imagecache /physicalpath:$ImageCacheDir
while (!$? -and $tries -lt 20) {
$tries++
    sleep 5
& $Env:WinDir\system32\inetsrv\appcmd.exe add vdir /app.name:$AppName /path:/imagecache /physicalpath:$ImageCacheDir
}

Write-Host "makevdir.ps1 exiting"
Exit

Upvotes: 2

Lilith River
Lilith River

Reputation: 16468

As DiskCache delegates the serving of files to IIS for performance, you will need an IIS virtual folder.

DiskCache can cache/serve files from any virtual folder, regardless of its physical location (although local storage is best - latency is unacceptable).

A temp folder won't work, as both IIS and the ASP.NET runtime user accounts need read/write access, and you definitely want DiskCache to be persistent.

It does sound like you'll need to script the setup for this. I think a lot of people could benefit from such a script, if you can share it when it's done. Here's how to script an IIS virtual folder.

Upvotes: 0

Related Questions