Web Deploy from Visual Studio to Production: Configuration Guide

FTP is fine for one-off uploads. The Plesk file manager works for first-time deploys. But once you're pushing builds multiple times a week, you want a deployment workflow that builds, packages, and ships in one click — without manually tracking which files changed. Web Deploy (also called MSDeploy) is Microsoft's answer: a publish protocol built directly into Visual Studio and IIS that handles incremental sync, configuration transformation, and remote installation in a single operation. This is the complete walkthrough for getting Web Deploy working from Visual Studio to a Plesk for Windows hosting plan.

What Web Deploy actually does

Web Deploy is a protocol + tool pair. The protocol describes how to package an IIS site (files, configuration, registry entries, certificates) and synchronize it with another IIS server. The tool, MSDeploy.exe, runs on both ends — client-side (your dev machine or CI server) and server-side (the IIS host).

What this means in practice:

Incremental sync — only files that changed since the last publish are uploaded. A 200-file ASP.NET Core publish typically transfers 10-30 changed files

Atomic-ish replacement — Web Deploy stages files in a temp location, then swaps them in. An ASP.NET Core app pool recycle happens once at the end, not per file

Configuration transformation — web.config values can be transformed at publish time based on the build configuration (Debug, Release, custom profiles)

Authentication — runs over HTTPS with username/password or certificate-based credentials

Built into Visual Studio — the Publish wizard generates a Web Deploy profile from a connection string the host provides

What you need before starting

Visual Studio 2022 (any edition, including the free Community) with the ASP.NET and web development workload

An Adaptive Web Hosting plan or any other Plesk for Windows host with Web Deploy enabled

Your Plesk login — you'll generate the Web Deploy credentials from the Plesk UI

An ASP.NET Core or classic ASP.NET project you want to deploy

The Web Deploy server-side component is pre-installed on every Adaptive Web Hosting plan — you don't need to ask us to enable it, and there's no per-deployment fee.

Step 1 — enable Web Deploy publishing in Plesk

From your Plesk dashboard:

Navigate to Websites & Domains → select your domain

Click Web Hosting Access (or "Web Hosting Settings" depending on Plesk version)

Find the Microsoft Web Deploy publishing section

Check Allow Microsoft Web Deploy publishing

Plesk displays the connection settings:

Server (publish URL) — typically https://your.host:8172/msdeploy.axd

Site name — your domain

Username — usually a Web Deploy-specific account, not your main Plesk login

Password — provided by Plesk

Save

Copy these four values somewhere safe — you'll need them in the Visual Studio publish profile. The password is sometimes displayed only once on creation; if you lose it, regenerate from the same page.

Step 2 — create a publish profile in Visual Studio

Open your ASP.NET Core (or classic ASP.NET) project in Visual Studio.

Right-click the project in Solution Explorer → Publish

Click + New profile (or "Add a publish profile" if this is your first)

Choose Web Server (IIS) as the target

Choose Web Deploy as the specific method

Fill in the connection details from Step 1:

Server: your Plesk-supplied URL (e.g., your.host:8172)

Site name: your domain (e.g., example.com)

User name: from Plesk

Password: from Plesk

Destination URL: https://example.com/ (used to open the site after publish)

Click Validate Connection — you should see a green checkmark

Click Finish

If the connection validation fails, the most common cause is the username being wrong (it's the Web Deploy-specific account, not your Plesk login). Re-check the credentials.

Step 3 — first publish

With the profile created, the Publish tab shows a summary of the deployment settings and a big blue Publish button.

Before clicking it for the first time, expand Settings on the publish tab:

Configuration: Release

Target Framework: matches your .csproj (e.g., net10.0)

Deployment Mode: Framework-dependent (don't choose Self-Contained — Adaptive's servers already have the runtime)

Target Runtime: Portable for framework-dependent

File Publish Options:

Check Remove additional files at destination on first deploy to clean out any placeholder files

Uncheck it for subsequent deploys to preserve logs/, uploads/, or other runtime-generated content

Click Publish. Visual Studio:

Builds the project in Release configuration

Runs dotnet publish internally to produce the publish output

Connects to Web Deploy at your host

Syncs files incrementally (first publish = all files; subsequent = changed only)

Triggers an app pool recycle on the host so the new build is picked up

Opens the destination URL in your browser to verify

For a typical small-to-medium ASP.NET Core app, first publish takes 30-90 seconds (most of it the file transfer over HTTPS). Subsequent publishes typically complete in 5-15 seconds.

Step 4 — configuration transformations

One reason to use Web Deploy over plain FTP: per-environment configuration. Your appsettings.json in source control has dev-friendly defaults; your production needs different connection strings, API keys, and logging levels.

For ASP.NET Core, the convention is appsettings.Production.json alongside the main appsettings.json. ASP.NET Core merges them at runtime based on the ASPNETCORE_ENVIRONMENT environment variable. Web Deploy handles this if:

You include appsettings.Production.json in your project (with <Content Update="appsettings.Production.json" CopyToPublishDirectory="PreserveNewest"/> in the .csproj)

You set ASPNETCORE_ENVIRONMENT=Production on the host. Plesk's IIS Manager tool (under Websites & Domains) lets you set application pool environment variables; or you can set it inline in web.config:

<aspNetCore processPath="dotnet" arguments=".\YourApp.dll"

stdoutLogEnabled="false"

hostingModel="inprocess">

<environmentVariables>

<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Production" />

</environmentVariables>

</aspNetCore>

Step 5 — protect secrets

Never commit production secrets to source control. Connection strings with passwords, API keys, signing keys — none of these belong in appsettings.Production.json if that file is tracked by git. Options:

Option A: Environment variables on the host

Set environment variables via the web.config <environmentVariables> block above. The values live in IIS configuration, not in your source. The trade-off: every deploy that includes a new web.config overwrites the values — you'd need a sticky out-of-band web.config override or set the variables at the IIS Application Pool level (Plesk's IIS Manager extension).

