Ubuntu 20.04にdotnet開発環境を構築する。アプリを作りコンテナー化する。
はじめに
仮想環境のUbuntu 20.04環境にdotnet開発環境を構築する。
コンソールアプリを作成し、コンテナー化(docker)する。
本資料のコマンドラインやキャプチャーはmacベースだがWindowsでも動作確認済み。
↓の手順でセットアップした環境を使用する。
- Mac向けMultipassのUbuntu 20.04でLocalStackを使ってみる
- Mac上のVS CodeでRemote-SSHを使い。MultipassのUbuntu 20.04へアクセスする。
- WSL2のUbuntu 20.04をcloud-initで構築してLocalStackを使ってみる
- Windows上のVS CodeでRemote-WSLを使い。WSL2のUbuntu 20.04へアクセスする。
環境
- .NET SDK: 6.0.200
- Microsoft.NETCore.App 6.0.2
- Microsoft.AspNetCore.App 6.0.2
.NET SDK
インストール
信頼されたキーの一覧にMicrosoftパッケージ署名キーを追加し、パッケージ リポジトリを追加する。[1]
ubuntu@docker-vm:~$ curl -O https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb
ubuntu@docker-vm:~$ sudo dpkg -i packages-microsoft-prod.deb
ubuntu@docker-vm:~$ rm packages-microsoft-prod.deb
.NET SDK 6.0インストールする。
ubuntu@docker-vm:~$ sudo apt-get update; \
sudo apt-get install -y apt-transport-https && \
sudo apt-get update && \
sudo apt-get install -y dotnet-sdk-6.0
dotnet --info
ubuntu@docker-vm:~$ dotnet --info
.NET SDK (reflecting any global.json):
Version: 6.0.200
Commit: 4c30de7899
Runtime Environment:
OS Name: ubuntu
OS Version: 20.04
OS Platform: Linux
RID: ubuntu.20.04-x64
Base Path: /usr/share/dotnet/sdk/6.0.200/
Host (useful for support):
Version: 6.0.2
Commit: 839cdfb0ec
.NET SDKs installed:
6.0.200 [/usr/share/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.2 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.2 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
To install additional .NET runtimes or SDKs:
https://aka.ms/dotnet-download
ランタイムの追加
# AspNetCore 5.0系をランタイムをインストール
ubuntu@docker-vm:~$ sudo apt-get install -y aspnetcore-runtime-5.0
dotnet --info
$ dotnet --info
.NET SDK (reflecting any global.json):
Version: 6.0.200
Commit: 4c30de7899
Runtime Environment:
OS Name: ubuntu
OS Version: 20.04
OS Platform: Linux
RID: ubuntu.20.04-x64
Base Path: /usr/share/dotnet/sdk/6.0.200/
Host (useful for support):
Version: 6.0.2
Commit: 839cdfb0ec
.NET SDKs installed:
6.0.200 [/usr/share/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 5.0.14 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.2 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 5.0.14 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.2 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
To install additional .NET runtimes or SDKs:
https://aka.ms/dotnet-download
# NETCore 5.0系をランタイムのみをインストール
ubuntu@docker-vm:~$ sudo apt-get install -y dotnet-runtime-5.0
dotnet --info
$ dotnet --info
.NET SDK (reflecting any global.json):
Version: 6.0.200
Commit: 4c30de7899
Runtime Environment:
OS Name: ubuntu
OS Version: 20.04
OS Platform: Linux
RID: ubuntu.20.04-x64
Base Path: /usr/share/dotnet/sdk/6.0.200/
Host (useful for support):
Version: 6.0.2
Commit: 839cdfb0ec
.NET SDKs installed:
6.0.200 [/usr/share/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.2 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 5.0.14 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.2 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
To install additional .NET runtimes or SDKs:
https://aka.ms/dotnet-download
アンインストール
# すべてをアンインストールする
ubuntu@docker-vm:~$ sudo apt-get remove dotnet-host
コンソールアプリ
プロジェクト作成
作業をフォルダーを作成し、コンソールプロジェクトを作成する。
ubuntu@docker-vm:~$ mkdir docker-working
ubuntu@docker-vm:~$ cd docker-working
ubuntu@docker-vm:~/docker-working$ dotnet new console -o App -n DotNet.Docker
The template "Console App" was created successfully.
Processing post-creation actions...
Running 'dotnet restore' on /home/ubuntu/docker-working/App/DotNet.Docker.csproj...
Determining projects to restore...
Restored /home/ubuntu/docker-working/App/DotNet.Docker.csproj (in 105 ms).
Restore succeeded.
フォルダー構成
docker-working
└── App
├── DotNet.Docker.csproj
├── Program.cs
└── obj
├── DotNet.Docker.csproj.nuget.dgspec.json
├── DotNet.Docker.csproj.nuget.g.props
├── DotNet.Docker.csproj.nuget.g.targets
├── project.assets.json
└── project.nuget.cache
プロジェクトを実行する。
ubuntu@docker-vm:~/docker-working$ cd App/
ubuntu@docker-vm:~/docker-working/App$ dotnet run
Hello, World!
カウンターアプリ作成
VS Codeで仮想環境内のプロジェクトを開いて編集する。
プロジェクトを開く
「エクスプローラー」→「フォルダーを開く」を選択する。
「/home/ubuntu/docker-working/」フォルダーへ移動して「OK」ボタンを押す。
C#プラグインインストール
プロジェクトから「Program.cs」を開いた時にプラグインが未インストールだと表示される。
VS CodeにC#プラグインインストールのサジェストが表示される。
インストールボタンを押す。
インストールが完了するまで待つ。
「YES」ボタンを押す。
「拡張機能: C#」タブを閉じる。
「F5」キーを押してプロジェクトを実行する。
「Hello, World!」が表示される。
コードを編集
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
↑から↓のように書き換える。
var counter = 0;
var max = args.Length != 0 ? Convert.ToInt32(args[0]) : -1;
while (max == -1 || counter < max)
{
Console.WriteLine($"Counter: {++counter}");
await Task.Delay(1000);
}
「F5」キーを押し実行する。
デバッグコンソールに「Counter: 1」から順番にカウントアップすることを確認する。
上部の「□」ボタンを押して停止する。
アプリを作成
VS Codeのターミナルを開く。[2]
publishコマンドでアプリを作成する。
ubuntu@docker-vm:~/docker-working$ cd App/
ubuntu@docker-vm:~/docker-working/App$ dotnet publish -c Release
Microsoft (R) Build Engine version 17.1.0+ae57d105c for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
All projects are up-to-date for restore.
DotNet.Docker -> /home/ubuntu/docker-working/App/bin/Release/net6.0/DotNet.Docker.dll
DotNet.Docker -> /home/ubuntu/docker-working/App/bin/Release/net6.0/publish/
# ファイルの確認
ubuntu@docker-vm:~/docker-working/App$ ls bin/Release/net6.0/publish
DotNet.Docker DotNet.Docker.dll DotNet.Docker.runtimeconfig.json
DotNet.Docker.deps.json DotNet.Docker.pdb
コンテナー化
この項目内はコマンドを読みやすくするために「ubuntu@docker-vm:~/docker-working/App$」を「$」と省略します。
イメージ
Dockerfile作成
Appの下にDockerfileを作成する。
フォルダー構成
docker-working
└── App
├── Dockerfile
├── DotNet.Docker.csproj
├── Program.cs
├── bin
│ ├── Debug
│ │ └── 〜以下略〜
│ └── Release
│ └── net6.0
│ ├── 〜略〜
│ └── publish
│ ├── DotNet.Docker
│ ├── DotNet.Docker.deps.json
│ ├── DotNet.Docker.dll
│ ├── DotNet.Docker.pdb
│ └── DotNet.Docker.runtimeconfig.json
└── obj
〜略〜
Dockerfileの内容は下記の通り。
FROM mcr.microsoft.com/dotnet/aspnet:6.0
COPY bin/Release/net6.0/publish/ App/
WORKDIR /App
ENTRYPOINT ["dotnet", "DotNet.Docker.dll"]
SDKを使用したい場合
「aspnet:6.0」→「sdk:6.0」へ変更する。
FROM mcr.microsoft.com/dotnet/sdk:6.0
COPY bin/Release/net6.0/publish/ App/
WORKDIR /App
ENTRYPOINT ["dotnet", "DotNet.Docker.dll"]
.NET Coreランタイムのみ(ASP.NET Coreランタイムが不要な場合)
「aspnet:6.0」→「runtime:6.0」へ変更する。
FROM mcr.microsoft.com/dotnet/runtime:6.0
COPY bin/Release/net6.0/publish/ App/
WORKDIR /App
ENTRYPOINT ["dotnet", "DotNet.Docker.dll"]
作成
カウンターアプリのイメージを作成する。
$ docker build -t counter-image -f Dockerfile .
Sending build context to Docker daemon 1.023MB
Step 1/4 : FROM mcr.microsoft.com/dotnet/aspnet:6.0
6.0: Pulling from dotnet/aspnet
5eb5b503b376: Pull complete
1d0c01fc21b0: Pull complete
a0a88332a3eb: Pull complete
312960dda1eb: Pull complete
8ad6f1875aa9: Pull complete
Digest: sha256:299dce0ad496ffd8ec987c420e5d66129422247b02ffa7c5779c7a9911770d0a
Status: Downloaded newer image for mcr.microsoft.com/dotnet/aspnet:6.0
---> 09231bfea5df
Step 2/4 : COPY bin/Release/net6.0/publish/ App/
---> 78f302cb2f87
Step 3/4 : WORKDIR /App
---> Running in 38d4b9e21aa6
Removing intermediate container 38d4b9e21aa6
---> c0ca06bc2a55
Step 4/4 : ENTRYPOINT ["dotnet", "DotNet.Docker.dll"]
---> Running in 63e26e64276d
Removing intermediate container 63e26e64276d
---> 206de2aeb877
Successfully built 206de2aeb877
Successfully tagged counter-image:latest
作成されたイメージを確認する。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
counter-image latest 206de2aeb877 About a minute ago 208MB
mcr.microsoft.com/dotnet/aspnet 6.0 09231bfea5df 8 days ago 208MB
〜略〜
削除
イメージの削除をする。
$ docker rmi counter-image:latest
Untagged: counter-image:latest
Deleted: sha256:206de2aeb877bb38687c988e10783a86251b5500e1a458ae06543727a5a6213a
Deleted: sha256:c0ca06bc2a551008718337ce37c94966b9a96d4c1d53b59f64a9c09c7b14066d
Deleted: sha256:78f302cb2f87415313967a98a2b3ed5b13ed3781480d70dd72842256c5effb72
Deleted: sha256:339fb4bf539580dc1f09b22d1a0b9defa90e54c44f307fdb6bd1acd55325f593
$ docker rmi mcr.microsoft.com/dotnet/aspnet:6.0
Untagged: mcr.microsoft.com/dotnet/aspnet:6.0
Untagged: mcr.microsoft.com/dotnet/aspnet@sha256:299dce0ad496ffd8ec987c420e5d66129422247b02ffa7c5779c7a9911770d0a
Deleted: sha256:09231bfea5df094c8fe14ad0cd4905fcc1ffee95fc91041c3bf6f607b24ff40a
Deleted: sha256:a805346469f528735c7bc396c9dbd1f33ecfeb219faaebf7eb07b21c0d64cc38
Deleted: sha256:cb571dae3d5aac905296acb190a64a6cad7b88e3a631d1aac46d199bb8a72fb7
Deleted: sha256:61300747b0169f1b3cc20952506c0ea1397eba89e48a8c28b4fa8d1bbe8f283a
Deleted: sha256:8276c9b27c9a87e163ccbe8b23bd78418e453d97f444196cbca290133373dc5a
Deleted: sha256:7d0ebbe3f5d26c1b5ec4d5dbb6fe3205d7061f9735080b0162d550530328abd6
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
コンテナーが削除されていないとイメージは削除できない
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
30b687176d1b counter-image "dotnet DotNet.Docke…" 54 seconds ago Up 46 seconds core-counter
# コンテナーが動いている状態ではイメージは削除できない
$ docker rmi counter-image:latest
Error response from daemon: conflict: unable to remove repository reference "counter-image:latest" (must force) - container 30b687176d1b is using its referenced image 831fce097bc5
# コンテナーを止める
$ docker stop core-counter
core-counter
# コンテナー登録されている状態ではイメージは削除できない
$ docker rmi counter-image:latest
Error response from daemon: conflict: unable to remove repository reference "counter-image:latest" (must force) - container 30b687176d1b is using its referenced image 831fce097bc5
# コンテナーを削除する
$ docker rm core-counter
core-counter
# イメージが削除できる
$ docker rmi counter-image:latest
Untagged: counter-image:latest
Deleted: sha256:831fce097bc51c70e8ed4208a646dd1b1d198e83ce76cac99aeab795cf96bb9c
Deleted: sha256:7d00db4662b0e8ad7b842c60f3f6d371eaf711af954f2a05ba233fa80ba1cac5
Deleted: sha256:b01f2788cbd39cee9c0be02e5710438c54af57f55ae6d6acad301370c69bf567
Deleted: sha256:919259a2766b656e6aba5ff2da7dc1b6f467738457d74117ce9eda55eee8329d
コンテナー操作
作成
counter-imageからcore-counterコンテナーを作成する。
$ docker create --name core-counter counter-image
84fc51f048981cf69f2e4d9ed1c0ceb3f2a6396fd819d251e2745aa2b8cc445b
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
84fc51f04898 counter-image "dotnet DotNet.Docke…" 17 seconds ago Created core-counter
起動
core-counterを起動する。
$ docker start core-counter
core-counter
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
84fc51f04898 counter-image "dotnet DotNet.Docke…" 2 minutes ago Up 3 seconds core-counter
停止
core-counterを停止する。
$ docker stop core-counter
core-counter
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
84fc51f04898 counter-image "dotnet DotNet.Docke…" 4 minutes ago Exited (143) 1 second ago core-counter
接続
実行状態のコンテナーに接続し、出力を確認する。
$ docker start core-counter
core-counter
$ docker attach --sig-proxy=false core-counter
Counter: 61
Counter: 62
Counter: 63
Counter: 64
# control + cで終了。
^C
削除
core-counterを削除する。
$ docker stop core-counter
core-counter
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
84fc51f04898 counter-image "dotnet DotNet.Docke…" 16 minutes ago Exited (143) 4 seconds ago core-counter
$ docker rm core-counter
core-counter
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
単一実行
1つのコマンドでコンテナー作成と実行する。
コンテナー停止後に、自動でコンテナーは削除される。
$ docker run -it --rm counter-image
Counter: 1
Counter: 2
Counter: 3
Counter: 4
Counter: 5
# control + cで終了。
^C
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
パラメーターをつけて実行する。
$ docker run -it --rm counter-image 3
Counter: 1
Counter: 2
Counter: 3
コンテナーのシェルを使ってログインする。
entrypointを変更することでプログラムではなくシェルを実行する。
$ docker run -it --rm --entrypoint "bash" counter-image
root@7562009fdbf6:/App# ls
DotNet.Docker DotNet.Docker.dll DotNet.Docker.runtimeconfig.json
DotNet.Docker.deps.json DotNet.Docker.pdb
root@7562009fdbf6:/App# dotnet DotNet.Docker.d
DotNet.Docker.deps.json DotNet.Docker.dll
# 実行する
root@7562009fdbf6:/App# dotnet DotNet.Docker.dll 3
Counter: 1
Counter: 2
Counter: 3
root@7562009fdbf6:/App# exit
exit
$
Docker拡張
VS CodeのDocker拡張できる操作。
イメージ操作
単一実行(Run)やRegistriesの操作ができる。
RunするとCONTAINERSに実行状態が表示されるようになる。
コンテナー操作
ログ表示(View Logs)、シェルアクセス(Attach Shell)、コンテナー操作ができる。
ログ表示(View Logs)をするとターミナルにログが表示される。
シェルアクセス(Attach Shell)をするとターミナルでコンテナー内のシェルが使用できる。
参考にしたサイト
- Linux ディストリビューションに .NET をインストールする | Microsoft Docs
- Ubuntu に .NET をインストールする - .NET | Microsoft Docs
- .NET ランタイムと SDK を削除する | Microsoft Docs
- Docker を使用してアプリをコンテナー化するチュートリアル - .NET | Microsoft Docs
-
wslで「curl: (6) Could not resolve host: packages.microsoft.com」が出る場合。一度WSLから抜けて「wsl --shutdown」を行い入り直すと直る。それでもダメな場合は「WSL2 で dns の名前解決ができなくなって ネット接続できなくなった場合の対処方法 - Qiita」という方法もあるようだ。 ↩︎
-
メニューの「ターミナル」→「新しいターミナル」で開く ↩︎
Discussion