如何在 Linux Docker 容器中运行 VS2017 Angular 项目? [英] How can I run a VS2017 Angular project in a Linux Docker container?

查看:34
本文介绍了如何在 Linux Docker 容器中运行 VS2017 Angular 项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:关于这个主题已经有几个问题,我在下面参考.虽然这个问题在这个意义上是重复的,但我试图遵循其他问题中的建议但没有成功.有时这是因为现在的答案是指相关软件包的过时版本,有时是因为不清楚如何实施更改.

这个问题是我试图记录一个最小的(非)工作示例,以及如何重现问题的完整说明.希望我能用同样清晰的说明更新它,说明如何修复它.

<小时>

我有以下环境:

  • Windows 10(企业版,1709)
  • VS2017 (15.8.4)
  • 节点 (11.5)
  • Angular CLI (7.1.4)
  • Docker 桌面(社区,2.0.0.2)

以下是我创建 Angular SPA 项目所遵循的确切步骤:

<块引用>

为项目创建目录

md MyAngularWebsitecd MyAngular网站

<块引用>

使用 dotnet CLI(使用 Angular 模板)创建项目

dotnet new angular

如果我在 VS 中打开这个解决方案,我会看到我希望看到的所有文件:

...如果我运行它(在 IIS Express 中)它会按预期工作:

到目前为止,一切都很好.

<块引用>

添加 Docker 支持

