How to Install and Configure Octopus Deploy on Windows Server 2025

Octopus Deploy is a dedicated deployment automation server that sits between your CI build system and your production infrastructure. While tools like Jenkins and Azure DevOps can deploy code, Octopus specialises in it — providing environment management, structured release pipelines, deployment approvals, runbooks for operational tasks, and detailed audit trails. On Windows Server 2025, Octopus Server runs as a Windows Service backed by a SQL Server database, and it communicates with deployment targets through a lightweight agent called the Tentacle. This tutorial covers installing Octopus Server, configuring it through the Octopus Manager, installing Tentacles on target servers, structuring environments, defining a deployment project with steps, and creating a Runbook for routine operational tasks.

Prerequisites

  • Windows Server 2025 (minimum 4 vCPU, 8 GB RAM for Octopus Server)
  • SQL Server 2019 or 2022 (Express is supported for small deployments; Standard or Enterprise for production)
  • A SQL Server database created for Octopus (e.g., OctopusDeploy)
  • A valid Octopus Deploy license (free tier available at octopus.com)
  • Administrator privileges on all servers involved
  • WinRM or firewall access: Tentacle listening mode uses TCP port 10933
  • .NET Framework 4.8 (included in Windows Server 2025 by default)

Step 1: Prepare SQL Server for Octopus

Octopus Server requires a dedicated SQL Server database. If you are using an existing SQL Server instance, create the database and a dedicated SQL login with db_owner rights on that database. If SQL Server is not yet installed, install SQL Server Express for small environments.

# Download SQL Server 2022 Express
$SqlUrl  = "https://go.microsoft.com/fwlink/p/?linkid=2216019&clcid=0x409"
$SqlExe  = "$env:TEMPSQL2022Express.exe"
Invoke-WebRequest -Uri $SqlUrl -OutFile $SqlExe -UseBasicParsing

# Silent install of SQL Server Express with named instance SQLEXPRESS
Start-Process -FilePath $SqlExe -ArgumentList @(
    "/ACTION=Install",
    "/FEATURES=SQLEngine",
    "/INSTANCENAME=SQLEXPRESS",
    "/SQLSVCACCOUNT=`"NT AUTHORITYNetwork Service`"",
    "/SQLSYSADMINACCOUNTS=`"BUILTINAdministrators`"",
    "/AGTSVCSTARTUPTYPE=Disabled",
    "/BROWSERSVCSTARTUPTYPE=Automatic",
    "/TCPENABLED=1",
    "/NPENABLED=0",
    "/IACCEPTSQLSERVERLICENSETERMS",
    "/QUIET"
) -Wait -NoNewWindow

# Enable TCP/IP in SQL Server Configuration Manager via PowerShell
Import-Module SqlServer -ErrorAction SilentlyContinue

# Create Octopus database using sqlcmd
sqlcmd -S "localhostSQLEXPRESS" -Q @"
IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = 'OctopusDeploy')
BEGIN
    CREATE DATABASE [OctopusDeploy]
    COLLATE SQL_Latin1_General_CP1_CI_AS;
    PRINT 'Database OctopusDeploy created.'
END
GO

-- Create a dedicated login
IF NOT EXISTS (SELECT name FROM sys.server_principals WHERE name = 'octopus_svc')
BEGIN
    CREATE LOGIN [octopus_svc] WITH PASSWORD = 'Str0ngP@ssword2025!';
    PRINT 'Login octopus_svc created.'
END
GO

USE [OctopusDeploy];
GO
IF NOT EXISTS (SELECT name FROM sys.database_principals WHERE name = 'octopus_svc')
BEGIN
    CREATE USER [octopus_svc] FOR LOGIN [octopus_svc];
    ALTER ROLE db_owner ADD MEMBER [octopus_svc];
    PRINT 'User octopus_svc added to db_owner.'
END
GO
"@

Step 2: Install Octopus Server

Download the Octopus Server MSI from octopus.com and install it silently. The MSI installs the application files and registers the Octopus Windows Service; actual configuration is done afterwards via the Octopus Manager CLI (Octopus.Server.exe).

