Skip to main content

How to Run an ASP.NET Core App as Production on Your Machine

· 5 min read
Jagdish Kumawat
Founder @ Dewiride

A lot of what differs in production never runs on your machine, until you make it. dotnet run --no-launch-profile starts an ASP.NET Core app as Production, so you can see those differences before your users do.

Why Not Just Set the Variable?​

dotnet run uses launchSettings.json, whose profile sets ASPNETCORE_ENVIRONMENT=Development, and Microsoft's documentation says "Environment values set in launchSettings.json override values set by the system environment." So a variable in your shell doesn't change it. Fixed: dotnet run -e Staging Still Starts in Development has the details.

Step 1: Run with No Profile​

With no profile and no variable, the environment defaults to Production. User-secrets aren't read in Production, so the connection string has to come from an environment variable. ASPNETCORE_URLS sets the address, because the profile that used to set it isn't there:

Terminal
ASPNETCORE_URLS=http://localhost:5190 ConnectionStrings__Inventory="Server=127.0.0.1;Port=3306;Database=inventory;User ID=inventory_app;Password=$(grep '^MYSQL_PASSWORD=' .env | cut -d= -f2-);SslMode=Required" dotnet run --no-launch-profile --project src/Dewiride.Inventory.Api
API log (shortened)
{"Timestamp":"2026-11-06T06:15:08.353Z","EventId":0,"LogLevel":"Information","Category":"Microsoft.Hosting.Lifetime","Message":"Hosting environment: Production","State":{"EnvName":"Production","{OriginalFormat}":"Hosting environment: {EnvName}"}}

The API starting with Hosting environment: Production in its JSON log.

Step 2: See What Changes​

Here's what I saw on a real API:

With no connection string at all, it stops right away, because this app checks at startup. In Development, user-secrets hid that this was needed:

Output
Unhandled exception. System.InvalidOperationException: The connection string 'ConnectionStrings:Inventory' is missing. In development, set it with dotnet user-secrets. Everywhere else, set the ConnectionStrings__Inventory environment variable.

Development-only endpoints are gone:

Status codes
/openapi/v1.json 404
/scalar/v1 404

Everything in appsettings.Development.json is gone, such as verbose logging. Here, that means no SQL statements in the log.

Errors stop showing detail. Any IsDevelopment block in your own code stops running too. How to Run Code Only in Development in ASP.NET Core explains that.

What to Check While You're There​

CheckWhat you want to see
It startsWith a clear error if a setting is missing
The API's documentation404
A bad requestA clean error, with no stack trace
The logNo passwords, and no personal data
Requests with the database stoppedA 503, not a hang

The Other Ways​

dotnet run can set it for one run, with the profile still in use for the rest:

Terminal
dotnet run -e ASPNETCORE_ENVIRONMENT=Production --project src/Dewiride.Inventory.Api

For the closest match to a server, publish it and run that, with the same two variables set:

Terminal
dotnet publish src/Dewiride.Inventory.Api -c Release -o publish
cd publish
dotnet Dewiride.Inventory.Api.dll

Start it from inside that folder. From anywhere else, appsettings.json is ignored, with no error.

Common Mistakes​

MistakeWhat happensDo this instead
Setting ASPNETCORE_ENVIRONMENT in the shell onlyThe launch profile overrides itUse --no-launch-profile
Expecting user-secrets to loadThey're Development onlyUse an environment variable
Leaving variables set in PowerShellLater runs use themRemove them when you're done

Troubleshooting​

SymptomLikely causeFix
Hosting environment: DevelopmentA profile, or a variable left overThe fix
The connection string … is missingUser-secrets aren't read hereSet the variable
It listens on port 5000No URL was setSet ASPNETCORE_URLS
Log levels look wrong from a published folderIt started in another folderThe fix

Conclusion​

dotnet run --no-launch-profile gives you Production, with no user-secrets and no developer pages. Run your app that way before you ship it, and check that what you see is what you want.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.