[注意:虽然我通过 .NET CLI 创建了项目,但也可以使用 Visual Studio UI 创建项目.执行此操作时,新项目对话框中有一个添加 Docker 支持"复选框.但是,该复选框对于 Angular 项目是禁用的.大概这是因为它不起作用.但是,我们可以使用以下方法完成一半.]

我右键单击网站项目 (MyAngularWebsite),然后从弹出菜单中选择添加 Docker 支持".

Visual Studio 询问 Docker 映像将使用的操作系统类型 - 我选择了 Linux:

这似乎做了两件事:

  1. 将名为 Dockerfile 的文件添加到项目中.
  2. 将名为Docker"的新配置文件添加到 PropertieslaunchSettings.json

这是Dockerfile的内容:

FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base工作目录/应用程序暴露 14242暴露 44321从 microsoft/dotnet:2.2-sdk AS 构建工作目录/src复制 ["MyAngularWebsite.csproj", ""]运行 dotnet 恢复/MyAngularWebsite.csproj"复制 ..工作目录/src/"运行 dotnet 构建MyAngularWebsite.csproj" -c Release -o/app从构建 AS 发布运行 dotnet 发布MyAngularWebsite.csproj" -c Release -o/appFROM base AS final工作目录/应用程序复制 --from=publish/app .入口点 ["dotnet", "MyAngularWebsite.dll"]

现在,如果我使用新的Docker"启动配置文件启动项目,在下载和构建所有必需的部分时会暂停很长时间,然后创建一个 docker 容器,并启动一个浏览器窗口,指向 <代码>https://localhost:44321/.

此时我们看到一个错误,提示Failed to start 'npm':

已阅读很多其他 关于此的问题,我认为问题只是基本图像(在这种情况下Dockerfile 顶部指定的 >microsoft/dotnet:2.2-aspnetcore-runtime 不包括 Node.

Node 是必需的,以便可以构建 Angular 应用程序,因为 ng build 是用来构建它的 - 并且依赖于 Node.(虽然我的本地机器上有 Node,但它不在构建应用程序的 Docker 镜像上).

因此,建议的方法是通过修改 Dockerfile 将 Node 添加到 Docker 镜像.

<块引用>

将节点添加到 Docker 镜像

正如上面提到的问题所建议的,我修改了 Dockerfile 以包含以下内容:

RUN apt-get update &&apt-get install -y wget &&apt-get install -y gnupg2 &&wget -qO- https://deb.nodesource.com/setup_6.x |bash - &&apt-get install -y build-essential nodejs

这意味着我的完整 Dockerfile 现在看起来像这样:

FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base运行 apt-get 更新 &&apt-get install -y wget &&apt-get install -y gnupg2 &&wget -qO- https://deb.nodesource.com/setup_6.x |bash - &&apt-get install -y build-essential nodejs工作目录/应用程序暴露 14242暴露 44321从 microsoft/dotnet:2.2-sdk AS 构建工作目录/src复制 ["MyAngularWebsite.csproj", ""]运行 dotnet 恢复/MyAngularWebsite.csproj"复制 ..工作目录/src/"运行 dotnet 构建MyAngularWebsite.csproj" -c Release -o/app从构建 AS 发布运行 dotnet 发布MyAngularWebsite.csproj" -c Release -o/appFROM base AS final工作目录/应用程序复制 --from=publish/app .入口点 ["dotnet", "MyAngularWebsite.dll"]

...而且... 结果完全一样.

<块引用>

为什么没有安装 NPM?

根据@DannyB 的评论,我尝试 bash-ing 进入 Docker 容器以直接运行 npm:

docker exec -it mycontainer_id/bin/bash

...当我尝试执行 npm 时,我收到一条错误消息,提示npm:未找到命令".所以,我想这就是它仍然无法正常工作的原因.

然后我尝试直接在 bash shell 中依次执行我添加到 Dockerfile 的每个命令.当我到达线路时:

wget -qO- https://deb.nodesource.com/setup_6.x

...它在不产生任何输出的情况下执行,但我意识到这是因为 -q 标志意味着安静模式",所以我在没有 q 的情况下再次执行它.这一次,我遇到了错误:

错误:deb.nodesource.com"的证书不受信任.错误:'deb.nodesource.com' 的证书没有已知的颁发者.

深入挖掘,结果发现即使我只是这样做,我也会遇到与证书相关的错误:

curl https://www.google.com

这会导致错误提示SSL 证书问题:证书链中的自签名证书".

所以,我的容器似乎存在信任问题:-).

<块引用>

为什么我的容器无法建立 HTTPS 连接?

根据 这个问题,似乎是因为我在公司环境中运行,通过防火墙的 SSL 流量被拦截/重新加密,我需要配置我的 Docker 容器以信任相应的证书.

假设这是正确的,希望我能够解决信任问题,然后安装 NPM,希望解决最初的问题.

我认为这个问题现在已经离题了,不过如果我能取得进一步的进展,我会继续更新它.

解决方案

我的工作 DockerFile 在 apt-gets 之后有一个 npm 安装.

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base工作目录/应用程序曝光 80第 443 章从 mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build运行 apt-get update -yq &&apt-get upgrade -yq &&apt-get install -yq curl git nano运行 curl -sL https://deb.nodesource.com/setup_8.x |bash - &&apt-get install -yq nodejs build-essential运行 npm install -g npm运行 npm install -g @angular/cli工作目录/src/PAP.UI复制 .PAP.UI.csproj运行 dotnet 还原PAP.UI.csproj"复制 ..运行 dotnet build "PAP.UI.csproj" -c Release -o/app从构建 AS 发布运行 dotnet 发布PAP.UI.csproj" -c 发布 -o/appFROM base AS final工作目录/应用程序复制 --from=publish/app .入口点 ["dotnet", "PAP.UI.dll"]

NOTE: there are several questions about this topic already, which I reference below. While this question is in that sense a duplicate, I have tried to follow the advice in those other questions without success. Sometimes that's because the answer now refers to an out-of-date version of the relevant packages, and sometimes because it's not clear exactly how to implement the changes.

This question is my attempt to document a minimal, (non-)working example, with full instructions of how to reproduce the issue. Hopefully I can update it with similarly clear instructions on how to fix it.


I have the following environment:

  • Windows 10 (enterprise, 1709)
  • VS2017 (15.8.4)
  • Node (11.5)
  • Angular CLI (7.1.4)
  • Docker Desktop (community, 2.0.0.2)

Here are the exact steps I followed to create an Angular SPA project:

Create a directory for the project

md MyAngularWebsite
cd MyAngularWebsite

Create the project using the dotnet CLI (using the Angular template)

dotnet new angular

If I open this solution in VS, I see all the files I'd expect to see:

...and if I run it (in IIS Express) it works as expected:

So far, so good.

Add Docker support

[Note: although I created the project via the .NET CLI, it's also possible to create projects using the Visual Studio UI. When doing this, there's an "Add Docker Support" checkbox in the new-project dialog. However, that checkbox is disabled for Angular projects. Presumably this is because it doesn't work. We can however get halfway there using the following method.]

I right-clicked on the website project (MyAngularWebsite), and chose "Add Docker Support" from the pop-up menu.

Visual Studio asks for the type of Operating System that the Docker image will use - I chose Linux:

This seems to do two things:

  1. Adds a file named Dockerfile to the project.
  2. Adds a new profile named "Docker" to PropertieslaunchSettings.json

Here's the contents of Dockerfile:

FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 14242
EXPOSE 44321

FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /src
COPY ["MyAngularWebsite.csproj", ""]
RUN dotnet restore "/MyAngularWebsite.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "MyAngularWebsite.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "MyAngularWebsite.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "MyAngularWebsite.dll"]

Now, if I start the project using the new "Docker" launch profile, there's a long pause while it downloads and builds all the required parts, and then a docker container is created, and a browser window is launched pointing to https://localhost:44321/.

It's at this point that we see an error saying Failed to start 'npm':

Having read many other questions about this, I gather that the issue is simply that the base image (in this case microsoft/dotnet:2.2-aspnetcore-runtime as specified at the top of the Dockerfile) does not include Node.

Node is required so that the Angular app can be built, since ng build is what's used to build it - and that relies on Node. (Although I have Node on my local machine, it's not on the Docker image on which the app is being built).

So, the suggested approach is to add Node to the Docker image by modifying the Dockerfile.

Add Node to the Docker image

As suggested in the questions referenced above, I modified the Dockerfile to include the following:

RUN apt-get update && 
    apt-get install -y wget && 
    apt-get install -y gnupg2 && 
    wget -qO- https://deb.nodesource.com/setup_6.x | bash - && 
    apt-get install -y build-essential nodejs

This means that my full Dockerfile now looks like this:

FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base

RUN apt-get update && 
    apt-get install -y wget && 
    apt-get install -y gnupg2 && 
    wget -qO- https://deb.nodesource.com/setup_6.x | bash - && 
    apt-get install -y build-essential nodejs

WORKDIR /app
EXPOSE 14242
EXPOSE 44321

FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /src
COPY ["MyAngularWebsite.csproj", ""]
RUN dotnet restore "/MyAngularWebsite.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "MyAngularWebsite.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "MyAngularWebsite.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "MyAngularWebsite.dll"]

...and... the results are exactly the same.

Why is NPM not installed?

Per @DannyB's comment, I tried bash-ing into the Docker container to run npm directly:

docker exec -it mycontainer_id /bin/bash

...and when I tried to execute npm I got an error saying "npm: command not found". So, I guess that's the reason that it's still not working.

I then tried executing each of the commands I added to the Dockerfile in turn, directly in the bash shell. When I got to the line:

wget -qO- https://deb.nodesource.com/setup_6.x

...it executed without producing any output, but I realised that's because the -q flag means "quiet mode", so I executed it again without the q. This time, I got errors:

ERROR: The certificate of 'deb.nodesource.com' is not trusted.
ERROR: The certificate of 'deb.nodesource.com' hasn't got a known issuer.

Digging deeper, it turns out I get certificate-related errors even if I simply do:

curl https://www.google.com

This results in an error saying "SSL certificate problem: self signed certificate in certificate chain".

So, it seems that my container has trust issues :-).

Why is my container unable to make HTTPS connections?

Per this question, it seems that it's because I'm running in a corporate environment where SSL traffic through the firewall is intercepted/re-encrypted, and that I'll need to configure my Docker container to trust the corresponding certificate.

Assuming that's correct, hopefully I'll be able to fix the trust issues, then install NPM, and hopefully solve the original issue.

I think this question has moved rather off-topic now, though I'll continue to update it if I manage to make further progress.

解决方案

My working DockerFile has an npm install for npm after the apt-gets.

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
RUN apt-get update -yq && apt-get upgrade -yq && apt-get install -yq curl git nano
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - && apt-get install -yq nodejs build-essential
RUN npm install -g npm
RUN npm install -g @angular/cli
WORKDIR /src/PAP.UI
COPY . PAP.UI.csproj
RUN dotnet restore "PAP.UI.csproj"
COPY . .
RUN dotnet build "PAP.UI.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "PAP.UI.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "PAP.UI.dll"]

这篇关于如何在 Linux Docker 容器中运行 VS2017 Angular 项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