How to point IIS physical path to a temporary directory during deployment

Hello team,
my current IIS set up deploys the package to a directory using custom installation path by overriding the previous contents of the directory. The problem i’m experiencing with this approach is the deployment is failing occasionally due to the file lock reason when the website is serving the inflight requests. I’m thinking of a solution where i could use pre deploy script to map the physical path to the octopus working directory where the package is extracted and once the override in the custom installation directory is complete, use the post deploy script to set the physical path. Any suggestions on the efficiency on this approach or are there any alternate solutions for this kind of use case? Please let me know.
Thanks,
SRK.

Hi,

Thanks for getting in touch! It looks you will benefit from implementing a blue-green deployment strategy.

We have an excellent documentation page which details how you can configure blue-green deployments in IIS.

The docs details the basic idea very clearly in these three steps:

  1. Deploy a new instance of your web application and warm it up.
  2. Use an on-server reverse-proxy to seamlessly switch new incoming requests to the new instance.
  3. Delete the old instance once it has finished processing outstanding requests.

This method will allow you to deploy new versions of your website without file locks and will reduce downtime.

If you have any further questions or run into any issues with this, please don’t hesitate to let me know.

Best regards,
Daniel

Hi,
Blue-green deployment is out of this equation as we have resource constraints. Following is the current set up:

  1. Package is deployed to C:\octopus\Applications\1.x.x\
  2. copied to C:\webapps\appdirectory\1.x.x\ by simply overriding the previous contents and it is causing deployment failures due to file already in use issues (this step is achieved on setting the custom installation directory)
  3. Physical path is always pointed to C:\webapps\appdirectory\ and we require it to be that way.

Target state idea:

  1. deploy package to C:\octopus\Applications\1.y.y\
  2. change the physical path to C:\octopus\Applications\1.x.x\ temporarily using (pre deploy? or during deploy scrpts?) and copy the contents of the new package to C:\webapps\appdirectory\ in usual manner.
  3. once the copying/overriding is complete, change the physical path back to C:\webapps\appdirectory\ using (post deployment scripts?)

How do i achieve this? and what scripts to be used? Please let me know.

Thanks,
SRK.

Hi @kondasankeerthreddy,

Thanks for getting back to us, and noted on the Blue-Green deployment not being an option.

I’m not sure what your deployment process currently looks like in Octopus, and I’m sorry to ask a somewhat basic question, but are you using the built-in ‘Deploy to IIS’ step in your process? If you are, would it be feasible to deploy to a different directory and repoint the website virtual directory there?

Regardless of if you’re using that step or not, for your current process you could try adding an ‘IIS AppPool - Stop’ from the community steps prior to deploying the package to get any background tasks locking the files. There’s also an ‘IIS Website - Stop’ step that might be needed if you aren’t using the built-in ‘Deploy to IIS’ step.

image

The ‘Deploy to IIS’ step is set to start the AppPool and Website by default, so you shouldn’t have to do anything further for that, however, if you aren’t using the ‘Deploy to IIS’ step there are also community steps to start these back up.

I hope that’s helpful, but let us know if not!

Best,
Patrick

Hi @patrick.smergut,

The target server runs behind a load balancer and serves the requests with session stickiness enabled. I’m currently using inbuilt deploy to IIS set up and looks like it stops/restart the App pool, which means the load balancer will not be having the App pool restart info and the requests will be failed. I’d prefer something that doesn’t stop the App pool and deploys the package on to the same directory so that once the old requests are served, IIS will automatically serves the requests from the new package.
I’m looking for something that i could deploy the new package without overriding the older package and point the physical path to the new one using post deploy scripts/variables. Please let me know the better way to handle and if possible provide more information on post deployment scripts.

Thanks,
SRK.

Hi @kondasankeerthreddy

Apologies if this has been asked before, but looking at your desired state (e.g. wanting to avoid file locks etc), is there a reason you wouldn’t want to use the standard Octopus functionality with the IIS step, e.g. to let Octopus handle the directory where the webapp is stored on disk?

Octopus handles the directory creation for a new folder to avoid the file lock issues you’ve described.
You also get the benefit of retention policies handling clean-u of the old files and folders.