# Download Octopus Server MSI
$OctoVersion = "2024.3.12063"
$OctoUrl     = "https://download.octopusdeploy.com/octopus/Octopus.$OctoVersion-x64.msi"
$OctoMsi     = "$env:TEMPOctopusServer.msi"

Write-Host "Downloading Octopus Server $OctoVersion..."
Invoke-WebRequest -Uri $OctoUrl -OutFile $OctoMsi -UseBasicParsing

# Silent MSI install — installs files only, no service configuration yet
Start-Process msiexec.exe -ArgumentList "/i `"$OctoMsi`" /qn /norestart RUNMANAGERONEXIT=no" `
    -Wait -NoNewWindow

Write-Host "Octopus Server MSI installed."

Step 3: Configure Octopus Server via the Command Line

The Octopus.Server.exe command-line tool handles initial configuration: creating the master key, connecting to the database, setting up the admin account, and configuring the web portal port. These steps can be scripted fully for automated provisioning.

$OctoExe = "C:Program FilesOctopus DeployOctopusOctopus.Server.exe"

# 1. Create the Octopus instance and connect it to the database
# The master key is generated automatically and stored in the registry.
# IMPORTANT: Back up the master key — without it, the database cannot be decrypted.
& $OctoExe create-instance `
    --instance   "OctopusServer" `
    --config     "C:OctopusOctopusServer.config"

& $OctoExe database `
    --instance         "OctopusServer" `
    --connectionString "Server=localhostSQLEXPRESS;Database=OctopusDeploy;User Id=octopus_svc;Password=Str0ngP@ssword2025!;TrustServerCertificate=true" `
    --create

# 2. Configure the admin user and web portal
& $OctoExe configure `
    --instance        "OctopusServer" `
    --webForceSSL     "false" `
    --webListenPrefixes "http://localhost:8080/" `
    --commsListenPort  10943 `
    --serverNodeName   "$env:COMPUTERNAME"

# 3. Create the initial admin user
& $OctoExe admin `
    --instance  "OctopusServer" `
    --username  "admin" `
    --email     "[email protected]" `
    --password  "AdminP@ss2025!"

# 4. Configure license (paste your license XML)
# & $OctoExe license --instance "OctopusServer" --licenseBase64 "BASE64_ENCODED_LICENSE"

# 5. Install and start the Windows Service
& $OctoExe service `
    --instance "OctopusServer" `
    --install `
    --stop `
    --start

Write-Host "Octopus Server service started. Web UI available at http://localhost:8080"

# 6. Retrieve and display the master key — STORE THIS SECURELY
& $OctoExe show-master-key --instance "OctopusServer"

Step 4: Install a Tentacle on a Deployment Target

The Tentacle is a lightweight Windows Service installed on each server that Octopus will deploy to. It communicates with Octopus Server over TCP port 10933. Tentacles support two communication modes: Listening (Tentacle opens a port and Octopus connects to it) and Polling (Tentacle polls Octopus Server, useful when the target is behind a firewall or NAT).

# Download Tentacle MSI
$TentacleUrl = "https://download.octopusdeploy.com/octopus/Octopus.Tentacle.2024.3.12063-x64.msi"
$TentacleMsi = "$env:TEMPOctopusTentacle.msi"

Invoke-WebRequest -Uri $TentacleUrl -OutFile $TentacleMsi -UseBasicParsing

# Silent install
Start-Process msiexec.exe -ArgumentList "/i `"$TentacleMsi`" /qn /norestart" -Wait -NoNewWindow

$TentacleExe = "C:Program FilesOctopus DeployTentacleTentacle.exe"

# Configure Tentacle in LISTENING mode (Octopus Server connects TO this Tentacle)
& $TentacleExe create-instance `
    --instance "Tentacle" `
    --config   "C:OctopusTentacleTentacle.config"

& $TentacleExe new-certificate `
    --instance    "Tentacle" `
    --if-blank `
    --export-file "C:OctopusTentacleTentacle.cer"

