iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 6
0

2019/5/14 更新,有實際跑成功的,補貼執行結果

今天也是比較簡單,只是簡單就M$的image介紹,沒有跟Jenkins串連
算是過渡一天~

大家可參考官網文件,就可以學到很完整的起手式囉
只是有些主題不好從左邊tree選單找到
https://docs.microsoft.com/zh-tw/dotnet/core/
再推一個參考文件
https://jakeydocs.readthedocs.io/en/latest/

本篇主要參考will保哥的文章,感恩~
如何將 ASP.NET Core 2.1 網站部署到 Docker 容器中
https://blog.miniasp.com/post/2018/08/25/How-to-deploy-ASPNET-Core-to-Docker-Container.aspx

Develop .NET Core Applications in a Container
https://github.com/dotnet/dotnet-docker/blob/master/samples/dotnetapp/dotnet-docker-dev-in-container.md

下載專案

# 假設在 ~/git/ 目錄底下
$ cd ~/git
$ git clone https://github.com/dotnet/dotnet-docker/

執行專案 dotnet watch run
-v 掛載 host目錄:container目錄,掛到host的dotnet core專案
-w 工作目錄
--rm 會清掉container resources,適合在開發時用,若在production用可能會清掉log
--name dotnetSample 記得給container取個名字
production 下 docker run -d
development 下 docker run --rm -it
dotnet:2.1-sdk 這個image有完整的開發環境

Ubuntu 18.04 叫我們用這個tag 2.1-sdk-bionic
SDK: 2.1-sdk-bionic
Runtime:-2.1-aspnetcore-runtime-bionic

$ docker run --rm -it 
    --name dotnetSample
    -v ~/git/dotnet-docker/samples/dotnetapp:/app/ 
    -w /app/dotnetapp microsoft/dotnet:2.1-sdk 
    dotnet watch run
watch : Polling file watcher is enabled
watch : Started
    Hello from .NET Core!
      __________________
                        \
                        \
                            ....
                            ....'
                            ....
                          ..........
                      .............'..'..
                  ................'..'.....
                .......'..........'..'..'....
                ........'..........'..'..'.....
              .'....'..'..........'..'.......'.
              .'..................'...   ......
              .  ......'.........         .....
              .                           ......
              ..    .            ..        ......
            ....       .                 .......
            ......  .......          ............
              ................  ......................
              ........................'................
            ......................'..'......    .......
          .........................'..'.....       .......
      ........    ..'.............'..'....      ..........
    ..'..'...      ...............'.......      ..........
    ...'......     ...... ..........  ......         .......
  ...........   .......              ........        ......
  .......        '...'.'.              '.'.'.'         ....
  .......       .....'..               ..'.....
    ..       ..........               ..'........
            ............               ..............
          .............               '..............
          ...........'..              .'.'............
        ...............              .'.'.............
        .............'..               ..'..'...........
        ...............                 .'..............
        .........                        ..............
          .....

  
**Environment**
Platform: .NET Core
OS: Linux 4.15.0-47-generic #50-Ubuntu SMP Wed Mar 13 10:44:52 UTC 2019

watch : Exited
watch : Waiting for a file to change before restarting dotnet...
# 如果要跑.net core 2.2,就改成2.2-sdk,好處image包含了SDK,不用再灌了

離開container如果按Ctrl+C可是會中斷container的,如此container就不見了
如果要繼續讓dotnet run跑,就要用Ctrl+P -> Ctrl+Q
記得不要在VS Code底下的terminal跑docker run喔,
因為在VS Code底下按Ctrl+P -> Ctrl+Q,就會關掉VS Code了 = =

幫container取名字的好處就是,不用打不友善的container id

# 查container狀態
$ docker stats dotnetRunSample
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
3f4ecbd8a33d        dotnetRunSample     1.22%               95.65MiB / 7.605GiB   1.23%               38.9kB / 10.8kB     0B / 238kB          43

# 停掉container,由於是跑dotnet run指令,所以停掉就是關掉container了
$ docker stop dotnetRunSample
dotnetRunSample

跑測試
dotnet-docker/samples/dotnetapp/tests
ConsoleUtilsTests.cs StringUtilsTests.cs tests.csproj
是使用xUnit

$ docker run --rm -it 
    --name donetTest
    -v ~/git/dotnet-docker/samples/dotnetapp:/app/ 
    -w /app/tests microsoft/dotnet:2.1-sdk 
    dotnet watch test
    
watch : Polling file watcher is enabled
watch : Started
Test run for /app/tests/bin/container/Debug/netcoreapp2.0/tests.dll(.NETCoreApp,Version=v2.0)
Microsoft (R) Test Execution Command Line Tool Version 16.0.1
Copyright (c) Microsoft Corporation.  All rights reserved.

Starting test execution, please wait...
test text 1
test text 2
test text 3
test text.

Total tests: 3. Passed: 3. Failed: 0. Skipped: 0.
Test Run Successful.
Test execution time: 9.2798 Seconds
watch : Exited
watch : Waiting for a file to change before restarting dotnet...

