2x1=10

because numbers are people, too
Persönliches
Fotografie
Programmierung
    • Fun with ASP.NET 5 beta7: Bliss, Build errors, Dockerfiles and Reverse Proxies

      I was nev­er a ASP.NET devel­op­er, but since self-host­ing on Lin­ux only meant trou­ble, I gave ASP.NET vNext a try. At first, the whole DNX and .NET Core thing hit me like a ham­mer. A big one. Wield­ing a jack­ham­mer. After work­ing with it for a cou­ple of days now though, I’m actu­al­ly more than excit­ed — it’s almost heresy. With all the log­ging, con­fig­u­ra­tion ser­vices (Microsoft.Framework.Configuration!), devel­op­er secrets, host-inte­grat­ed depen­den­cy injec­tion includ­ed by design — not to for­get the Lin­ux sup­port — there’s absolute­ly no way I’ll ever go back to .NET once DNX is sta­ble.

      That said, here are some things I stum­bled over:

      • If you just installed Visu­al Stu­dio 2015 Com­mu­ni­ty and ASP.NET is still beta, make sure to install the newest beta inte­gra­tion. Last time I checked I was two ver­sions behind and things change rapid­ly at the moment.
      • When div­ing into this DNX (“Class Library (Pack­age)”, “Con­sole Appli­ca­tion (Pack­age)”, ASP.NET 5 web project) thing, if you don’t explic­it­ly need .NET Core sup­port, kick the dnxcore50 frame­work out of the projects.json. That reduces pain time to a min­i­mum, when oth­er­wise you’d be search­ing for the cause of one gazil­lion build errors that should not be there.
      • When using the offi­cial (and sweet) microsoft/aspnet Dockerfile, know that the exam­ples are tai­lored for sin­gle-project solu­tions. 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 like­ly some­thing 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 mid­dle­ware for MVC 6 to sup­port X-Forwarded-Proto and the offi­cial RFC 7239 Forwarded head­ers, more below.

      First of all, I had my devel­op­ment site run­ning local­ly in Visu­al Stu­dio, avail­able to the sub­net through a local nginx reverse proxy which I would use to dis­patch to any of my devel­op­ment web­sites. In this case, the .../aspnet route would point to my self-host­ed appli­ca­tion. That nginx, in turn, was behind anoth­er nginx, lis­ten­ing to the https://myhost/testing route on the actu­al web­serv­er. Sad­ly, this base path of /testing/aspnet was total­ly trip­ping up ASP.NET which assumed a base path of /, also the pro­to­col was not rec­og­nized. So I added this con­fig­u­ra­tion 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 imple­ment­ed the fol­low­ing in C#:

      public static void UseReverseProxyProtocolRecognition(
                                     [NotNull] this IApplicationBuilder app)
      {
          app.Use(next => context =>
          {
              var request = context.Request;
              var headers = request.Headers;
      
              if (!string.IsNullOrWhiteSpace(headers["X-Base-Path"]))
              {
                  request.PathBase = headers["X-Base-Path"];
              }
      
              if (string.Equals(context.Request.Headers["X-Forwarded-Proto"], 
                                Uri.UriSchemeHttps, 
                                StringComparison.OrdinalIgnoreCase))
              {
                  request.Scheme = Uri.UriSchemeHttps;
              }
              else if (!string.IsNullOrWhiteSpace(headers["Forwarded"]))
              {
                  // http://tools.ietf.org/html/rfc7239
                  var match = Regex.Match(headers["Forwarded"], 
                                          @"proto=(?<proto>https?)");
                  if (match.Success)
                  {
                      request.Scheme = match.Groups["proto"].Value;
                  }
              }
              return next(context);
          });
      }
      

      which allowed me to sim­ply do:

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

      As for the Dockerfile, since I was using mul­ti­ple projects in one solu­tion, I had to cheat a lit­tle. This file works by copy­ing the project files into the image, then run­ning dnu restore indi­vid­u­al­ly for each DNX project, then adding the whole sources. This — when putting the least mod­i­fied project first — allows for caching as much as pos­si­ble when rebuild­ing the image, while still allow­ing for cross-project depen­den­cies. Also note the use of MONO_THREADS_PER_CPU which real­ly is a life-saver here.

      FROM microsoft/aspnet
      
      ENV MONO_THREADS_PER_CPU 2000
      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 Dock­er for Win­dows toolk­it which amaz­ing­ly sucks less than it did some months ago.
      Also have fun and cof­fee. You know I do.

      September 8th, 2015 GMT +2 von
      Markus
      2015-09-8T19:59:20+02:00 2015-09-8T19:59:20+02:00 · 0 Kommentare
      Windows Linux docker .NET vNext nginx
      .NET ASP.NET DNX

      Hinterlasse einen Kommentar

      Hier klicken, um das Antworten abzubrechen.

    1. “Compiler crashed with code 1” on Mono">« newer
    2. 1
    3. …
    4. 7
    5. 8
    6. “Compiler crashed with code 1” on Mono" rel="prev prefetch">9
    7. 10
    8. 11
    9. 12
    10. 13
    11. …
    12. 43
    13. older »
    • Kategorien

      • .NET
        • ASP.NET
        • Core
        • DNX
      • Allgemein
      • Android
      • Data Science
      • Embedded
      • FPGA
      • Humor
      • Image Processing
      • Kalman Filter
      • Machine Learning
        • Caffe
        • Hidden Markov Models
        • ML Summarized
        • Neural Networks
        • TensorFlow
      • Mapping
      • MATLAB
      • Robotik
      • Rust
      • Signal Processing
      • Tutorial
      • Version Control
    • Neueste Beiträge

      • Summarized: The E-Dimension — Why Machine Learning Doesn’t Work Well for Some Problems?
      • Use your conda environment in Jupyter Notebooks
      • Building OpenCV for Anaconda Python 3
      • Using TensorFlow’s Supervisor with TensorBoard summary groups
      • Getting an image into and out of TensorFlow
    • Kategorien

      .NET Allgemein Android ASP.NET Caffe Core Data Science DNX Embedded FPGA Hidden Markov Models Humor Image Processing Kalman Filter Machine Learning Mapping MATLAB ML Summarized Neural Networks Robotik Rust Signal Processing TensorFlow Tutorial Version Control
    • Tags

      .NET Accelerometer Anaconda Bitmap Bug Canvas CLR docker FPGA FRDM-KL25Z FRDM-KL26Z Freescale git Gyroscope Integration Drift Intent J-Link Linear Programming Linux Magnetometer Matlab Mono Naismith OpenCV Open Intents OpenSDA Optimization Pipistrello Player/Stage PWM Python Sensor Fusion Simulink Spartan 6 svn tensorflow Tilt Compensation TRIAD ubuntu Windows Xilinx Xilinx SDK ZedBoard ZYBO Zynq
    • Letzte Kommetare

      • Lecke Mio bei Frequency-variable PWM generator in Simulink
      • Vaibhav bei Use your conda environment in Jupyter Notebooks
      • newbee bei Frequency-variable PWM generator in Simulink
      • Markus bei Using TensorFlow’s Supervisor with TensorBoard summary groups
      • Toke bei Using TensorFlow’s Supervisor with TensorBoard summary groups
    • Blog durchsuchen

    • September 2015
      M D M D F S S
      « Jul   Dez »
       123456
      78910111213
      14151617181920
      21222324252627
      282930  
    • Self

      • Find me on GitHub
      • Google+
      • Me on Stack­Ex­change
      • Ye olde blog
    • Meta

      • Anmelden
      • Beitrags-Feed (RSS)
      • Kommentare als RSS
      • WordPress.org
    (Generiert in 0,340 Sekunden)

    Zurück nach oben.