I'm new to docker and I'm trying to "dockerise" my .Net Core 3.1 web app and have been having lots of issues. I think I'm close with my current configuration, but I can't resolve the following error
#20 15.48 /bin/sh: 2: /tmp/tmp304aa1375f814c218c0b827fa8987b12.exec.cmd: npm: not found
#20 15.49 /src/AptivDataViz.UI/AptivDataViz.UI.csproj(193,5): error MSB3073: The command "npm install" exited with code 127.
Here's my DockerFile:
# https://medium.com/@oluwabukunmi.aluko/dockerize-asp-net-core-web-app-with-multiple-layers-projects-part1-2256aa1b0511
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE $PORT
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY myapp.UI/*.csproj ./myapp.UI/
COPY myapp.Data/*.csproj ./myapp.Data/
COPY myapp.DTO/*.csproj ./myapp.DTO/
COPY myapp.LiteDB/*.csproj ./myapp.LiteDB/
COPY myapp.Repository/*.csproj ./myapp.Repository/
#RUN echo ''
RUN dotnet restore "myapp.UI/myapp.UI.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "myapp.UI/myapp.UI.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "myapp.UI/myapp.UI.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "myapp.ui.dll"]
I also tried the following config, but got the same result:
FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 8080
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY *.sln .
COPY myapp.UI/*.csproj ./myapp.UI/
#RUN dotnet restore
COPY . .
WORKDIR "/src/myapp.UI"
RUN dotnet build -c Release -o /app/build
FROM build AS publish
RUN dotnet publish -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "myapp.UI.dll"]
csproj:
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
<!--As part of publishing, ensure the JS resources are freshly built in production mode-->
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />
<!--Include the newly-built files in the publish output-->
<ItemGroup>
<DistFiles Include="$(SpaRoot)build\**; $(SpaRoot)build-ssr\**" />
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
<RelativePath>%(DistFiles.Identity)</RelativePath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</ResolvedFileToPublish>
</ItemGroup>
</Target>
npm install
and npm run build
from my Clientapp folder both execute wihtout any errors.
Following a recommendation of this page, I removed the Target
nodes from the csproj and this resulted in a successful docker build, but it didn't run so I'm thinking that was not the right advice
docker-compose
version: '3.5'
services:
aptivpoc:
build:
context: .
dockerfile: Dockerfile
image: myapp:dev
container_name: myapp
restart: unless-stopped
env_file:
- .env
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.IdleTimeout = System.TimeSpan.FromMinutes(30);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
services.AddControllersWithViews();
services.AddHttpContextAccessor();
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "Dashboard API", Description="Tool for testing dashboard API endpoints", Version = "v1" });
});
}
I run the following command from the folder where my sln file is (one level above the project folder where the DockerFile is
docker build -f myapp.UI\Dockerfile --force-rm -t myapp.ui .
I did manage to get a previous app to successfully build into a do
EDIT I am basing my DockerFile off of this: https://docs.docker.com/samples/dotnetcore/ and this: https://softchris.github.io/pages/dotnet-dockerize.html
CodePudding user response:
You need to install node and npm in the SDK image, since they aren't there in the standard image. You can install them by adding a line in the build step of your Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
# Add this line VVVVV
RUN apt-get update && apt-get install -y nodejs npm
WORKDIR /src
CodePudding user response:
I got it working! I took some inspiration from this post that suggested removing the entire Target
section from the csproj file, but doing that also failed. Thanks to Obsidian Age's comment, I decided to try removing the npm commands from csproj. I just removed the following two elements from the csproj
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />
Prior to that, I also whittled my DockerFile down to the following:
FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 8080
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY *.sln .
COPY myapp.UI/*.csproj ./myapp.UI/
#RUN dotnet restore
COPY . .
WORKDIR "/src/myapp.UI"
RUN dotnet build -c Release -o /app/build
FROM build AS publish
RUN dotnet publish -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "myapp.UI.dll"]
docker build -f myapp.UI\Dockerfile --force-rm -t myapp.ui .
docker run -d -p 8080:80 --name containername myapp.ui
et voila! Site is running from Docker!
It's worth noting that I did not add those two elements to the csproj. I started the project in Visual Studio Enterprise 2019 using a React .Net Core 3.1 template and the csproj file was created that way. I'll have to see how publishing directly to Azure App Service (just for UAT) works (or fails!) now.