Windows NFS File Storage

Follow the steps below to configure NFS on a Windows Server for Octopus Deploy to use.

  1. Install NFS on the Windows VM

    On the Windows VM, open PowerShell as an administrator, and install the NFS client:

    # Install the NFS client
    Install-WindowsFeature -Name NFS-Client 
    

    Restart the Windows VM instance as prompted, then reconnect.

  2. Configure the user ID used by the NFS client

    In PowerShell, run the following commands to create two new registry entries, AnonymousUid and AnonymousGid:

    New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\ClientForNFS\CurrentVersion\Default" `
     -Name "AnonymousUid" -Value "0" -PropertyType DWORD
    
    New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\ClientForNFS\CurrentVersion\Default" `
     -Name "AnonymousGid" -Value "0" -PropertyType DWORD
    
  3. Restart the NFS client service

    nfsadmin client stop
    
    nfsadmin client start
    
  4. Create a batch file (.bat or .cmd) to mount the NFS share.

    net use X: \\your-nfs-share\share-name
    

    Substituting the placeholders with your own values:

    • X: with the mapped drive letter you want
    • your-nfs-share with either the host name or IP address of the Filestore instance
    • share-name with the Filestore instance share name
  5. Create a Windows Scheduled Task to run at system startup to mount the NFS share using the batch file.

    Below is an example scheduled task for mounting an NFS volume. Remember to substitute C:\OctoHA\MountNfsShare.cmd with the path to your batch file and ensure the task is set to run as LocalSystem.

    <?xml version="1.0" encoding="UTF-16"?>
    <Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
      <RegistrationInfo>
        <URI>\OctopusDeploy - mount nfs volume</URI>
      </RegistrationInfo>
      <Triggers>
        <BootTrigger>
          <Enabled>true</Enabled>
        </BootTrigger>
      </Triggers>
      <Principals>
        <Principal id="Author">
          <UserId>S-1-5-18</UserId>
          <RunLevel>HighestAvailable</RunLevel>
        </Principal>
      </Principals>
      <Settings>
        <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
        <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
        <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
        <AllowHardTerminate>true</AllowHardTerminate>
        <StartWhenAvailable>false</StartWhenAvailable>
        <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
        <IdleSettings>
          <StopOnIdleEnd>true</StopOnIdleEnd>
          <RestartOnIdle>false</RestartOnIdle>
        </IdleSettings>
        <AllowStartOnDemand>true</AllowStartOnDemand>
        <Enabled>true</Enabled>
        <Hidden>true</Hidden>
        <RunOnlyIfIdle>false</RunOnlyIfIdle>
        <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
        <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
        <WakeToRun>false</WakeToRun>
        <ExecutionTimeLimit>PT1H</ExecutionTimeLimit>
        <Priority>5</Priority>
      </Settings>
      <Actions Context="Author">
        <Exec>
          <Command>C:\OctoHA\MountNfsShare.cmd</Command>
        </Exec>
      </Actions>
    </Task>
    

    You can add multiple Actions to a Scheduled task. If you want to be sure the NFS share is mounted before the Octopus Service is started, you can set the service Startup Type to Manual, and add the following command to run after the NFS share is mounted:

    C:\Program Files\Octopus Deploy\Octopus\Octopus.Server.exe" checkservices --instances OctopusServer
    
    <Exec>
      <Command>"C:\Program Files\Octopus Deploy\Octopus\Octopus.Server.exe"</Command>
      <Arguments>checkservices --instances OctopusServer</Arguments>
    </Exec>
    
    

    This is in effect the same when using the watchdog command to configure a scheduled task to monitor the Octopus Server service.

  6. Create folders in your NFS share for the Artifacts, Packages, TaskLogs, Imports, and EventExports.

  7. Create the symbolic links for the Artifacts, Packages, TaskLogs, Imports, and EventExports folders.

    Run the following PowerShell script, substituting the placeholder values with your own:

    # Create the local folder to use to create the symbolic links within.
    $LocalFolder="C:\OctopusShared"
    
    if (-not (Test-Path -Path $LocalFolder)) {
       New-Item -ItemType directory -Path $LocalFolder    
    }
    
    $NfsShare = "\\your-nfs-share\share-name"
    
    # Create symbolic links
    $ArtifactsFolder = Join-Path -Path $LocalFolder -ChildPath "Artifacts"
    if (-not (Test-Path -Path $ArtifactsFolder)) {
        New-Item -Path $ArtifactsFolder -ItemType SymbolicLink -Value "$NfsShare\Artifacts"
    }
    
    $PackagesFolder = Join-Path -Path $LocalFolder -ChildPath "Packages"
    if (-not (Test-Path -Path $PackagesFolder)) {
        New-Item -Path $PackagesFolder -ItemType SymbolicLink -Value "$NfsShare\Packages"
    }
    
    $TaskLogsFolder = Join-Path -Path $LocalFolder -ChildPath "TaskLogs"
    if (-not (Test-Path -Path $TaskLogsFolder)) {
        New-Item -Path $TaskLogsFolder -ItemType SymbolicLink -Value "$NfsShare\TaskLogs"
    }
    
    $ImportsFolder = Join-Path -Path $LocalFolder -ChildPath "Imports"
    if (-not (Test-Path -Path $ImportsFolder)) {
        New-Item -Path $ImportsFolder -ItemType SymbolicLink -Value "$NfsShare\Imports"
    }
    
    $EventExportsFolder = Join-Path -Path $LocalFolder -ChildPath "EventExports"
    if (-not (Test-Path -Path $EventExportsFolder)) {
        New-Item -Path $EventExportsFolder -ItemType SymbolicLink -Value "$NfsShare\EventExports"
    }
    

    Remember to create the folders in the NFS share before trying to create the symbolic links.

Once you’ve completed those steps, install Octopus and then when you’ve done that on all nodes, run the path command to change the paths to the shared storage:

& 'C:\Program Files\Octopus Deploy\Octopus\Octopus.Server.exe' path `
--artifacts "C:\OctopusShared\Artifacts" `
--nugetRepository "C:\OctopusShared\Packages" `
--taskLogs "C:\OctopusShared\TaskLogs" `
--imports "C:\OctopusShared\Imports" `
--eventExports "C:\OctopusShared\EventExports"

Changing the path only needs to be done once, and not on each node as the values are stored in the database.

Help us continuously improve

Please let us know if you have any feedback about this page.

Send feedback

Page updated on Tuesday, July 30, 2024