I have a .NET Core 2.0 application which I want to run on a Linux server.
Everything is set up correctly and if I run dotnet MyApplication.dll manually then the application starts and going to the url in the browser works fine.
I want to automatically start the application with supervisor as I have seen others do online.
Supervisor is installed and configured to run my application however the .NET app cannot start and I can see the errors in the supervisor error log.
System.ArgumentNullException: Value cannot be null.
Parameter name: path1
at System.IO.Path.Combine(String path1, String path2)
at Microsoft.DotNet.Configurer.CliFallbackFolderPathCalculator.get_DotnetUserProfileFolderPath()
at Microsoft.DotNet.Configurer.FirstTimeUseNoticeSentinel..ctor(CliFallbackFolderPathCalculator cliFallbackFolderPathCalculator)
at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, ITelemetry telemetryClient)
at Microsoft.DotNet.Cli.Program.Main(String[] args)
supervisor configuration as follows:
[program:myapplication]
command=/usr/bin/dotnet /var/www/myapplication.mydomain/MyApplication.dll
directory=/var/www/myapplication.mydomain
autostart=true
autorestart=true
stderr_logfile=/var/log/websites/myapplication.mydomain.err.log
stdout_logfile=/var/log/websites/myapplication.mydomain.out.log
environment=ASPNETCORE_ENVIRONMENT=Production
user=myuser
stopsignal=INT
dotnet --info as follows:
.NET Command Line Tools (2.0.0)
Product Information:
Version: 2.0.0
Commit SHA-1 hash: cdcd1928c9
Runtime Environment:
OS Name: ubuntu
OS Version: 16.04
OS Platform: Linux
RID: ubuntu.16.04-x64
Base Path: /usr/share/dotnet/sdk/2.0.0/
Microsoft .NET Core Shared Framework Host
Version : 2.0.0
Build : e8b8861ac7faf042c87a5c2f9f2d04c98b69f28d
Application is a .NET Core 2.0 / .NET Standard 2.0 application.
I have seen this method in a few blog posts online so it must have worked at some point.
Would love to get this working!
Also posted issue on Stackoverflow here
NuGet requires you to have HOME set when running on a Unix box. I would imagine that you don't on the machine where you are running right now.
@livarcocc
Is this a fairly recent requirement?
And how exactly do I go about doing this? I'm new to setting up a Linux environment. Thanks!
No, this has been true for as long as I can remember actually.
HOME is a special environment variable in Linux, meaning that it controls many different things.
Strictly speaking, you just need to run set HOME=
cc @emgarten here, so that he is aware this is coming up again.
So I ran echo $HOME and I do have a $HOME variable which is set to /home/myuser. I guess this is just the logged in user's home directory since if I log in as root the $HOME variable is set to /root
Is this the variable you are referring to?
Hum, I wonder if that variable remains set when running under supervisor.
This is our code:
string profileDir = Environment.GetEnvironmentVariable(
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "USERPROFILE" : "HOME");
return Path.Combine(profileDir, ".dotnet");
Do you do any extra configuration in the Main method on startup?
Mine looks like this
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseUrls("http://localhost:5001")
.Build();
}
I have seen an number of walkthroughs and cannot see how my setup is different as to why it's not working.
e.g.
https://www.hanselman.com/blog/PublishingAnASPNETCoreWebsiteToACheapLinuxVMHost.aspx
http://coderscoffeehouse.com/tech/2016/08/19/real-world-aspnetcore-linux-example.html
I've also tried NOT using supervisor but using a native Linux service and still couldn't get the application to start. At least supervisor gives better logging to try to help understand the problem though.
Desperate to get this to work now
Sorry, the snippet that I shared above was the for the code that is failing. To show the Path.Combine we are trying to do. We are just resolving the HOME environment variable and combining with .dotnet.
I don't know how supervisor works, sorry about that. What are the inputs to it? A script file? A set of commands? I suspect that the problem you are running into is that supervisor runs under a different account than yours and in that context, HOME is not set. I would update your supervisor "script" to call set HOME=
I tried setting HOME to /home/myuser manually in the supervisor config but still no luck.
So forgetting supervisor, I just disabled it and had another go with creating a 'native' service that can be started with systemctl
There is a Microsoft post about this here
https://docs.microsoft.com/en-us/aspnet/core/publishing/apache-proxy
Using identical configuration to the post, my application is still not able to be started.
Would like to add...
I am building the application on macOS Sierra 10.12.6 with dotnet publish, then using ftp to transfer the contents of the /bin/Debug/netcoreapp2.0/publish to my Linux server. I don't think this is relevant though since the default build can run on any platform, and also like I mentioned before, if I manually run dotnet MyApplication.dll it works
On the NuGet side the NRE was improved with a helpful error message when HOME isn't set: https://github.com/NuGet/Home/issues/4671
Based on the stack trace above it looks like the CLI may need to do the same.
Note that env var names are case-sensitive on Linux.
If this is a case of env variables not being set, I am not sure as to _why_. Like I said initially, if I manually run dotnet MyApplication.dll it runs fine. It's only when using a service file or supervisor to run it that the error occurs. I even tried setting environment=ASPNETCORE_ENVIRONMENT=Production,HOME=/var/www in the supervisor configuration and still no luck
Ok, I think I figured out what is going on.
@emgarten you are absolutely right. I realized that this was not a NuGet issue but did not comment back here. Sorry about that.
@mbrookson The problem that you are running into is because your supervisor file is invoking dotnet with this as its argument: /var/www/myapplication.mydomain/MyApplication.dll. However, on your supervisor machine, this file does not exist, as such, the host (dotnet), instead of simply executing your application, in which case no HOME is required, thinks that you are trying to run an SDK command and goes into the SDK code path.
I would recommend double checking the location of your assemblies in the supervisor machine and the path you are passing in your script.
So the files are all on the same 'machine'.
I am using Apache to run the website so the contents of my dotnet publish folder is in /var/www/myapplication.mydomain
The supervisor configuration is on the same machine in /etc/supervisor/conf.d/myapplication.mydomain.conf
Supervisor also has stderr_logfile=/var/log/websites/myapplication.mydomain.err.log set which does write to the log file successfully so that path does work
Since the paths I use are all relative to the machine root I would have thought this would work?
Like I said, I haven't used supervisor.
If you want to do a quick test, just change the dotnet command to a ls command and see if it finds anything at the path that you are expecting the supervisor to find the dll.
Good idea. Just tried that and ls /var/www/myapplication.mydomain does definitely list all the expected files including the MyApplication.dll that I'm trying to run.
If you are setting the directory to
directory=/var/www/myapplication.mydomain have you tried setting the command to command=/usr/bin/dotnet MyApplication.dll since in theory the working directory is already the application directory?
You my friend are a genius! It works!
Thanks very much @livarcocc
@mbrookson you are welcome. Glad we could sort it out.
Most helpful comment
If you are setting the directory to
directory=/var/www/myapplication.mydomainhave you tried setting the command tocommand=/usr/bin/dotnet MyApplication.dllsince in theory the working directory is already the application directory?