Option B: User secrets in development + environment variables in production

ASP.NET Core's User Secrets system stores dev-time values outside your source tree. For production, the same IConfiguration pipeline reads from environment variables, so you set them once at the host and your code reads them the same way locally and in production.

Option C: Azure Key Vault or AWS Secrets Manager

For more elaborate setups, your app fetches secrets from a cloud secret store at startup. Adds a network dependency but centralizes secret rotation. Overkill for many small apps; appropriate for anything with regulatory requirements or many environments.

Step 6 — Web Deploy from CI (GitHub Actions, Azure DevOps)

Visual Studio publishes are great for development. For production releases, you want builds to happen on a server, not a developer's laptop. Web Deploy works identically from CI.

GitHub Actions

Add .github/workflows/deploy.yml to your repo:

name: Deploy to Adaptive Web Hosting

on:

push:

branches: [main]

jobs:

deploy:

runs-on: windows-latest

steps:

- uses: actions/checkout@v4

- uses: actions/setup-dotnet@v4

with:

dotnet-version: '10.0.x'

- name: Publish

run: dotnet publish -c Release -o ./publish

- name: Web Deploy

shell: cmd

run: |

"C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync ^

-source:contentPath=".\publish" ^

-dest:contentPath="${{ secrets.WEBDEPLOY_SITE }}",computerName="${{ secrets.WEBDEPLOY_SERVER }}",userName="${{ secrets.WEBDEPLOY_USER }}",password="${{ secrets.WEBDEPLOY_PASSWORD }}",authtype="Basic" ^

-allowUntrusted

Store the four Web Deploy values as repository secrets in GitHub:

WEBDEPLOY_SITE — your site/domain name

