AntonMiles
AntonMiles

Reputation: 185

Starting a barebones MVC C# ASP.NET project in Docker gives "Compilation Error"

To start, if Overflow is not the right Stack site for this, please let me know! Also, if you need to see any other files, please feel free to ask.

I started a sample Visual Studio C#/ASP.NET MVC app to try and put in Docker as a Proof of Concept to see how to configure the two parts to work together. It works locally, but when deployed via Docker it throws an error.

Server Error in '/' Application.
Compilation Error

Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately. 

Compiler Error Message: CS0016: Could not write to output file 'c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\e22c2559\92c7e946\App_Web_index.cshtml.a8d08dba.w8h4d0pg.dll' -- 'The directory name is invalid. '

Source Error:

[No relevant source lines]

My workflow is to publish to the filesystem, then build the docker image via the dockerfile below. I use the option to "precompile" the source (leaving me confused by the error). Below are the files I feel are relevant (comments after hashtags added to this post, not in the actual files).

dockerfile

FROM microsoft/aspnet
COPY ./ /inetpub/wwwroot #this copies from the published folder, which contains 'bin'

web.config

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=301880
  -->
<configuration>
  <system.web>
    <customErrors mode="Off"/>
  </system.web>
  <appSettings>
    <add key="webpages:Version" value="3.0.0.0"/>
    <add key="webpages:Enabled" value="false"/>
    <add key="ClientValidationEnabled" value="true"/>
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.0"/>
    <httpRuntime targetFramework="4.0"/>
  </system.web>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed"/>
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-1.5.2.14234" newVersion="1.5.2.14234"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-5.2.2.0" newVersion="5.2.2.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

I use the following commands to build/run the environment:

docker build -t testapp .
docker run -d --name test -p 20012:20012 testapp

the -p doesn't seem to want to work, I've tried going to that port on the docker's IP and it always gets refused, so I go directly to the docker's IP gotten from an inspect.

Things I've tried to varying levels of failure:

Any help would be appreciated!

Update 1:

After using the answers to solve the issue, it successfully builds and as was my end-goal prints the IP of the server (docker container) to show how the load-balancing/Swarming works. For anybody interested in a pre-built docker image (in a windows container) which prints the IP of the docker image you hit, as a proof of concept for load balancing/Swarming with docker, the image is on hub.docker.com under the image name acmiles/aspnet_printserverip. Feel free to check it out, but it's just a sample project with added logic to print the Docker container's IP on the index page. Below is the final version of my dockerfile used to build the image.

FROM microsoft/aspnet
RUN New-Item c:\testapp -type directory
WORKDIR /testapp
COPY ./outputRelease/ .
RUN Remove-WebSite -Name 'Default Web Site' 
RUN New-Website -Name 'webapp' -Port 80 -PhysicalPath 'c:\testapp' -ApplicationPool '.NET v4.5'

Upvotes: 2

Views: 923

Answers (2)

Davide Icardi
Davide Icardi

Reputation: 12219

Another workaround is to work on a different website. In my docker file I remove the default website and add a new one.

RUN New-Item c:\webapp -type directory
RUN Remove-WebSite -Name 'Default Web Site' 
RUN New-Website -Name 'webapp' -Port 80 -PhysicalPath 'c:\webapp' -ApplicationPool '.NET v4.5'

Upvotes: 1

Jared Holgate
Jared Holgate

Reputation: 116

I had the same issue when trying to get an existing MVC app working in docker. I went all around the houses trying to resolve the issue and have spent many hours on it over the weekend! I tried setting permissions on various temp folders to various accounts and I tried setting the app pool to run with a local profile.

I finally got it to work by adding the app pool account to the local admins group. This isn't a final solution, but it's got it working and pointed me in the right direction for which account I need to assign permissions for.

Here is my Dockerfile;

FROM microsoft/aspnet
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
ARG source
WORKDIR /inetpub/wwwroot
COPY ${source:-obj/Docker/publish} .

RUN Add-LocalGroupMember -Group 'Administrators' -Member 'IIS AppPool\DefaultAppPool'; \
IISRESET; 

Hope it helps.

Thanks

Jared

Upvotes: 3

Related Questions