-c Release 用 release mode(預設的debug模式) 來 build
-o dll檔輸出到host的 out目錄

$ docker run --rm 
    --name donetRelease # dotnet publish跑完就停掉了,所以可以不用給名字
    -v ~/git/dotnet-docker/samples/dotnetapp:/app 
    -w /app/dotnetapp microsoft/dotnet:2.2-sdk 
    dotnet publish -c Release -o out

Microsoft (R) Build Engine version 16.0.450+ga8dc7f1d34 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 438.33 ms for /app/utils/utils.csproj.
  Restore completed in 442.39 ms for /app/dotnetapp/dotnetapp.csproj.
  utils -> /app/utils/bin/container/Release/netstandard2.0/utils.dll
  dotnetapp -> /app/dotnetapp/bin/container/Release/netcoreapp2.2/dotnetapp.dll
  dotnetapp -> /app/dotnetapp/out/

會在這個目錄底下,產生可publish的檔案
dotnet-docker/samples/dotnetapp/dotnetapp/out
dotnetapp.deps.json  dotnetapp.dll  dotnetapp.pdb  dotnetapp.runtimeconfig.json  utils.dll  utils.pdb

清掉build的檔案,但目錄都還在

$ docker run --rm --name donetClean -v ~/git/dotnet-docker/samples/dotnetapp:/app -w /app/dotnetapp microsoft/dotnet:2.2-sdk dotnet clean

Microsoft (R) Build Engine version 16.0.450+ga8dc7f1d34 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 05/14/2019 15:09:55.
     1>Project "/app/dotnetapp/dotnetapp.csproj" on node 1 (Clean target(s)).
     1>CoreClean:
         Deleting file "/app/dotnetapp/bin/container/Debug/netcoreapp2.2/dotnetapp.deps.json".
         Deleting file "/app/dotnetapp/bin/container/Debug/netcoreapp2.2/dotnetapp.runtimeconfig.json".
         Deleting file "/app/dotnetapp/bin/container/Debug/netcoreapp2.2/dotnetapp.runtimeconfig.dev.json".
         Deleting file "/app/dotnetapp/bin/container/Debug/netcoreapp2.2/dotnetapp.dll".
         Deleting file "/app/dotnetapp/bin/container/Debug/netcoreapp2.2/dotnetapp.pdb".
         Deleting file "/app/dotnetapp/bin/container/Debug/netcoreapp2.2/utils.dll".
         Deleting file "/app/dotnetapp/bin/container/Debug/netcoreapp2.2/utils.pdb".
         Deleting file "/app/dotnetapp/obj/container/Debug/netcoreapp2.2/dotnetapp.csprojAssemblyReference.cache".
         Deleting file "/app/dotnetapp/obj/container/Debug/netcoreapp2.2/dotnetapp.csproj.CoreCompileInputs.cache".
         Deleting file "/app/dotnetapp/obj/container/Debug/netcoreapp2.2/dotnetapp.AssemblyInfoInputs.cache".
         Deleting file "/app/dotnetapp/obj/container/Debug/netcoreapp2.2/dotnetapp.AssemblyInfo.cs".
         Deleting file "/app/dotnetapp/obj/container/Debug/netcoreapp2.2/dotnetapp.csproj.CopyComplete".
         Deleting file "/app/dotnetapp/obj/container/Debug/netcoreapp2.2/dotnetapp.dll".
         Deleting file "/app/dotnetapp/obj/container/Debug/netcoreapp2.2/dotnetapp.pdb".
     1>Project "/app/dotnetapp/dotnetapp.csproj" (1) is building "/app/utils/utils.csproj" (2:2) on node 1 (Clean target(s)).
     2>CoreClean:
         Deleting file "/app/utils/bin/container/Debug/netstandard2.0/utils.deps.json".
         Deleting file "/app/utils/bin/container/Debug/netstandard2.0/utils.dll".
         Deleting file "/app/utils/bin/container/Debug/netstandard2.0/utils.pdb".
         Deleting file "/app/utils/obj/container/Debug/netstandard2.0/utils.csprojAssemblyReference.cache".
         Deleting file "/app/utils/obj/container/Debug/netstandard2.0/utils.csproj.CoreCompileInputs.cache".
         Deleting file "/app/utils/obj/container/Debug/netstandard2.0/utils.AssemblyInfoInputs.cache".
         Deleting file "/app/utils/obj/container/Debug/netstandard2.0/utils.AssemblyInfo.cs".
         Deleting file "/app/utils/obj/container/Debug/netstandard2.0/utils.dll".
         Deleting file "/app/utils/obj/container/Debug/netstandard2.0/utils.pdb".
     2>Done Building Project "/app/utils/utils.csproj" (Clean target(s)).
     1>Done Building Project "/app/dotnetapp/dotnetapp.csproj" (Clean target(s)).

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:08.33

.NET Core Docker Samples
https://github.com/dotnet/dotnet-docker/tree/master/samples
官方的sample專案,跑起來很有成就感呢~
aspnetapp #
dotnetapp # 這個是含測試

