Set document root in Zend Framework 1.12.x application in Azure Cloud Service

断了今生、忘了曾经 提交于 2020-01-03 05:47:05

问题


in relation to my other question on how to set the document root for a Azure Web Site, I would like to know how to do the same with a Cloud Service.

I've used the Azure Powershell Tools to create a package of my application and succesfully uploaded it to the cloud. But setting document root is not working.

My ServiceDefinition.csdef looks like this:

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="myCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
    <WebRole name="myWebRole" vmsize="ExtraSmall">
    <Imports />
    <Startup>
      <Task commandLine="setup_web.cmd &gt; log.txt" executionContext="elevated">
        <Environment>
          <Variable name="EMULATED">
            <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
          </Variable>
          <Variable name="RUNTIMEVERSIONPRIMARYKEY" value="5.3.17" />
          <Variable name="RUNTIMEID" value="PHP" />
          <Variable name="RUNTIMEURL" value="http://az413943.vo.msecnd.net/php/5.3.17.exe" />    
        </Environment>
      </Task>
    </Startup>
    <Endpoints>
      <InputEndpoint name="Endpoint1" protocol="http" port="80" />
    </Endpoints>
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Endpoint1" endpointName="Endpoint1" />
        </Bindings>
      </Site>
    </Sites>
</WebRole>
</ServiceDefinition>

Now I've tried setting the physicalDirectoryPath for the site directly

<Sites>
  <Site name="Web" physicalDirectory="../htdocs">
    ...
  </Site>
</Sites>

and I've tried to use a VirtualApplication, but both don't seem to work.

<Sites>
  <Site name="Web">
    <VirtualApplication name="MyWeb" physicalDirectory="../htdocs" />
    ...
  </Site>
</Sites>

Any help?


回答1:


Following a Blog entry, I found a solution that works. I'll sum it up to give a quick insight on how to do it:

Link: Change your azure websites root folder

You have to add da startup task in your ServiceDefinition.csdef file

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

This instructs each instance on startup to execute 'changeroot.cmd'. This file hast to go into the /bin directory of your web role instance directory.

This contains the following code:

@echo off
cd "%~dp0"

icacls %RoleRoot%\approot /grant "Everyone":F /T

powershell.exe Set-ExecutionPolicy Unrestricted
powershell.exe .\changeroot.ps1
ECHO Changeroot Run. >> ..\startup-tasks-log.txt

This will execute the powershell changeroot.ps1 script, with elevated user right, that will move the physicalPath of the site in IIS once it is created. This also has to go into your /bin path in your web role.

It contains the following code:

$siteName = "Web"
$serverIP = "127.0.0.1"
$newPath = "htdocs" ## your document root

$pathset = $false
$trycount = 0

##loop until physical path has changed
while($pathset -eq $false) {
   $trycount += 1

   ##if the role id can be determined
   if([Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::CurrentRoleInstance.Id -ne $null)
   {
          $fullName = [Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::CurrentRoleInstance.Id + "_" + $siteName
          $op = "Changeroot: Site Full Name: $fullName`r`n"
          Write-Output $op | Out-File -Encoding Ascii ..\startup-tasks-log.txt

          ##init server manager
          $serverManager = [Microsoft.Web.Administration.ServerManager]::OpenRemote($serverIP)
          if($serverManager -ne $null)
          {
                 $op = "Changeroot: Site Manager Setup`r`n"
                 Write-Output $op | Out-File -Encoding Ascii ..\startup-tasks-log.txt

                 ##load site
                 $site = $serverManager.Sites | where { $_.Name -eq $fullName }
                 if($site -ne $null)
                 {
                       $op = "Changeroot: Site loaded ($fullName)`r`n"
                       Write-Output $op | Out-File -Encoding Ascii ..\startup-tasks-log.txt
                       ##change physical path
                        $rootApp = $site.Applications | where { $_.Path -eq "/" }
                       $rootVdir = $rootApp.VirtualDirectories | where { $_.Path -eq "/" }
                       $dir = $rootVdir.PhysicalPath.EndsWith('\')
                       if($dir -eq $true) {
                              $rootVdir.PhysicalPath += $newPath + "\"
                       } else {
                              $rootVdir.PhysicalPath += "\" + $newPath + "\"
                       }
                       $serverManager.CommitChanges()
                       $op = "Root changed for $fullName (after $trycount tries)`r`n"
                       Write-Output $op | Out-File -Encoding Ascii ..\startup-tasks-log.txt
                       $pathset = $true
                       exit
                 }
          }
   } else {
          startup-tasks-log.txt
   }
   # Restart the loop in 5 seconds
   Start-Sleep -Seconds 5
}

This finally worked for me.

For a more detailed explanation please follow the link.

An added precaution:

Make sure you build your package (or deploy using publish-azureserviceproject) using a build machine that has a matching (or lesser) .net framework as your cloud host. If deploying on a Windows 8.1 machine, you may need to make sure your OSFamily is set to 4. In order to verify that your .net runtimes aren't newer on your build machine than they are on your cloud host:

  • open a powershell on both machines
  • take a look at [System.Environment]::Version or if you're using powershell 2.0 or newer, you can look at the $PSVersionTable variable

The problems you'll run into if you don't do this - you likely won't be able to use any of the Azure Assemblies such as Microsoft.WindowsAzure.ServiceRuntime. Changing the Physical Path of a web site depends on knowing the web site name and this is only (dynamically) available in that assembly.



来源:https://stackoverflow.com/questions/24821599/set-document-root-in-zend-framework-1-12-x-application-in-azure-cloud-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!