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:
- 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.
- Run a Script — runs inline PowerShell on the Tentacle, for example to restart IIS or update a config file.
- 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.