& $TentacleExe configure `
    --instance              "Tentacle" `
    --reset-trust `
    --app                   "C:OctopusApplications" `
    --port                  10933 `
    --noListen              "false"

# Trust the Octopus Server certificate (paste the server thumbprint from the Octopus web UI)
$OctoServerThumbprint = "PASTE_OCTOPUS_SERVER_THUMBPRINT_HERE"
& $TentacleExe configure `
    --instance      "Tentacle" `
    --trust         $OctoServerThumbprint

# Open firewall port for Tentacle
New-NetFirewallRule -DisplayName "Octopus Tentacle" `
    -Direction Inbound -Protocol TCP -LocalPort 10933 `
    -Action Allow -Profile Any

# Register the Tentacle with Octopus Server
& $TentacleExe register-with `
    --instance        "Tentacle" `
    --server          "http://octopus-server.contoso.local:8080" `
    --apiKey          "API-YOURAPIKEYHERE" `
    --name            "$env:COMPUTERNAME" `
    --env             "Development" `
    --role            "web-server" `
    --comms-style     TentaclePassive

# Install and start the Tentacle service
& $TentacleExe service `
    --instance "Tentacle" `
    --install `
    --stop `
    --start

Write-Host "Tentacle installed and registered with Octopus Server."

Configure Tentacle in Polling Mode

# Polling mode — Tentacle initiates outbound connection to Octopus Server
# Useful when target is behind NAT or strict firewall

& $TentacleExe configure `
    --instance  "Tentacle" `
    --noListen  "true"     # Do not open an inbound port

& $TentacleExe register-with `
    --instance        "Tentacle" `
    --server          "http://octopus-server.contoso.local:8080" `
    --apiKey          "API-YOURAPIKEYHERE" `
    --name            "$env:COMPUTERNAME-Polling" `
    --env             "Production" `
    --role            "app-server" `
    --comms-style     TentacleActive   # Active (polling) mode

& $TentacleExe service --instance "Tentacle" --install --stop --start

Step 5: Configure Environments in Octopus

Environments represent stages in your deployment pipeline. Creating them via the Octopus REST API allows scripted, repeatable environment setup without manual UI interaction.

$OctoBaseUrl = "http://localhost:8080"
$ApiKey      = "API-YOURAPIKEYHERE"
$Headers     = @{ "X-Octopus-ApiKey" = $ApiKey; "Content-Type" = "application/json" }

# Create environments: Development, Staging, Production
$Environments = @("Development", "Staging", "Production")

foreach ($Env in $Environments) {
    $Body = @{ Name = $Env; Description = "Auto-created by provisioning script" } | ConvertTo-Json
    $Response = Invoke-RestMethod -Uri "$OctoBaseUrl/api/environments" `
        -Method Post -Headers $Headers -Body $Body
    Write-Host "Created environment: $($Response.Name) (ID: $($Response.Id))"
}

# List all environments
$AllEnvs = Invoke-RestMethod -Uri "$OctoBaseUrl/api/environments/all" -Headers $Headers
$AllEnvs | ForEach-Object { Write-Host "$($_.Id)  $($_.Name)" }

Step 6: Create a Deployment Project and Process

A Project in Octopus encapsulates the deployment process — a sequence of steps that run in order. Common step types include deploying a package (copies files and runs scripts), running a PowerShell script, and sending Slack/email notifications.

# Create a project via the API
$ProjectGroupId = (Invoke-RestMethod "$OctoBaseUrl/api/projectgroups/all" -Headers $Headers |
    Where-Object { $_.Name -eq "Default Project Group" }).Id

$NewProject = @{
    Name           = "MyWebApplication"
    Description    = "Deploys MyWebApplication to all environments"
    ProjectGroupId = $ProjectGroupId
    LifecycleId    = "Lifecycles-1"   # Default lifecycle; retrieve real IDs from /api/lifecycles/all
} | ConvertTo-Json

