緣起:
假日學 dotnet core 學到無聊,轉去學 docker,想試試看能不能在
pi 上面跑個 dotnet core的 container,跑起來感覺會很酷。
Raspberry pi 安裝 docker:
搜尋 raspberry pi docker 就能找到 docker
官方的教學文件,不過我的是 pi 5, 它的 Raspbian 是 64
位元的作頁系統,所以要看的是在Debian上的安裝教學。
複製指令跟著下就行了,沒碰上什麼問題
先把 pi 上舊版的 docker 相關套件給移除,不然會有衝突。我的
pi 之前沒有裝過 docker,所以指令執行完後,它跟我說 0 upgraded, 0 newly
installed, 0 to remove and 0 not upgraded。
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done
然後下這些指令,安裝 curl 跟 ca-certificates,pi
上是都有了。後面的那些指令是跟憑證的處理有關
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
那個
install 一開始看還以為是跟安裝什麼之類的有關,後來去查才發現,原來是複製檔案的功能。
再來是這個指令,設定 docker apt repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
最後下指令安裝,會佔去 300 多 MB 的容量。
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
最後跑個 sudo docker run hellow-world,如果能看到 container
輸出的 hello world 訊息的話,就代表成功了。
加入 docker 群組:
docker 一開始裝好後,要使用它的指令都要
sudo,蠻麻煩的,所以去找了教學,把自己這個使用者加入 docker 群組後,就可以用 docker 的指令不需要 sudo 了。
新增 dotnet core web 專案並打包成 docker image:
這是在我 ubuntu 筆電上操作的,看這篇文章跟著做的。新增一個 web 專案
dotnet new web -o DockerTest
用 vs code 開啟資料㚒,然後複製它的 Program.cs
程式,再來修改 DockerTest.csproj 檔,把 <TargetFrameWork> 區塊改成
net8.0 (我 ubuntu 上安裝的版本),然後用 dotnet run
測試程式可以跑後,接著處理 Dockerfile 的部份。話說我發現那個 logs.txt
檔是産在 {專案根目錄}/logs.txt,原來用 WebApplication
的 Environment.ContentRootPath 取得的路徑是這樣。
新增一個 Dockerfile,然後輸入内容
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
WORKDIR /app
# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore
# Build and publish a release
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "DockerTest.dll"]
再來 build image,建出一個叫 birdshiu-dockertest 的
image
docker build -t birdshiu-dockertest -f Dockerfile .
然後用 docker run 來執行 container
docker run -d --name birdshiutest -p 8080:5007 birdshiu-dockertest:latest
可以用 docker ps 來列出現在在跑的 container。我在我瀏覽器輸入
localhost:8080,原本期待能看到頁面,但看到的卻是瀏覧器的 network reset
錯誤頁,所以就開始找錯誤。找錯誤時有學到 docker stop {container名稱} =>
停止 container,docker rm {container名稱} => 移除 container,container
要先停止後才能被移除,在這邊還有學到怎麼移除所有的 container。如果是想要重啟停止的 container 的話,可以下
docker restart {container名稱}。
我最後是發現,原來是 appsetting.json 沒有設定, 所以
published 的專案在執行時預設是使用 8080 port,我被 launchSettings.json
給誤導了。
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Kestrel": {
"EndPoints": {
"Http": {
"Url": "http://0.0.0.0:5002"
}
}
}
}
再來重新 build image,由於我是用一樣的 tag
name,所以會産生 dangling image
可以下 docker image prune 來移除它。如果有 container 是依照那個 image 建出來的話,image 會刪不掉,可以先把 container 刪除後再下 docker image prune,這樣就能成功刪除了。
後面我再接著測試重産的 image,run
起來後確認是可以正常運作。
image 的匯出與匯入:
再來要把建好的 image 給放到 raspberry pi 上。看這個文章跟著操作的,把 image 弄成 tar 檔,放到桌面
docker save birdshiu-dockertest > ~/Desktop/birdshiu-dockertest.tar
scp ~/Desktop/birdshiu-dockertest.tar birdshiu@{pi的local ip}:/home/birdshiu/Desktop
檔案傳好後,來到 pi 那邊,移置 Desktop 開啟
terminal,下
docker load < birdshiu-dockertest.tar
等它處理好後,用 docker images 查看我們匯入的 image。我確定
images 有 load 進來後,再下 docker run 的指令,發現它有錯
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm/v8) and no specific platform was requested
exec /usr/bin/dotnet: exec format error
hmmmm.....,好像也是吼, pi 是 arm,我筆電是
x86。所以就換個做法,先用 scp 把整個專案搬到 pi 那邊,搬完後再下 docker
build 的指令來建 image。花了不少時間,大部份的時間是在載 https://mcr.microsoft.com/dotnet/sdk:8.0。
再次跑 docker run ,可以成功執行,而且在瀏覽器輸入
localhost:8080 也能成功看到頁面,讚哦。
在這篇文章學到,可以用 docker exec -it {container名稱}
/bin/bash 來進入 docker 的 shell。我在我的 pi 再開個 terminal,下
docker exec -it birdshiutest /bin/bash
就成功進入 container 裡,再用基本的指令查看文件内容
如果想把東西從 container 裡複製出來的話,可以用 docker cp
沒有留言:
張貼留言