Running Umbraco locally from published folder
# help-with-umbraco
j
Morning! How do I run an Umbraco application from a published folder? I was expecting to be able to run
dotnet <ApplicationName>.dll
from the published folder ((MS docs)[https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/?view=aspnetcore-6.0#run-the-published-app-locally]) but when creating a fresh project this command is hanging (i.e. not finishing, no console messages). Steps to reproduce: - Create new Umbraco v10.7 instance - Run in debug mode, create a basic homepage - Publish to folder - Go to folder, run
dotnet <ApplicationName>.dll
- ....wait forever? All advice greatly appreciated! Rich https://cdn.discordapp.com/attachments/1158658538600673311/1158658539024306246/image.png?ex=651d0c5a&is=651bbada&hm=b748e2ce367831c2b18ecb557b653f5d4704bbbb5b0584ff6864ac6ff7e66b15&
a
@jacksorjacksor (Richard Jackson) I believe the syntax is like this:
dotnet run --project "MyProject"
j
a
Ah you're right!
m
so just had a go
dotnet publish --no-build --no-restore -c Release /p:EnvironmentName=Development -o ..\..\publish
dotnet exec www.dll --verbosity d
eventually errored in a couple of minutes.. with a failed to bind.. so maybe specify a port? https://cdn.discordapp.com/attachments/1158658538600673311/1158679451673038868/message.txt?ex=651d1fd4&is=651bce54&hm=bb95c39492d91de9716b63866cb3c92b7e5209ade4cc6fefb3880ad3d7ce5fff&
--urls=https://localhost:44489/
???
Copy code
json
{"@t":"2023-10-03T08:15:52.7047929Z","@mt":"The HostOptions.BackgroundServiceExceptionBehavior is configured to StopHost. A BackgroundService has thrown an unhandled exception, and the IHost instance is stopping. To avoid this behavior, configure this to Ignore; however the BackgroundService will not be restarted.","@l":"Fatal","@x":"System.OperationCanceledException: The operation was canceled.\r\n   at System.Threading.CancellationToken.ThrowOperationCanceledException()\r\n   at System.Threading.SemaphoreSlim.WaitUntilCountOrTimeoutAsync(TaskNode asyncWaiter, Int32 millisecondsTimeout, CancellationToken cancellationToken)\r\n   at Umbraco.Cms.Infrastructure.HostedServices.BackgroundTaskQueue.DequeueAsync(CancellationToken cancellationToken)\r\n   at Umbraco.Cms.Infrastructure.HostedServices.QueuedHostedService.BackgroundProcessing(CancellationToken stoppingToken)\r\n   at Umbraco.Cms.Infrastructure.HostedServices.QueuedHostedService.ExecuteAsync(CancellationToken stoppingToken)\r\n   at Microsoft.Extensions.Hosting.Internal.Host.TryExecuteBackgroundServiceAsync(BackgroundService backgroundService)","EventId":{"Id":10,"Name":"BackgroundServiceStoppingHost"},"SourceContext":"Microsoft.Extensions.Hosting.Internal.Host","ProcessId":49768,"ProcessName":"dotnet","ThreadId":12,"ApplicationId":"43b4f000b61af45719d8ce43246f4c2fe0c7d6c2","MachineName":"MINI-7","Log4NetLevel":"FATAL","EnvironmentName":"Production"}
interesting.. looks like you need to also pass the environment name to the dotnet exex www.dll? as don't want production running!
so maybe..
dotnet exec www.dll --verbosity d --urls=https://localhost:44489/  -c Release /p:EnvironmentName=Development
d
And is there not a
.exe
variant of your application present in your publish output folder? I do believe that's the one that you're supposed to be running
m
🀷 just responding to the question and where is says you can run from a dll...https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet#examples
.\www.exe urls=https://localhost:44589
same boot failed with the wrong environment name..
Copy code
{
  "@t": "2023-10-03T08:54:22.7270781Z",
  "@mt": "The HostOptions.BackgroundServiceExceptionBehavior is configured to StopHost. A BackgroundService has thrown an unhandled exception, and the IHost instance is stopping. To avoid this behavior, configure this to Ignore; however the BackgroundService will not be restarted.",
  "@l": "Fatal",
  "@x": "System.OperationCanceledException: The operation was canceled.\r\n   at System.Threading.CancellationToken.ThrowOperationCanceledException()\r\n   at System.Threading.SemaphoreSlim.WaitUntilCountOrTimeoutAsync(TaskNode asyncWaiter, Int32 millisecondsTimeout, CancellationToken cancellationToken)\r\n   at Umbraco.Cms.Infrastructure.HostedServices.BackgroundTaskQueue.DequeueAsync(CancellationToken cancellationToken)\r\n   at Umbraco.Cms.Infrastructure.HostedServices.QueuedHostedService.BackgroundProcessing(CancellationToken stoppingToken)\r\n   at Umbraco.Cms.Infrastructure.HostedServices.QueuedHostedService.ExecuteAsync(CancellationToken stoppingToken)\r\n   at Microsoft.Extensions.Hosting.Internal.Host.TryExecuteBackgroundServiceAsync(BackgroundService backgroundService)",
  "EventId": {
    "Id": 10,
    "Name": "BackgroundServiceStoppingHost"
  },
  "SourceContext": "Microsoft.Extensions.Hosting.Internal.Host",
  "ProcessId": 29348,
  "ProcessName": "www",
  "ThreadId": 19,
  "ApplicationId": "43b4f000b61af45719d8ce43246f4c2fe0c7d6c2",
  "MachineName": "MINI-7",
  "Log4NetLevel": "FATAL",
  "EnvironmentName": "Production"
}
WORKING!!!
.\www.exe urls=https://localhost:44589 --environment Development --configuraton Release
as does
dotnet www.dll --urls=https://localhost:44589/  --configuration Release --environment Development
πŸ™‚
j
OOO will check out and report back!!
m
this was the eureka moment...
Copy code
Buried in the documentation under Environment variable configuration provider is the following extract:

The default configuration loads environment variables and command-line arguments prefixed with DOTNET_. The DOTNET_ prefix is used by .NET for host and app configuration, but not for user configuration.

So if you use the command line parameter --environment Development that should get transformed into DOTNET_ENVIRONMENT=Development. This was tested as working with a .NET 5.0 worker service.
Ps... your test above that was running forever (not reliant on appsettings.{env}.config) might have been accessible on
localhost:5000
as that's the default kestrel port.
s
I came here to say this!
It's not necessarily hanging, it's just "running" but you will not get any output in the console.
m
though I get output in the console.. when running
dotnet www.dll --urls=https://localhost:44589/  --configuration Release --environment Development
???
s
I cam here to say that too! πŸ˜›
but I'm not sure there's console output still, once you build in Release mode it gets very quiet. Ah I see you get output.. well, that seems a bit of a kludge to use Release and Development together πŸ˜…
j
Thanks everyone - at work right now but will look into this tonight!
s
So:
dotnet www.dll
will automatically run
http://localhost:5000
and you can change the port with
dotnet run www.dll  --urls "http://*:5001"
for port
5001
etc. πŸ™‚
m
hmm.. not getting ya.. why would
dotnet www.dll
give no output.. but
dotnet www.dll --urls=https://localhost:44589/  --configuration Release --environment Development
immediately give https://cdn.discordapp.com/attachments/1158658538600673311/1158694503415296000/image.png?ex=651d2dd9&is=651bdc59&hm=bd9a05613e73713635f7415eb505c0b7584525d6728a9d0689d9b6bc1dd25ac5&
s
Becsause you added
--environment Development
m
I guess for me it's because it's erroring as port 5000 taken.
ah assumed apsettings.config had console logging?
not just appsettings.devleopment πŸ™‚
s
dotnet www.dll
will suppress any and all output, then you need to dive into log files.
appsettings.development.config
should not apply when you build as
Release
unless you add, as you did
--environment Development
m
because behind the scenes release sets environment as production?
app.config bundled in the dll/exe?
s
I think it's
appconfig.production.config
yeah, but I am not entirely sure about that one what the default is!
m
so dotnet www.dll also relies on how you published..
dotnet publish --no-build --no-restore -c Debug /p:EnvironmentName=Development -o ..\..\publish
and we'd have a different story..
all good to know for testing.. and especially a loadbalanced set up locally.. could publish to backoffice, sub1, sub2 folders with the correct environments.. and run all via this as separate instances...
s
Yep (careful with
--no-build --no-restore
as well, it has bitten me before, publishing on local machine and forgetting to do
dotnet build
first).
m
yeah me too.. just lifted it from the ci/di script...
s
I'm afraid we're confusing @jacksorjacksor (Richard Jackson) here though! I think the simple answer to his question is: -
dotnet www.dll
(in the directory where you published the release) - Go to http://localhost:5000 Note: you will probably get the Umbraco installer starting because the database does not get published.
m
and in chrome enjoy the I think http should be https schenanigans..
or can we also default to https://localhost:5001?
wouldn't you always get the installer.. as the connection string to sqllite is in the appsettings.development.json from the default install? so not really to do with db published or not?
s
Depends, not if you have automatic installs enabled πŸ˜‰
s
It depends, appSettings.Development don't apply unless you set the environment to be development. So just
dotnet publish
will use the appsettings.json which doesn't auto-install.
j
@Sebastiaan off-topic from OP but when you run
dotnet publish
does that use appsettings.json AND appsettings.Production.json?
s
I couldn't remember for sure, but yes indeed it does! I did: -
dotnet publish -c Release -o .\publish
(-o is to set the output directory) -
dotnet www.dll
This actually gave me output as it was doing an automatic install, since I copied
appsettings.Development.json
to
appsettings.Production.json
I made 1 crucial change in
appsettings.Production.json
though and that is
Data Source=|DataDirectory|/Umbraco.sqlite.db
to
Data Source=|DataDirectory|/Umbraco.sqlite222.db
Then checked
~\publish\umbraco\Data
and found a
Umbraco.sqlite222.db
there. To note: dotnet starts to look at
appsettings.Production.json
first, if anything is undefined there, but defined in
appsetting.json
then it will pick up from
appsetting.json
, I believe environment variables take even more precedence than
appsettings.Production.json
but I'm not quite sure. You could check with Diplo God Mode (https://marketplace.umbraco.com/package/diplo.godmode) using "View diagnostics and configuration settings about your Umbraco site and hosting environment" where exactly variables came from.
I find this magical by the way, how am I supposed to know it uses
appsettings.Production.json
? I'd kinda expect
appsettings.Release.json
🀷
r
The environment selection is a runtime thing unlike config transforms in dotnet framework which was at build time. The
DOTNET_ENVIRONMENT
or
ASPNETCORE_ENVIRONMENT
environment variable defines which environment you are running, if not defined it defaults to
Production
. ASP.NET Core is by default loading
appsettings.json
then
appsettings.{environment}.json
if it exists, and then environment variable see https://learn.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-7.0 and https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-7.0
m
Don't forget
user secrets
too if defined and --environment Development πŸ™‚ that link has https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-7.0#default-application-configuration-sources for priority πŸ™‚
Wasn't that a fundamental change with dotnet over framework.. https://learn.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-7.0 and we get isDevelopment, isStaging, isProduction methods.. but no isDebug/isRelease?? I do remember getting caught in framework with release transforms occuring as well as a named production environment transform... I wonder if it's the same in netcore? can you add appsettings.release.json and a appsettings.production.json and both apply when -c release /p:enviromentname = production?? πŸ€”
r
There’s no transforms on build anymore. It also always felt like a hack if you had multiple environments because you had to add different build configurations for each environment and had to do multiple builds to apply the configuration unless you built/had a custom release flow that applied the transforms but used the same build. Now you just set the
DOTNET_ENVIRONMENT
environment variable to whatever you want and load the configuration based on that variable. Also the fact that you can easily override/add where configuration is loaded from makes it so more powerful.
m
yep for sure.. I was talking about old framework transforms and the replacement for netcore had this shift to development/staging/production as completely separate to release/debug.. hence why appsettings.release.config isn't to be expected.. (but also musing incase they kept the duality/overlap from framework)
(as you might have common settings dictated by release configuration.. in addition to multiple environment settings all deployed in release mode)
thinking like loadbalanced, publisher, subscriber1, subscriver2 etc.. all use the same db.. but have differenent serverroles..
all would be release so could have one setting for DB.. in a release.json..
but don't think it works like that.. and you'd have to define the common db in all the env.jsons.
r
I’d still use the same build for that, but either use environment variables to override the settings for each instance, or maybe even load another configuration file based on another environment variable if I want to keep the configuration in source control
m
but either use environment variables to override the settings for each instance
but then that's not really DRY..
that's what we do now.. same build and each env.json has the exact same db configstring set.