You can see the process that Octopus goes through here:

Having a custom install directory means you have to do all of the work that Octopus already handles for you by default.

The other option you could consider is taking the server out of whatever load balancer technology your using, typically by draining the node, then when its finished processing requests, use the built-in step to deploy your site to IIS.

Best,

Hi @mark.harrison,
The reason behind not using octopus managed location (C:\Octopus\Applications) but trying to deploy the package to (C:\webapps\app_directory$version_1) is simply due to security standards(think of exposing only few directories on disk). My question here would be can i deploy to (C:\webapps\app_directory$version_2) and point the physical path to the later after the deployment is completed? If yes, what variables are best suited for this?

Thanks,
SRK.

Hi @kondasankeerthreddy

Thanks for the clarification.

You can deploy to any directory you like with the custom installation directory option as you’re already using.

I’m wondering if there might be a way to do it using a script step that runs before the IIS step. The step would run against the deployment target and would need to perform the following steps (pseudo-code):

  1. Query IIS to see the path that the site is already installed to (C:\webapps\app_directory$version_1 in your example)
  2. Next it would calculate the new path (C:\webapps\app_directory$version_2 in your example)
  3. A new Octopus output variable would be created with the new path for the site
  4. The IIS step would use the Output variable as the custom install directory

You would also need to clear-up the contents from the previously installed directory (C:\webapps\app_directory$version_1 in your example) to avoid disk space issues.

You wouldn’t need any specific special variables per-se, just the use of the output variable for the custom install directory option.

Best,

Hi @mark.harrison,

Thanks for the detailed information.

I’m trying the below and it seems to work, please let me know if i would run into any potential issues:

  1. Using only one step which is Deploy to IIS and configured custom installation directory like this:
    C:\webapps\app_directory\app_folder_#{Octopus.Release.Number}
  2. with this, it is simply uploading the package with the latest version number and updating the physical path to the newly deployed package.

My questions around this be:

  1. Does inbuilt IIS deploy step starts App pool by default? (it doesn’t seem like and i prefer not to restart)
  2. Does changing the physical path would affect in flight requests which are being served from the earlier location? (I’m assuming it won’t unless IIS deploy stop/restart the App pool)

Please let me know if you have any info around this.

Regards,
SRK.

The issue with your approach using the release number won’t work for a redeploy of the same version. You will continue to see potential file locking issues.

The built in step will start the app pool if the option start web site is ticked in the step I believe but you could check the code here:

With regards to your last question:

Does changing the physical path would affect in flight requests

I believe it will yes. Any change to the IIS metabase for the site will result in a potential application recycle meaning requests in flight will be lost. This is why draining a node in your load balancer offers the best chance to mitigate this.

Best,

Hi,
with C:\webapps\app_directory\app_folder_#{Octopus.Release.Number} this set up it would have issues if we release same version again, but with the octopus managed deployments this doesn’t seem to a problem. If we release the same version again, it doesn’t try to override the earlier one but puts a new copy.
ex: 3.31.0-alpha.31898 → earlier version
3.31.0-alpha.31898_1 —> copy with the redeploy and physical path is automatically pointed to this one.

How do i achieve the similar behavior with my custom installation directory? Any variable i can use on
C:\webapps\app_directory\app_folder_#{Octopus.Release.Number} +?.

Any variable that could be unique on each release (even if it’s a redeployment) would work.

Please suggest.

Thanks,
SRK.

Hi @kondasankeerthreddy

Octopus will generate a unique folder, but only when its not using the Custom Install directory. Since you want to use this option, the unique folder won’t be generated as a variable for you to use.

You can create a unique folder as I described earlier, but this would have to be a script step that runs before the IIS step, since you would need to make use of Output variables, as you can’t create variables in the pre or post deployment steps for use in the IIS step.

The script itself would need to be determined by you based on whatever logic you decide is relevant. We have a general policy not to write scripts for our customers as we feel it’s important you own it.

You could simply test to see if the path exists, and if it does, increment a number and add that to a working variable and check the next path etc.

Best,