WEBDEPLOY_SERVER — the full URL (e.g., https://your.host:8172/msdeploy.axd?site=your.com)

WEBDEPLOY_USER — the Plesk Web Deploy username

WEBDEPLOY_PASSWORD — the Plesk Web Deploy password

Every push to main now builds, publishes, and ships automatically.

Azure DevOps

Use the IIS Web App Deploy task or the lower-level Azure App Service Deploy task with WebDeploy as the deployment method. The configuration is similar to GitHub Actions — the same four credentials, pointed at the same MSDeploy endpoint.

Common pitfalls

"Could not connect to the remote computer"

Web Deploy uses port 8172 by default. If your local network or corporate firewall blocks outbound 8172, the connection fails entirely. Test with Test-NetConnection -ComputerName your.host -Port 8172 from PowerShell. On Adaptive Web Hosting, port 8172 is open and Web Deploy is reachable from any internet-connected client.

"Web Deploy detected updates that aren't included in this publish"

Visual Studio is warning that the destination has files your local publish doesn't have — usually logs/ entries, uploads/ directories, or files placed by Plesk. If you click "Yes" to delete, you lose those. Better: uncheck "Remove additional files at destination" in Publish settings after the first deploy.

"Access is denied"

The Web Deploy username is the dedicated Plesk Web Deploy account, NOT your main Plesk login. They're often different. Generate or re-fetch the credentials from Plesk's Web Hosting Access page.

App pool doesn't recycle after publish

This is rare with Web Deploy — the protocol triggers a recycle by writing to web.config as the last step. If your app is stuck on the old version, check whether web.config was actually updated (its modified timestamp should be the publish time). If not, your Web Deploy permissions might be limited to file write but not config write. Re-check the Plesk Web Deploy account permissions.

Database migrations don't run automatically

Web Deploy ships files; it doesn't run EF Core migrations. You either run migrations in your Program.cs startup (acceptable for small apps), include a dotnet ef database update step in your CI pipeline before the Web Deploy step, or generate an idempotent SQL script and apply it manually:

dotnet ef migrations script --idempotent --output migration.sql

Then apply migration.sql via SQL Server Management Studio.

HTTP 500.30 after Web Deploy

The app published successfully but won't start. Almost always a runtime version mismatch, missing config, or wrong app pool "Managed Code" setting. See our HTTP 500.30 troubleshooting guide for the diagnostic flow.

Web Deploy vs FTP vs GitHub Actions direct file copy

FTP/FTPSWeb DeployDirect Plesk API

Setup complexityLowMedium (one-time)Medium

Incremental syncManualAutomaticDepends on script

App pool recycleManualAutomaticAutomatic via API

Config transformationNoneBuilt-inNone

AuthenticationUsername + passwordUsername + password or certAPI token

VS integrationYesYes (best)No

CI integrationYesYes (best)Custom scripting

Speed (typical small app)30-90s full upload each time5-15s incrementalVaries

For one-off uploads or low-frequency deploys, FTP is fine. For active development or CI/CD, Web Deploy is the obvious choice — the incremental sync alone saves substantial time per deploy.

Frequently asked questions

Does Web Deploy work for Blazor Server and Blazor WebAssembly apps?

Yes — both are just ASP.NET Core projects from a publish perspective. The Web Deploy profile generated by Visual Studio handles either render mode identically. See our complete Blazor hosting guide for Blazor-specific configuration once the app is deployed.

Can I deploy to multiple hosts at once?

Visual Studio supports multiple publish profiles per project — create separate Web Deploy profiles for staging and production, then publish to each individually. For simultaneous parallel deployment (e.g., to multiple production servers behind a load balancer), use a CI pipeline that runs multiple Web Deploy steps in parallel.

What about deployment slots like Azure App Service has?

Web Deploy doesn't directly support slot-swap. The common workaround is staging-subdomain pattern: deploy to staging.yourdomain.com, validate, then deploy to www.yourdomain.com. Both subdomains can live on the same Adaptive Web Hosting plan with separate IIS sites. Or, for true zero-downtime, that's the use case for Azure App Service deployment slots (see Azure vs Adaptive comparison).

Is Web Deploy secure?

Yes — Web Deploy runs over HTTPS on port 8172 with username+password authentication. The transit is encrypted; the credentials are sent under TLS. The server-side endpoint also requires IIS-level authorization, so the Web Deploy user can only write to the specific site you configured. For higher security, certificate-based authentication is supported as an alternative to password.

Can I exclude specific files from the publish?

Yes — in your .csproj file, add <Content Remove="path/to/file" /> for individual files or use globs like <Content Remove="logs/**" />. The MSBuild publish task respects these and excludes the matched files from the publish output.

What about rollback?

Web Deploy doesn't include native rollback. The clean pattern: keep the last N Web Deploy packages from your CI as artifacts; if a deploy goes bad, re-publish the previous package. Plesk's daily automatic backups also let you restore the file state from before the deploy, though that's slower and operates at the whole-site level.

Does Adaptive Web Hosting include Web Deploy?

Yes — Microsoft Web Deploy is pre-installed and enabled on every plan from the $9.49 Developer tier up. There's no add-on fee, no upgrade required, no support ticket needed to enable it. Generate the credentials from your Plesk dashboard and you're ready to publish.

What's the difference between Web Deploy and "Folder publish"?

Visual Studio's Folder publish target writes the publish output to a local directory — useful if you want to manually FTP or copy. Web Deploy publish target ships files directly over the network to the remote host. For one-step Visual Studio publish, Web Deploy is the right answer; for CI pipelines that do their own upload (e.g., via a custom step), Folder publish is more flexible.

Bottom line

Web Deploy turns ASP.NET deployment into a one-click operation from Visual Studio and a single CI step in GitHub Actions or Azure DevOps. The protocol handles incremental sync, app pool recycle, and config transformation automatically — saving substantial time per deploy compared to manual FTP uploads.

On Adaptive Web Hosting plans, Web Deploy is pre-installed and enabled on every plan. Combine it with the complete ASP.NET Core deployment walkthrough for the broader setup steps and free Let's Encrypt SSL via Plesk for free HTTPS, and you have a production-ready deployment pipeline that costs $9.49/month and supports CI/CD out of the box. Every plan includes a 30-day money-back guarantee. View hosting plans or talk to an ASP.NET expert.

Back to Blog