かみのメモ

コンピュータビジョン・プログラムな話題中心の勉強メモ(記事一覧は https://kamino.hatenablog.com/archive へ)

ASP.NET Core + AngularのDocker化でつまずいた話

タイトル通り、ASP.NET Core + AngularなアプリのDockerコンテナを作ろうとしたときにエラーが出たのでメモ。

自分の環境

  • macOS High Sierra 10.13.3
  • .NET Command Line Tools (2.1.101)
  • Docker Community Edition 17.12.0-ce-mac55 (23011)

プロジェクトの作成

.NET Coreに用意されているテンプレートプロジェクトを作成する。

$ mkdir asp_ng_test
$ cd asp_ng_test
$ dotnet new angular

とりあえずローカルで動くことを確認してみる。

$ npm install
$ dotnet run

すると次のようなメッセージが出るのでブラウザから確認してみる。

Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

f:id:kamino-dev:20180404213707p:plain

うん。動いてる。

Dockerfileの準備

次にDockerfileを用意する。 公式のDockerHubの解説に従って、asp_ng_testディレクトリ内にDockerfile.dockerignoreを作成する。

テンプレートプロジェクトではビルドされるASPアプリのファイル名がasp_ng_test.dllなので、ENTRYPOINTの行を編集しておく。

https://hub.docker.com/r/microsoft/aspnetcore-build/

  • Dockerfile
# Sample contents of Dockerfile
# Stage 1
FROM microsoft/aspnetcore-build AS builder
WORKDIR /source

# caches restore result by copying csproj file separately
COPY *.csproj .
RUN dotnet restore

# copies the rest of your code
COPY . .
RUN dotnet publish --output /app/ --configuration Release

# Stage 2
FROM microsoft/aspnetcore
WORKDIR /app
COPY --from=builder /app .
ENTRYPOINT ["dotnet", "asp_ng_test.dll"]
  • .dockerignore
# sample contents of .dockerignore file
bin/
obj/
node_modules/

コンテナをビルド

いつも通りに。

$ docker build -t asp_ng_test:latest .

起動!

いつも通りに。

$ docker run --rm -it -p 8080:80 asp_ng_test:latest

ちゃんと起動してるっぽいメッセージが出るので、ブラウザで確認してみる。

Now listening on: http://[::]:80
Application started. Press Ctrl+C to shut down.

f:id:kamino-dev:20180404222352p:plain

あれ…? こけた。

エラーメッセージを確認

[1] Ensure that Node.js is installed and can be found in one of the PATH directories.
    Current PATH enviroment variable is: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    Make sure the Node executable is in one of those directories, or update your PATH.

[2] See the InnerException for further details of the cause. ---> System.ComponentModel.Win32Exception: No such file or directory

~~~~

どうやらmicrosoft/aspnetcoreのイメージにAngularのためのNode.jsが入っていないのが原因っぽい。

Dockerfileを編集

RUNコマンドでNode.jsをインストールするように指示する。 バージョンの指定とかはとりあえず無視する。

ここでもう一箇所つまずいたのが、aptで入るNode.jsは実行ファイル名がnodejsになるらしいという点。 ASPプロジェクトではnodeで呼び出されるようなので、ln -sシンボリックリンクを作成しておく。

# Sample contents of Dockerfile
# Stage 1
FROM microsoft/aspnetcore-build AS builder
WORKDIR /source

# caches restore result by copying csproj file separately
COPY *.csproj .
RUN dotnet restore

# copies the rest of your code
COPY . .
RUN dotnet publish --output /app/ --configuration Release

# Stage 2
FROM microsoft/aspnetcore
WORKDIR /app
COPY --from=builder /app .
RUN apt-get update \
    && apt-get install -y nodejs \
    && ln -s /usr/bin/nodejs /usr/bin/node
ENTRYPOINT ["dotnet", "asp_ng_test.dll"]

リトライ

もう一度ビルド&起動してみる。

$ docker build -t asp_ng_test:latest .
$ docker run --rm -it -p 8080:80 asp_ng_test:latest

f:id:kamino-dev:20180404224006p:plain

動いた! おしまい!