## Schlüsselwortarchiv

Du betrachtest das Archiv des Tags vNext.

• ## Fun with ASP.NET 5 beta7: Bliss, Build errors, Dockerfiles and Reverse Proxies

I was never a ASP.NET developer, but since self-hosting on Linux only meant trouble, I gave ASP.NET vNext a try. At first, the whole DNX and .NET Core thing hit me like a hammer. A big one. Wielding a jackhammer. After working with it for a couple of days now though, I’m actually more than excited – it’s almost heresy. With all the logging, configuration services (Microsoft.Framework.Configuration!), developer secrets, host-integrated dependency injection included by design – not to forget the Linux support – there’s absolutely no way I’ll ever go back to .NET once DNX is stable.

That said, here are some things I stumbled over:

• If you just installed Visual Studio 2015 Community and ASP.NET is still beta, make sure to install the newest beta integration. Last time I checked I was two versions behind and things change rapidly at the moment.
• When diving into this DNX (“Class Library (Package)”, “Console Application (Package)”, ASP.NET 5 web project) thing, if you don’t explicitly need .NET Core support, kick the dnxcore50 framework out of the projects.json. That reduces pain time to a minimum, when otherwise you’d be searching for the cause of one gazillion build errors that should not be there.
• When using the official (and sweet) microsoft/aspnet Dockerfile, know that the examples are tailored for single-project solutions. Below is how I did it in the end.
• At least as per beta 7, the dnu restore in the docker build process takes ages. This has likely something to do with mono and – as per this bug report – there’s a quick fix for it: Add ENV MONO_THREADS_PER_CPU 2000 to your Dockerfile and see the world with new eyes.
• I also had to write a middleware for MVC 6 to support X-Forwarded-Proto and the official RFC 7239 Forwarded headers, more below.

First of all, I had my development site running locally in Visual Studio, available to the subnet through a local nginx reverse proxy which I would use to dispatch to any of my development websites. In this case, the .../aspnet route would point to my self-hosted application. That nginx, in turn, was behind another nginx, listening to the https://myhost/testing route on the actual webserver. Sadly, this base path of /testing/aspnet was totally tripping up ASP.NET which assumed a base path of /, also the protocol was not recognized. So I added this configuration to my local nginx:

upstream local_aspnet {
server localhost:9000;
}

server {
listen       80;
server_name  myhost localhost;

location /aspnet {
rewrite /testing/aspnet(.*) $1 break; # Handled within ASP.NET proxy_set_header X-Base-Path /testing/aspnet; proxy_set_header X-Real-IP$remote_addr;
proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto "https"; proxy_pass http://local_aspnet/; proxy_redirect off; proxy_set_header HOST$host;
proxy_buffering off;
break;
}
}


And implemented the following in C#:

public static void UseReverseProxyProtocolRecognition(
[NotNull] this IApplicationBuilder app)
{
app.Use(next => context =>
{
var request = context.Request;

{
}

Uri.UriSchemeHttps,
StringComparison.OrdinalIgnoreCase))
{
request.Scheme = Uri.UriSchemeHttps;
}
{
// http://tools.ietf.org/html/rfc7239
@"proto=(?<proto>https?)");
if (match.Success)
{
request.Scheme = match.Groups["proto"].Value;
}
}
return next(context);
});
}


which allowed me to simply do:

public void Configure(IApplicationBuilder app, IApplicationEnvironment env,
ILoggerFactory loggerfactory)
{
// ...
app.UseReverseProxyProtocolRecognition();
// ...
}


As for the Dockerfile, since I was using multiple projects in one solution, I had to cheat a little. This file works by copying the project files into the image, then running dnu restore individually for each DNX project, then adding the whole sources. This – when putting the least modified project first – allows for caching as much as possible when rebuilding the image, while still allowing for cross-project dependencies. Also note the use of MONO_THREADS_PER_CPU which really is a life-saver here.

FROM microsoft/aspnet

ENV STARTUP_PROJECT src/Startup.Project

COPY NuGet.Config /app/
COPY global.json /app/

COPY src/Startup.Project/project.json /app/src/Startup.Project/
COPY src/Second.Project/project.json  /app/src/Second.Project.Models/
COPY src/Third.Project/project.json   /app/src/Third.Project/

WORKDIR /app/src/Startup.Project
RUN ["dnu", "restore"]

WORKDIR /app/src/Second.Project
RUN ["dnu", "restore"]

WORKDIR app/src/Third.Project
RUN ["dnu", "restore"]

COPY . /app
WORKDIR /app/\$STARTUP_PROJECT

EXPOSE 5004
ENTRYPOINT ["dnx", "kestrel"]


If you’re at it, check out the Docker for Windows toolkit which amazingly sucks less than it did some months ago.
Also have fun and coffee. You know I do.