$Project = Invoke-RestMethod -Uri "$OctoBaseUrl/api/projects" `
    -Method Post -Headers $Headers -Body $NewProject

Write-Host "Project created: $($Project.Name) (ID: $($Project.Id))"
Write-Host "Edit deployment process at: $OctoBaseUrl/app#/projects/$($Project.Id)/deployments/process"

In the Octopus web UI, add steps to the deployment process:

  1. Deploy a Package — selects a NuGet or ZIP package from the built-in feed, extracts it to the target directory, and runs pre/post-deploy scripts.
  2. Run a Script — runs inline PowerShell on the Tentacle, for example to restart IIS or update a config file.
  3. Send Slack Notification — community step template that posts a message when the deployment succeeds or fails.

Step 7: Create a Runbook for Operational Tasks

Runbooks are Octopus’s mechanism for operational scripts — restart services, run database backups, rotate secrets — that are not tied to a software release. They use the same environment and target infrastructure as deployment projects but are triggered on demand or on a schedule.

# Create a Runbook via the REST API
$Runbook = @{
    Name          = "Restart IIS Application Pools"
    Description   = "Recycles all application pools on web servers"
    ProjectId     = $Project.Id
    RunRetentionPolicy = @{
        QuantityToKeep    = 10
        ShouldKeepForever = $false
    }
} | ConvertTo-Json

$NewRunbook = Invoke-RestMethod -Uri "$OctoBaseUrl/api/$($Project.SpaceId)/runbooks" `
    -Method Post -Headers $Headers -Body $Runbook

Write-Host "Runbook created: $($NewRunbook.Name) (ID: $($NewRunbook.Id))"

# The Runbook script step (added via UI or API) would contain:
@'
# PowerShell script step content for the Runbook
$AppPools = Get-WebConfiguration -Filter "/system.applicationHost/applicationPools/add"

foreach ($Pool in $AppPools) {
    Write-Host "Recycling application pool: $($Pool.Name)"
    Restart-WebAppPool -Name $Pool.Name
}

Write-Host "All application pools recycled on $env:COMPUTERNAME at $(Get-Date -Format 'HH:mm:ss')."
'@

Step 8: Create a Release and Deploy

A Release bundles a specific version of your application (a NuGet package version) with its deployment process snapshot. Once created, a release can be promoted through environments (Dev → Staging → Production) without rebuilding.

# Create a release for version 1.0.0
$Release = @{
    ProjectId        = $Project.Id
    Version          = "1.0.0"
    SelectedPackages = @(
        @{
            ActionName         = "Deploy MyWebApplication"
            PackageReferenceName = ""
            Version            = "1.0.0"
        }
    )
} | ConvertTo-Json -Depth 5

$NewRelease = Invoke-RestMethod -Uri "$OctoBaseUrl/api/$($Project.SpaceId)/releases" `
    -Method Post -Headers $Headers -Body $Release

Write-Host "Release created: $($NewRelease.Version)"

# Deploy to Development environment
$DevEnvId = ($AllEnvs | Where-Object { $_.Name -eq "Development" }).Id

$Deployment = @{
    ReleaseId     = $NewRelease.Id
    EnvironmentId = $DevEnvId
    Comments      = "Automated deployment from provisioning script"
} | ConvertTo-Json

$NewDeployment = Invoke-RestMethod -Uri "$OctoBaseUrl/api/$($Project.SpaceId)/deployments" `
    -Method Post -Headers $Headers -Body $Deployment

Write-Host "Deployment started: $($NewDeployment.Id)"
Write-Host "View progress at: $OctoBaseUrl/app#/tasks/$($NewDeployment.TaskId)"

Conclusion

You have installed and configured a complete Octopus Deploy environment on Windows Server 2025: the Octopus Server backed by SQL Server, Tentacle agents registered in both Listening and Polling modes, structured Development, Staging, and Production environments, a deployment project with a defined process, and a Runbook for ad-hoc operational tasks. Octopus separates the build process (which belongs to your CI server) from the deployment process (which belongs to Octopus), giving teams fine-grained control over what gets deployed where and when — with full audit history and per-environment configuration variables. As your pipeline matures, explore Octopus’s variable sets for sharing configuration across projects, its built-in certificate management for rotating SSL certificates across environments, and its deployment target triggers to automatically deploy whenever a new release is created, enabling true continuous deployment to your development environment.