一行就跑起來了
container的80 port對應到host的8000 port

$ docker run --name aspnetcoreSample --rm -it -p 8000:80 
    microsoft/dotnet-samples:aspnetapp

warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {20ffcf39-febf-41e5-aad4-a63ce57b8677} may be persisted to storage in unencrypted form.
Hosting environment: Production
Content root path: /app
Now listening on: http://[::]:80
Application started. Press Ctrl+C to shut down.
# 然後就能在你的host開瀏覽器囉 http://localhost:8000
$ sudo apt-key adv --keyserver packages.microsoft.com --recv-keys EB3E94ADBE1229CF

$sudo apt-key adv --keyserver packages.microsoft.com --recv-keys 52E16F86FEE04B979B07E28DB02C46DF417A0893

$ sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-bionic-prod bionic main" > /etc/apt/sources.list.d/dotnetdev.list'

$ sudo apt-get update

$ sudo apt-get install dotnet-sdk-2.1.105 

# 列出裝過的sdk或runtime
$ dotnet --list-sdks
$ dotnet --list-runtimes

crypticpassword 就類似 ssh-keygen 的 passphrase

$ dotnet dev-certs https -ep ${HOME}/.aspnet/https/aspnetapp.pfx -p crypticpassword
A valid HTTPS certificate is already present.

$ dotnet dev-certs https --trust # 只支援 macOS、Windows

secrets.json裡面可以放 資料庫的連線字串、token

# 先幫csproj裝package
$ sudo dotnet add package Microsoft.Extensions.SecretManager.Tools

# Secret Manager似乎要靠Visual Studio來建,VS Code似乎無法直接建
# https://github.com/aspnet/AspNetCore.Docs/issues/4889
# 我在猜自己在csproj檔裡加上GUID,再到appsettings.json加入"SecretSetting"應該也可以
  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <UserSecretsId>c44a6ec9-0a57-4680-892d-171e55992805</UserSecretsId>
  </PropertyGroup>

# 這篇借用 Poy Chang 的範例程式來無痛練習
$ git clone https://github.com/poychang/DemoDotnetCoreSecretManager.git
# 進到csproj的目錄
$ cd DemoDotnetCoreSecretManager/DemoDotnetCoreSecretManager

# dotnet user-secrets set 設定
$ dotnet user-secrets -p DemoDotnetCoreSecretManager aspnetapp.csproj set "Kestrel:Certificates:Development:Password" "crypticpassword"
Successfully saved Kestrel:Certificates:Development:Password = crypticpassword to the secret store.

$ dotnet user-secrets list
Kestrel:Certificates:Development:Password = crypticpassword

$ ls ~/.microsoft/usersecrets 
c44a6ec9-0a57-4680-892d-171e55992805 # <userSecretsId>就像GUID

$ ls ~/.microsoft/usersecrets/c44a6ec9-0a57-4680-892d-171e55992805
secrets.json # 會蓋掉 appsetting.json 裡的值

上面是練習,練習完回來看一下指令
本例是拿來放密碼 crypticpassword

$ dotnet user-secrets -p aspnetapp\aspnetapp.csproj set "Kestrel:Certificates:Development:Password" "crypticpassword"
密秘會放在這裡(官方可能會改路徑),用UserSecretsId來identity
Linux: ~/.microsoft/usersecrets/<userSecretsId>/secrets.json
Mac: ~/.microsoft/usersecrets/<userSecretsId>/secrets.json

好處是脫離版控
不過secrets.json裡面資料是明碼,只適合放「開發時期」的機密
在 aspnetapp\aspnetapp.csproj 的 PropertyGroup 會多出 UserSecretsId,用來去secrets.json找秘密的- - - dotnet

$ dotnet user-secrets list # 列出所有secrets
$ dotnet user-secrets set # 設定secrets,"SECRET_SETTING"    "VALUE"
$ cat ./input.json | dotnet user-secrets set # 批次設定
{
  "專案名稱": {
    "SECRET_SETTING": "VALUE",
    "ConnectionString": "VALUE",
    "ServiceApiKey": "VALUE",
  }
}

$ dotnet user-secrets remove # 刪除secrets,"SECRET_SETTING"    "VALUE"
$ dotnet user-secrets clear # 全清

$ docker build --pull -t aspnetapp .
$ docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_ENVIRONMENT=Development -v %APPDATA%\microsoft\UserSecrets\:/root/.microsoft/usersecrets -v %USERPROFILE%\.aspnet\https:/root/.aspnet/https/ aspnetapp


$ docker pull microsoft/dotnet-samples:aspnetapp
$ docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="crypticpassword" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx -v ${HOME}/.aspnet/https:/https/ microsoft/dotnet-samples:aspnetapp

在client端加憑證(開發時使用)

  • macOS
$ sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain <<certificate>>

上一篇
day04_docker03_Docker Swarm
下一篇
day07_補充說明:SSH設定_星期一累累der,先過渡一下
系列文
在地端建置Angular+ASP.NET Core的DevOps環境31

尚未有邦友留言

立即登入留言