0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NuxtとASP.NET Coreで開発したアプリケーションをコンテナ化してみた!

Posted at

はじめに

冬休みなので勉強がてらTODOアプリを開発してコンテナ化してみようと思い、苦戦しながらやってみたので備忘録代わりに記事にしてみます。

前提

開発環境は以下の通りです。

  • Nuxt
    • Ubuntu on Windows
    • node: v18.12.1
    • Nuxt: 2.15.8
  • ASP.NET Core
    • Windows 10
    • .NET 5.0

Dockerfileを作成する

Nuxt編

ルートディレクトリ直下に、以下の内容のDockerfileを作成しました。

FROM node:18.12.1-alpine3.16 AS build

WORKDIR /app

WORKDIR /app
COPY . ./
RUN yarn install
RUN yarn build

FROM nginx:stable-alpine as production
COPY --from=build /app/dist/ /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

同じくルート直下に.dockerignoreを作成し、一部ファイルをイメージ作成の対象から除外します。

.dockerignore
node_modules
dist
Dockerfile*

また、package.jsonを以下のように修正しました。

package.json
  "scripts": {
    "dev": "NODE_OPTIONS='--openssl-legacy-provider' nuxt",
    "build": "NODE_OPTIONS='--openssl-legacy-provider' nuxt build",
    "start": "NODE_OPTIONS='--openssl-legacy-provider' nuxt start",

nuxtコマンドの前に、NODE_OPTIONS='--openssl-legacy-provider'を追加しています。
これは、opensslのバージョンの互換性の影響でこのコマンド無しにビルドすると下記のエラーが発生するため、nuxtコマンド実行前に実行するようにしています。

RpcIpcMessagePortClosedError: Cannot send the message - the message port has been closed for the process 9800.

Dockerfileについて説明します。
まずビルドステージのベースイメージにnode:18.12.1-alpine3.16を使用します。
いったんすべてのファイルをapp配下にコピーし、yarn buildを実行してビルドファイルを生成します。
実際にコンテナとして作成されるイメージにはビルドファイルのみを配置したいので、ビルドステージから成果物のみをコピーし(成果物は/app/dist/下に作成されます)、nginxが参照するフォルダ配下(/usr/share/nginx/html)に配置します。
80番ポートを開放し、nginxを実行します。

.NET編

ほぼ公式のまんまですが、.slnファイルと同じディレクトリに以下のdockerfileを作成します。

# https://hub.docker.com/_/microsoft-dotnet
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /source

# copy csproj and restore as distinct layers
COPY *.sln .
COPY TodoApp/*.csproj ./TodoApp/
RUN dotnet restore

# copy everything else and build app
COPY TodoApp/. ./TodoApp/
WORKDIR /source/TodoApp
RUN dotnet publish -c release -o /app --no-cache --no-restore

# final stage/image
FROM mcr.microsoft.com/dotnet/aspnet:5.0
WORKDIR /app
COPY --from=build /app ./
ENTRYPOINT ["dotnet", "TodoApp.dll"]

.dockerignoreには、以下のように記載しました。

.dockerignore
# directories
**/bin/
**/obj/
**/out/

# files
Dockerfile*
**/*.trx
**/*.md
**/*.ps1
**/*.cmd
**/*.sh

dockerfileについて説明します。
まず.slnファイルや.csprojファイルをコピーし、dotnet restoreを実行します。
dotnet restoreはプロジェクトの依存関係とツールを復元するコマンドです。
そしてディレクトリを移動し、dotnet publishコマンドを実行します。
--no-restoreを指定することで、dotnet publishが実行されるときに暗黙的にdotnet restoreが実行されるのを防ぎます。

最後のステージで、生成されたTodoApp.dllを実行します。

コンテナ化する

dockerfileが作成できたので、それぞれのイメージをビルドし、実際にコンテナ化します。
それぞれのdockerfileがあるディレクトリに移動し、以下のコマンドを実行します。

Nuxt

docker build -t nuxt-app:v1 .

.NET

docker build -t dotnet-app:v1 .

docker imagesコマンドを実行して、イメージが作成できているか確認します。
作成できていたら、以下のコマンドでコンテナを起動します。

Nuxt

docker run -it -p 8080:80 nuxt-app:v1

.NET

docker run -it -p 5000:5000 dotnet-app:v1

これでコンテナを起動できます!
ブラウザでhttp://localhost:8080にアクセスすると、作成したNuxtアプリが表示されるはずです。

ハマったところ

.NETのリクエストを受け付けるURLの設定

.NET Coreで作成したAPIはデフォルトでhttps://localhost:5001をリッスンしますが、コンテナ内でlocalhost:5001をリッスンしていると、コンテナの外からのリクエストを受け付けられないそうです。
なのでProgram.cs内でリクエストURLを指定しました。(ハードコーディングはあまりよくないですが、今回は勉強がてらなので許してください、、)

Program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                    webBuilder.UseUrls("http://*:5000");

                });

このようにすることでコンテナ外からのリクエストを受け取ることができます。

さいごに

コンテナ化むずかしい、、、

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?