<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Linux 彙整 - 泰克哪裡去</title>
	<atom:link href="https://tech.uccu.website/category/it/linux/feed" rel="self" type="application/rss+xml" />
	<link>https://tech.uccu.website/category/it/linux</link>
	<description>一個科技相關的隨手記錄網站</description>
	<lastBuildDate>Sun, 25 Sep 2022 14:11:36 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.1</generator>
<site xmlns="com-wordpress:feed-additions:1">119574712</site>	<item>
		<title>【2022鐵人賽】基本版-建立CI Pipeline(3)</title>
		<link>https://tech.uccu.website/2022ironman-day10-ci-pipeline-deploy-dev-to-cloudrun.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=2022ironman-day10-ci-pipeline-deploy-dev-to-cloudrun</link>
					<comments>https://tech.uccu.website/2022ironman-day10-ci-pipeline-deploy-dev-to-cloudrun.html#respond</comments>
		
		<dc:creator><![CDATA[鳴人]]></dc:creator>
		<pubDate>Sun, 25 Sep 2022 13:59:09 +0000</pubDate>
				<category><![CDATA[2022鐵人賽]]></category>
		<category><![CDATA[Azure DevOps]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Google雲端GCP]]></category>
		<category><![CDATA[iThome鐵人賽]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[雲端]]></category>
		<category><![CDATA[2022ironman]]></category>
		<category><![CDATA[azure devops]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[gcp]]></category>
		<guid isPermaLink="false">https://tech.uccu.website/?p=1930</guid>

					<description><![CDATA[<p>這篇內容利用了Google建置的gcloud的Docker Image來執行gcloud CLI工具的指令，除了先前建立的服務帳戶要補上一個IAM的角色之外，透過Container執行gcloud指令還有一個重點，它將會是能不能夠正常透過Container執行gcloud的關鍵！</p>
<p>這篇文章 <a href="https://tech.uccu.website/2022ironman-day10-ci-pipeline-deploy-dev-to-cloudrun.html">【2022鐵人賽】基本版-建立CI Pipeline(3)</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></description>
										<content:encoded><![CDATA[<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" fetchpriority="high" decoding="async" width="990" height="150" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/00-DevelopCI-Flow.png?resize=990%2C150&#038;ssl=1" alt="" class="wp-image-1931" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/00-DevelopCI-Flow.png?w=990&amp;ssl=1 990w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/00-DevelopCI-Flow.png?resize=300%2C45&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/00-DevelopCI-Flow.png?resize=768%2C116&amp;ssl=1 768w" sizes="(max-width: 990px) 100vw, 990px" /><figcaption>Develop CI流程</figcaption></figure></div>


<p>上面這張圖是<a href="https://tech.uccu.website/2022ironman-day3-flow-plan.html" target="_blank" rel="noreferrer noopener">流程規劃說明</a>裡面畫的Develop CI Pipeline流程，我們已經在前兩篇完成了Build(Code)、Build Image，剩下最後一步就是Deploy Dev環境，這一篇就來完成這最後一步吧！</p>



<pre class="wp-block-prismatic-blocks"><code class="language-yaml">trigger:
- none

pool:
  vmImage: ubuntu-latest

resources:
  repositories:
  - repository: sources
    type: git
    name: ironman2022/NetApp
    ref: Develop
    trigger:
      branches:
        include:
          - Develop

variables:
  pipelineArtifact: output
  buildResultZipName: buildResult.zip
  slnOrCsprojName: IronmanWeb.sln
  imgRepository: &#039;asia-east1-docker.pkg.dev/feisty-mechanic-363012/ironman2022/ironmanweb&#039;
  buildDockerfile: &#039;Dockerfile&#039;
  imgRegistryService: &#039;GCPArtifactRegistry&#039;
  cloudRunServiceName: ironmanweb
  cloudRunPort: 8080
  cloudRunRegion: asia-east1
  cloudRunProjectId: feisty-mechanic-363012
  gcpAuthJsonFile: ironman2022-gcp-key.json

jobs:
  - job: BuildCode
    steps:
      - checkout: sources
        clean: true
      - script: |
          export UID=$(id -u)
          export GID=$(id -g)
          docker run --user $UID:$GID --rm \
          -v $(Build.SourcesDirectory):/tmp/source \
          -v $(Build.BinariesDirectory):/tmp/publish \
          -e DOTNET_CLI_HOME=/tmp/.dotnet \
          mcr.microsoft.com/dotnet/sdk:6.0-alpine \
          dotnet publish /tmp/source/$(slnOrCsprojName) \
          -c release \
          -o /tmp/publish
        displayName: Dotnet Build
      - task: ArchiveFiles@2
        displayName: 壓縮成zip
        inputs:
          rootFolderOrFile: $(Build.BinariesDirectory)
          includeRootFolder: false
          archiveType: &#039;zip&#039;
          archiveFile: &#039;$(Build.ArtifactStagingDirectory)/zipFiles/$(buildResultZipName)&#039;
          replaceExistingArchive: true
      - task: PublishBuildArtifacts@1
        displayName: 上傳到Pipeline Artifact
        inputs:
          PathtoPublish: &#039;$(Build.ArtifactStagingDirectory)/zipFiles/$(buildResultZipName)&#039;
          ArtifactName: &#039;$(pipelineArtifact)&#039;
          publishLocation: &#039;Container&#039;
  - job: BuildImage
    dependsOn: BuildCode
    steps:
      - task: DownloadBuildArtifacts@0
        displayName: 下載Pipeline Artifact
        inputs:
          buildType: &#039;current&#039;
          cleanDestinationFolder: true
          downloadType: &#039;single&#039;
          artifactName: &#039;$(pipelineArtifact)&#039;
          downloadPath: &#039;$(System.ArtifactsDirectory)/&#039;
      - task: ExtractFiles@1
        displayName: Unzip zip
        inputs:
          archiveFilePatterns: &#039;$(System.ArtifactsDirectory)/$(pipelineArtifact)/$(buildResultZipName)&#039;
          destinationFolder: &#039;$(System.ArtifactsDirectory)/BuildImage&#039;
          cleanDestinationFolder: true
          overwriteExistingFiles: true
      - task: Docker@2
        displayName: Build image
        inputs:
          repository: &#039;$(imgRepository)&#039;
          command: &#039;build&#039;
          Dockerfile: $(buildDockerfile)
          buildContext: &#039;$(System.ArtifactsDirectory)/BuildImage&#039;
          arguments: &#039;--no-cache&#039;
          tags: |
            latest
      - task: Docker@2
        displayName: &quot;Login to Container Registry&quot;
        inputs:
          command: login
          containerRegistry: $(imgRegistryService)
      - task: Bash@3
        displayName: Push docker image
        inputs:
          targetType: &#039;inline&#039;
          script: |
            docker push -a $(imgRepository)
  - job: DeployCloudRun
    dependsOn: BuildImage
    steps:
      - task: Bash@3
        displayName: Deploy docker image to cloudrun
        inputs:
          targetType: &#039;inline&#039;
          script: |
            docker run --rm \
            -v $(Build.SourcesDirectory)/$(gcpAuthJsonFile):/gcp/cloudKey.json \
            asia.gcr.io/google.com/cloudsdktool/google-cloud-cli:latest \
            bash -c &quot;gcloud auth login --cred-file=/gcp/cloudKey.json &amp;&amp; gcloud run deploy $(cloudRunServiceName) --set-env-vars=Ironman=$(Build.BuildId) --image $(imgRepository) --region $(cloudRunRegion) --project $(cloudRunProjectId) --allow-unauthenticated&quot;</code></pre>



<p>哇！一來就是一長串的YAML內容…</p>



<p>不不不，你如果是用VSCode打開，幾乎可以把前面兩個Job折疊起來，這邊增加的DeployCloudRun Job也只有一個Bash的task，不多的。</p>



<p>就讓我娓娓道來這篇主要增加的內容吧！</p>



<pre class="wp-block-prismatic-blocks"><code class="language-yaml">  cloudRunServiceName: ironmanweb
  cloudRunPort: 8080
  cloudRunRegion: asia-east1
  cloudRunProjectId: feisty-mechanic-363012
  gcpAuthJsonFile: ironman2022-gcp-key.json</code></pre>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" decoding="async" width="602" height="240" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/01-CloudRunList.png?resize=602%2C240&#038;ssl=1" alt="" class="wp-image-1936" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/01-CloudRunList.png?w=602&amp;ssl=1 602w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/01-CloudRunList.png?resize=300%2C120&amp;ssl=1 300w" sizes="(max-width: 602px) 100vw, 602px" /></figure></div>


<p>cloudRunServiceName就是圖中Cloud Run的名稱。</p>



<p>cloudRunPort設定為8080是在appsettings.json中設定了Kestrel的Http是使用8080 Port，也就是container內會監聽什麼Port，對應docker指令就是-p 80:8080。</p>



<p>cloudRunRegion則是CloudRun佈署的區域(機房)。</p>



<p>cloudRunProjectId可以直接從Google Cloud管理介面的URL得知，也就是在上圖畫面的時候，看一下瀏覽器上的網址列，「&amp;project=」後面的就是了，或是選擇Project的下拉選單：</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" decoding="async" width="1024" height="399" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/02-GCPFindProjectId-1024x399.png?resize=1024%2C399&#038;ssl=1" alt="" class="wp-image-1938" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/02-GCPFindProjectId.png?resize=1024%2C399&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/02-GCPFindProjectId.png?resize=300%2C117&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/02-GCPFindProjectId.png?resize=768%2C299&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/02-GCPFindProjectId.png?w=1142&amp;ssl=1 1142w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption>Google Cloud的Project Id</figcaption></figure></div>


<p>最後的gcpAuthJsonFile則是前面幾篇用來授權的Json檔案。不過這邊要補充一下，<a href="https://tech.uccu.website/2022ironman-day4-create-registry-and-service-account.html" target="_blank" rel="noreferrer noopener">那時候</a>在新增服務帳戶的時候還少加了一個「<strong>服務帳戶使用者</strong>」角色，所以漏加這個角色繼續做下去的話，就會碰到下面的錯誤訊息：</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p></p><cite>PERMISSION_DENIED: Permission &#8216;iam.serviceaccounts.actAs&#8217; denied on service account</cite></blockquote>



<p>為了讓後面使用gcloud cli可以順利執行，所以要先在<a href="https://console.cloud.google.com/iam-admin/iam?hl=zh-TW" target="_blank" rel="noreferrer noopener">IAM</a>裡面將前面新增的服務帳戶加上「<strong>服務帳戶使用者</strong>」角色：</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="424" height="340" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/03-AddGCPIAMRole.png?resize=424%2C340&#038;ssl=1" alt="" class="wp-image-1939" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/03-AddGCPIAMRole.png?w=424&amp;ssl=1 424w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/03-AddGCPIAMRole.png?resize=300%2C241&amp;ssl=1 300w" sizes="auto, (max-width: 424px) 100vw, 424px" /><figcaption>新增「<strong>服務帳戶使用者</strong>」角色</figcaption></figure></div>


<p>增加角色之後不需要重新下載用於授權的Json檔案，因為有什麼角色權限不會寫在檔案裡。</p>



<p>Job越加越多，這三個Job之間其實是有相依性的，也就是說要先BuildCode之後才能夠BuildImage，接下來才能DeployCloudRun，所以在第二個和第三個Job底下分別要加上dependsOn的屬性：</p>



<pre class="wp-block-prismatic-blocks"><code class="language-yaml">- job: BuildImage
    dependsOn: BuildCode</code></pre>



<pre class="wp-block-prismatic-blocks"><code class="language-yaml">- job: DeployCloudRun
    dependsOn: BuildImage</code></pre>



<p>這個部份滿重要的，尤其是如果有<a href="https://azure.microsoft.com/zh-tw/pricing/details/devops/azure-devops-services/" target="_blank" rel="noreferrer noopener">額外購買CloudAgent的執行數量</a>時，因為Job可以在不同的Agent執行，所以它可以在同一個Pipeline同時跑多個Job(沒有設定相依的dependsOn時)，就算沒有額外購買CloudAgent的執行數量，沒設定dependsOn也無法保證它們的執行順序。BuildImage的Job相較前一篇有增加的也只有dependsOn這個屬性。</p>



<p>最後就是DeployCloudRun這個Job，裡面的內容也只有一個Bash的task，所以下面我直接貼bash script的部份：</p>



<pre class="wp-block-prismatic-blocks"><code class="language-bash">            docker run --rm \
            -v $(Build.SourcesDirectory)/$(gcpAuthJsonFile):/gcp/cloudKey.json \
            asia.gcr.io/google.com/cloudsdktool/google-cloud-cli:latest \
            bash -c &quot;gcloud auth login --cred-file=/gcp/cloudKey.json &amp;&amp; gcloud run deploy $(cloudRunServiceName) --set-env-vars=Ironman=$(Build.BuildId) --image $(imgRepository) --region $(cloudRunRegion) --project $(cloudRunProjectId) --allow-unauthenticated&quot;</code></pre>



<p>在這裡是使用google的gcloud CLI工具來執行CloudRun的佈署，不過gcloud CLI工具還是需要安裝的，要嘛是需要先裝在Agent的電腦內，而且還要去爬<a href="https://cloud.google.com/sdk/docs/install" target="_blank" rel="noreferrer noopener">官方的安裝文件</a>知道怎麼安裝，不然就是安裝在Docker Image裡面。</p>



<p>我們使用的是ClougAgent，所以Agent的環境不是我們可以控制的，每次執行也是新的vm執行起來，所以選擇後者使用google建立的gcloud CLI的Docker Image會是最理想的選擇，除了從<a href="https://hub.docker.com/r/google/cloud-sdk" target="_blank" rel="noreferrer noopener">Docker Hub</a>可以找到之外，<a href="https://cloud.google.com/sdk/docs/downloads-docker" target="_blank" rel="noreferrer noopener">官方文件</a>也有提供不同Container Registry的選擇說明。</p>



<p>使用Container來執行gcloud CLI，我們可以省去安裝的麻煩事，只要會使用就可以了，這讓我們可以更專注在其它的設計部份。</p>



<p>script中的重點只有第二行和最後一行，分別是把授權用的Json檔案關聯到Container裡面，以便讓裡面的gcloud CLI工具可以讀取到內容進行login動作，以及最後一行包含lgoin的指令。</p>



<p>最後一行的指令有個重點，就是我們必須先使用gloud auth login的指令讓CLI工具登入，接著才能執行CloudRun的Deploy指令，也就是說要執行的指令有兩個，所以使用了「&amp;&amp;」這個管道符號讓它接續執行，但是直接這樣接在Image Repository後面是行不通的，「&amp;&amp;」符號的前面會跟最前面的docker run指令合起來作為第一個指令，後面的則是host環境接續docker run指令執行的第二個指令。</p>



<p>所以在這個地方必須是讓docker run執行起來的contianer是執行bash程式，後面接著要執行的指令字串(用引號包起來)，也因為是一整個字串，所以沒辦法使用「\\」換行，就會是一行很長的指令，下面為了方便閱讀，把它們拆開來說明。</p>



<pre class="wp-block-prismatic-blocks"><code class="language-bash">gcloud auth login --cred-file=/gcp/cloudKey.json</code></pre>



<p>「&amp;&amp;」符號前的這一行是將gcloud CLI工具登入，使用&#8211;cred-file參數帶入Json檔案，後面的路徑是Container內的路徑，也就是前面-v設定的部份。</p>



<pre class="wp-block-prismatic-blocks"><code class="language-batch">gcloud run deploy $(cloudRunServiceName) --set-env-vars=Ironman=$(Build.BuildId) --image $(imgRepository) --region $(cloudRunRegion) --project $(cloudRunProjectId) --allow-unauthenticated</code></pre>



<p>「&amp;&amp;」符號後面的指令我依參數拆行來看應該就很清楚，因為大部份都是上面設定的變數，已經有說明過了。</p>



<p>&#8211;set-env-vars的參數是設定CloudRun放入的環境變數(還記得前面的Ironman環境變數嗎？)，&#8211;allow-unauthenticated則是允許訪客瀏覽，不然CloudRun可能不會正常回應頁面。</p>



<p>gcloud run deploy $(cloudRunServiceName) <br>&#8211;set-env-vars=Ironman=$(Build.BuildId) <br>&#8211;image $(imgRepository) <br>&#8211;region $(cloudRunRegion) <br>&#8211;project $(cloudRunProjectId) <br>&#8211;allow-unauthenticated</p>



<p>關於CloudRun在gcloud CLI可以設定的更多參數部份，請參考<a href="https://cloud.google.com/sdk/gcloud/reference/run/deploy" target="_blank" rel="noreferrer noopener">官方文件的頁面</a>，之後的文章還會把部份參數用上。</p>



<p>最後，在CI Pipeline成功執行完之後，就可以在對應的Task log中看到gcloud CLI工具吐出來的CloudRun網址，這樣就不用進入到GCP的管理介面去查看。</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="689" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/04-DeployCloudRunLog-1024x689.png?resize=1024%2C689&#038;ssl=1" alt="" class="wp-image-1940" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/04-DeployCloudRunLog.png?resize=1024%2C689&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/04-DeployCloudRunLog.png?resize=300%2C202&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/04-DeployCloudRunLog.png?resize=768%2C516&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/04-DeployCloudRunLog.png?w=1316&amp;ssl=1 1316w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>


<p>最後補充一個小細節，就是在這三個Job之中，只有BuildCode這個Job中有明確的加上checkout: sources，並且身份驗證的Json檔案是放在Pipelines這個Git Repository裡面，但是在後面的BuildImage和DeployCloudRun並沒有明確加上checkout動作卻會(可以)取得Pipelines這個Git Repository裡面的檔案，也沒有在resources.repositories底下設定Pipelines，主要是因為這裡的Pipeline YAML檔案就是放在Pipelines這個Git Repository裡面，所以隱含了checkout: self這個動作，替我們省下了一些設定。(下圖紅框與藍框的差異)</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="336" height="1024" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/05-DefaultCheckoutSelfRepo-336x1024.png?resize=336%2C1024&#038;ssl=1" alt="" class="wp-image-1941" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/05-DefaultCheckoutSelfRepo.png?resize=336%2C1024&amp;ssl=1 336w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/05-DefaultCheckoutSelfRepo.png?resize=98%2C300&amp;ssl=1 98w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/05-DefaultCheckoutSelfRepo.png?resize=504%2C1536&amp;ssl=1 504w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2022/09/05-DefaultCheckoutSelfRepo.png?w=547&amp;ssl=1 547w" sizes="auto, (max-width: 336px) 100vw, 336px" /></figure></div><p>這篇文章 <a href="https://tech.uccu.website/2022ironman-day10-ci-pipeline-deploy-dev-to-cloudrun.html">【2022鐵人賽】基本版-建立CI Pipeline(3)</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tech.uccu.website/2022ironman-day10-ci-pipeline-deploy-dev-to-cloudrun.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1930</post-id>	</item>
		<item>
		<title>【2021鐵人賽】建立自管的Azure DevOps Agent(Linux Container agent)</title>
		<link>https://tech.uccu.website/2021ironman-day22-build-linux-container-image-for-azure-devops-agent.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=2021ironman-day22-build-linux-container-image-for-azure-devops-agent</link>
					<comments>https://tech.uccu.website/2021ironman-day22-build-linux-container-image-for-azure-devops-agent.html#respond</comments>
		
		<dc:creator><![CDATA[鳴人]]></dc:creator>
		<pubDate>Mon, 04 Oct 2021 15:40:42 +0000</pubDate>
				<category><![CDATA[2021鐵人賽]]></category>
		<category><![CDATA[Azure DevOps]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[iThome鐵人賽]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[資訊科技]]></category>
		<category><![CDATA[2021ironman]]></category>
		<category><![CDATA[azure devops]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[docker]]></category>
		<guid isPermaLink="false">https://tech.uccu.website/?p=1292</guid>

					<description><![CDATA[<p>前一篇文章建立了Azure DevOps Agent的Windows Container Image，已經知道了基本的概念就是：1.選擇基底映像檔、2.安裝所需要的額外套件與程式、3.將Azure DevOps Agent的開始程式start.ps/start.sh複製進去。</p>
<p>這篇文章 <a href="https://tech.uccu.website/2021ironman-day22-build-linux-container-image-for-azure-devops-agent.html">【2021鐵人賽】建立自管的Azure DevOps Agent(Linux Container agent)</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p><a href="https://tech.uccu.website/2021ironman-day21-build-windows-container-image-for-azure-devops-agent.html" target="_blank" rel="noreferrer noopener">前一篇文章</a>建立了Azure DevOps Agent的Windows Container Image，已經知道了基本的概念就是：</p>



<ol class="wp-block-list"><li>選擇基底映像檔</li><li>安裝所需要的額外套件與程式</li><li>將Azure DevOps Agent的開始程式start.ps/start.sh複製進去</li></ol>



<p>既然已經知道了上面的概念，前一篇也有做過一次，那麼這篇就少浪費一些篇幅，直接把Code端上來看吧！</p>



<p>start.sh的內容如下，記得要改成Unix格式的結束符號(LF)喔！(或是透過dos2unix轉換)</p>



<pre class="wp-block-prismatic-blocks"><code class="language-bash">#!/bin/bash
set -e

if [ -z &quot;$AZP_URL&quot; ]; then
  echo 1&gt;&amp;2 &quot;error: missing AZP_URL environment variable&quot;
  exit 1
fi

if [ -z &quot;$AZP_TOKEN_FILE&quot; ]; then
  if [ -z &quot;$AZP_TOKEN&quot; ]; then
    echo 1&gt;&amp;2 &quot;error: missing AZP_TOKEN environment variable&quot;
    exit 1
  fi

  AZP_TOKEN_FILE=/azp/.token
  echo -n $AZP_TOKEN &gt; &quot;$AZP_TOKEN_FILE&quot;
fi

unset AZP_TOKEN

if [ -n &quot;$AZP_WORK&quot; ]; then
  mkdir -p &quot;$AZP_WORK&quot;
fi

export AGENT_ALLOW_RUNASROOT=&quot;1&quot;

cleanup() {
  if [ -e config.sh ]; then
    print_header &quot;Cleanup. Removing Azure Pipelines agent...&quot;

    # If the agent has some running jobs, the configuration removal process will fail.
    # So, give it some time to finish the job.
    while true; do
      ./config.sh remove --unattended --auth PAT --token $(cat &quot;$AZP_TOKEN_FILE&quot;) &amp;&amp; break

      echo &quot;Retrying in 30 seconds...&quot;
      sleep 30
    done
  fi
}

print_header() {
  lightcyan=&#039;\033[1;36m&#039;
  nocolor=&#039;\033[0m&#039;
  echo -e &quot;${lightcyan}$1${nocolor}&quot;
}

# Let the agent ignore the token env variables
export VSO_AGENT_IGNORE=AZP_TOKEN,AZP_TOKEN_FILE

source ./env.sh

print_header &quot;1. Configuring Azure Pipelines agent...&quot;

./config.sh --unattended \
  --agent &quot;${AZP_AGENT_NAME:-$(hostname)}&quot; \
  --url &quot;$AZP_URL&quot; \
  --auth PAT \
  --token $(cat &quot;$AZP_TOKEN_FILE&quot;) \
  --pool &quot;${AZP_POOL:-Default}&quot; \
  --work &quot;${AZP_WORK:-_work}&quot; \
  --replace \
  --acceptTeeEula &amp; wait $!

print_header &quot;2. Running Azure Pipelines agent...&quot;

trap &#039;cleanup; exit 0&#039; EXIT
trap &#039;cleanup; exit 130&#039; INT
trap &#039;cleanup; exit 143&#039; TERM

# To be aware of TERM and INT signals call run.sh
# Running it with the --once flag at the end will shut down the agent after the build is executed
./run.sh &quot;$@&quot;</code></pre>



<p>官方的Dockerfile內容如下：</p>



<pre class="wp-block-prismatic-blocks"><code class="language-dockerfile">FROM ubuntu:18.04

# To make it easier for build and release pipelines to run apt-get,
# configure apt to not require confirmation (assume the -y argument by default)
ENV DEBIAN_FRONTEND=noninteractive
RUN echo &quot;APT::Get::Assume-Yes \&quot;true\&quot;;&quot; &gt; /etc/apt/apt.conf.d/90assumeyes

RUN apt-get update &amp;&amp; apt-get install -y --no-install-recommends \
    ca-certificates \
    curl \
    jq \
    git \
    iputils-ping \
    libcurl4 \
    libicu60 \
    libunwind8 \
    netcat \
    libssl1.0 \
  &amp;&amp; rm -rf /var/lib/apt/lists/*

RUN curl -LsS https://aka.ms/InstallAzureCLIDeb | bash \
  &amp;&amp; rm -rf /var/lib/apt/lists/*

ARG TARGETARCH=amd64
ARG AGENT_VERSION=2.185.1

WORKDIR /azp
RUN if [ &quot;$TARGETARCH&quot; = &quot;amd64&quot; ]; then \
      AZP_AGENTPACKAGE_URL=https://vstsagentpackage.azureedge.net/agent/${AGENT_VERSION}/vsts-agent-linux-x64-${AGENT_VERSION}.tar.gz; \
    else \
      AZP_AGENTPACKAGE_URL=https://vstsagentpackage.azureedge.net/agent/${AGENT_VERSION}/vsts-agent-linux-${TARGETARCH}-${AGENT_VERSION}.tar.gz; \
    fi; \
    curl -LsS &quot;$AZP_AGENTPACKAGE_URL&quot; | tar -xz

COPY ./start.sh .
RUN chmod +x start.sh

ENTRYPOINT [ &quot;./start.sh&quot; ]</code></pre>



<p>同樣的，上面的Dockerfile並不包含dotnet sdk，所以仍然需要自行安裝進去。</p>



<p>也和上一篇提到的一樣，我們可以透過在Docker hub上找到官方的dotnet sdk映像檔，找到我們要的OS版本，然後取代Dockerfile第一行的FROM後面使用的image repository：</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="439" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/718841de-dotnetsdkimage-linuxamd64tags-1024x439.png?resize=1024%2C439&#038;ssl=1" alt="" class="wp-image-1298" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/718841de-dotnetsdkimage-linuxamd64tags.png?resize=1024%2C439&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/718841de-dotnetsdkimage-linuxamd64tags.png?resize=300%2C129&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/718841de-dotnetsdkimage-linuxamd64tags.png?resize=768%2C329&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/718841de-dotnetsdkimage-linuxamd64tags.png?resize=1536%2C659&amp;ssl=1 1536w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/718841de-dotnetsdkimage-linuxamd64tags.png?w=1665&amp;ssl=1 1665w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>上圖的表格來自於微軟在<a href="https://hub.docker.com/_/microsoft-dotnet-sdk/" target="_blank" rel="noreferrer noopener">Docker Hub上的dotnet sdk頁面</a>，dotnet sdk的image repository是mcr.microsoft.com/dotnet/sdk:5.0，我們只需要將冒號後面的5.0改成需要的就行了，以上面紅框內容為例，就把5.0改為5.0-focal，這樣就是以Ubuntu 20.04為版本安裝了dotnet sdk 5.0製作的Docker image，再加上安裝PowerShell、Docker的話，最終的Dockerfile內容如下：</p>



<pre class="wp-block-prismatic-blocks"><code class="language-dockerfile">FROM mcr.microsoft.com/dotnet/sdk:5.0-focal

# To make it easier for build and release pipelines to run apt-get,
# configure apt to not require confirmation (assume the -y argument by default)
ENV DEBIAN_FRONTEND=noninteractive
RUN echo &quot;APT::Get::Assume-Yes \&quot;true\&quot;;&quot; &gt; /etc/apt/apt.conf.d/90assumeyes

#在這底下加入要額外裝在Docker Image內的程式

RUN apt-get update &amp;&amp; apt-get install -y --no-install-recommends \
    ca-certificates \
    curl \
    jq \
    git \
    iputils-ping \
    libcurl4 \
    libicu66 \
    libunwind8 \
    netcat \
    libssl1.0 \
	wget \
  &amp;&amp; rm -rf /var/lib/apt/lists/*

# 新增 Microsoft 存放庫金鑰和摘要
RUN wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb &amp;&amp; \
         dpkg -i packages-microsoft-prod.deb

# 安裝PowerShell
# Enable the &quot;universe&quot; repositories &amp; Install PowerShell
RUN apt-get update &amp;&amp; apt-get install -y powershell

# 安裝Docker
RUN apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add
RUN add-apt-repository \
   &quot;deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable&quot;
RUN apt-get update &amp;&amp; apt-get install docker-ce docker-ce-cli containerd.io

#===========================================

RUN curl -LsS https://aka.ms/InstallAzureCLIDeb | bash \
  &amp;&amp; rm -rf /var/lib/apt/lists/*

ARG TARGETARCH=amd64
ARG AGENT_VERSION=2.185.1

WORKDIR /azp
RUN if [ &quot;$TARGETARCH&quot; = &quot;amd64&quot; ]; then \
      AZP_AGENTPACKAGE_URL=https://vstsagentpackage.azureedge.net/agent/${AGENT_VERSION}/vsts-agent-linux-x64-${AGENT_VERSION}.tar.gz; \
    else \
      AZP_AGENTPACKAGE_URL=https://vstsagentpackage.azureedge.net/agent/${AGENT_VERSION}/vsts-agent-linux-${TARGETARCH}-${AGENT_VERSION}.tar.gz; \
    fi; \
    curl -LsS &quot;$AZP_AGENTPACKAGE_URL&quot; | tar -xz

COPY ./start.sh .
RUN chmod +x start.sh

ENTRYPOINT [ &quot;./start.sh&quot; ]</code></pre>



<p>上面的Dockerfile內容中要特別提一下在官方的範例中安裝的libicu60 package只適用在Ubuntu 18.04(<a href="https://askubuntu.com/questions/1225781/unable-to-locate-package-libicu60" target="_blank" rel="noreferrer noopener">參考這篇</a>)，因為我是選Ubuntu 20.04，所以改成libicu66(<a href="https://github.com/dotnet/core/issues/4360#issuecomment-618638299" target="_blank" rel="noreferrer noopener">參考這篇</a>)。</p>



<p>準備好Dockerfile和start.sh這兩個檔案之後，執行下面的指令建立映像檔：</p>



<pre class="wp-block-prismatic-blocks"><code class="language-docker">docker build -t devopsagent .</code></pre>



<p>完成Build Image的動作之後，透過下面的指令建立一個名為azure-agent的Container：</p>



<pre class="wp-block-prismatic-blocks"><code class="language-docker">docker run --name azure-agent -d -v /var/run/docker.sock:/var/run/docker.sock -e AZP_URL=[AzureDevOpsURL] -e AZP_TOKEN=[AzureDevOpsPAT] -e AZP_AGENT_NAME=[AzureDevOpsAgentName] IMAGE:TAG</code></pre>



<p>docker run的指令和<a href="https://tech.uccu.website/2021ironman-day21-build-windows-container-image-for-azure-devops-agent.html" target="_blank" rel="noreferrer noopener">前一篇</a>的大同小異，主要差別在於如何繫結host的docker給container使用。</p>



<p>同樣的環境變數表再貼一次：</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1025" height="408" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/4582d3e6-devopsagent-containerenvironmentvariables.png?resize=1025%2C408&#038;ssl=1" alt="" class="wp-image-1265" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/4582d3e6-devopsagent-containerenvironmentvariables.png?w=1025&amp;ssl=1 1025w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/4582d3e6-devopsagent-containerenvironmentvariables.png?resize=300%2C119&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/4582d3e6-devopsagent-containerenvironmentvariables.png?resize=768%2C306&amp;ssl=1 768w" sizes="auto, (max-width: 1025px) 100vw, 1025px" /><figcaption>Azure DevOps Agent所使用的環境變數</figcaption></figure></div>



<p>同樣貼一下執行的結果：</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1006" height="669" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/b80fcbf2-devopsagent-runagentinlinuxcontainer.png?resize=1006%2C669&#038;ssl=1" alt="" class="wp-image-1301" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/b80fcbf2-devopsagent-runagentinlinuxcontainer.png?w=1006&amp;ssl=1 1006w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/b80fcbf2-devopsagent-runagentinlinuxcontainer.png?resize=300%2C200&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/b80fcbf2-devopsagent-runagentinlinuxcontainer.png?resize=768%2C511&amp;ssl=1 768w" sizes="auto, (max-width: 1006px) 100vw, 1006px" /></figure></div>



<p>還有Agent Pools裡的列表和Agent的Capabilities：</p>



<div class="wp-block-image"><figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="793" height="344" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/4e5fe0f5-agentpools-default-linuxcontaineragent.png?resize=793%2C344&#038;ssl=1" alt="" class="wp-image-1304" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/4e5fe0f5-agentpools-default-linuxcontaineragent.png?w=793&amp;ssl=1 793w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/4e5fe0f5-agentpools-default-linuxcontaineragent.png?resize=300%2C130&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/4e5fe0f5-agentpools-default-linuxcontaineragent.png?resize=768%2C333&amp;ssl=1 768w" sizes="auto, (max-width: 793px) 100vw, 793px" /></figure></div>



<div class="wp-block-image"><figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="784" height="927" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/7b7c07bc-agentpools-default-linuxcontaineragent-capabilities.png?resize=784%2C927&#038;ssl=1" alt="" class="wp-image-1307" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/7b7c07bc-agentpools-default-linuxcontaineragent-capabilities.png?w=784&amp;ssl=1 784w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/7b7c07bc-agentpools-default-linuxcontaineragent-capabilities.png?resize=254%2C300&amp;ssl=1 254w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2021/10/7b7c07bc-agentpools-default-linuxcontaineragent-capabilities.png?resize=768%2C908&amp;ssl=1 768w" sizes="auto, (max-width: 784px) 100vw, 784px" /></figure></div>



<p>其它和前一篇的內容沒什麼太大的差別，至於Linux VM的部份意思差不多，所以就不再另外弄一篇安裝在Linux VM裡的文章了</p>
<p>這篇文章 <a href="https://tech.uccu.website/2021ironman-day22-build-linux-container-image-for-azure-devops-agent.html">【2021鐵人賽】建立自管的Azure DevOps Agent(Linux Container agent)</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tech.uccu.website/2021ironman-day22-build-linux-container-image-for-azure-devops-agent.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1292</post-id>	</item>
		<item>
		<title>解決.sh檔案在Container內執行時的換行字元(CRLF/LF)問題</title>
		<link>https://tech.uccu.website/convert-shell-file-end-of-line-sequence-at-dockerfile.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=convert-shell-file-end-of-line-sequence-at-dockerfile</link>
					<comments>https://tech.uccu.website/convert-shell-file-end-of-line-sequence-at-dockerfile.html#respond</comments>
		
		<dc:creator><![CDATA[鳴人]]></dc:creator>
		<pubDate>Tue, 24 Nov 2020 09:47:26 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[crlf]]></category>
		<category><![CDATA[dockerfile]]></category>
		<category><![CDATA[dos2unix]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[shell]]></category>
		<guid isPermaLink="false">https://tech.uccu.website/?p=158</guid>

					<description><![CDATA[<p>如果有在使用Docker並且是建置Linux環境的Image，搭配自行撰寫的shell檔案，有時候會因為版本控 ... <a title="解決.sh檔案在Container內執行時的換行字元(CRLF/LF)問題" class="read-more" href="https://tech.uccu.website/convert-shell-file-end-of-line-sequence-at-dockerfile.html" aria-label="Read more about 解決.sh檔案在Container內執行時的換行字元(CRLF/LF)問題">閱讀全文</a></p>
<p>這篇文章 <a href="https://tech.uccu.website/convert-shell-file-end-of-line-sequence-at-dockerfile.html">解決.sh檔案在Container內執行時的換行字元(CRLF/LF)問題</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>如果有在使用Docker並且是建置Linux環境的Image，搭配自行撰寫的shell檔案，有時候會因為版本控管、編輯器(IDE)等雜七雜八的因素，導致在Dockerfile中複製到Image的時候看起來雖然沒問題，但是在Run Container的時候出現因為換行字元(CRLF/LF)導致的錯誤時，除了可以回頭去調整或修改shell檔案，將換行字元從CRLF轉換成LF之外，還有一個更方便的方法，那就是在shell檔案複製到Docker Image的時候再執行轉換的動作。</p>



<p>起先我在寫Shell檔案的時候真的是碰到了許多次因為CRLF / LF換行字元的問題，早期都是回頭去修改原始檔案之後再重新Build Image，久了之後實在是覺得很麻煩，某天忽然想到直接在Dockerfile中安裝<em><strong>dos2unix</strong></em>這個套件，在shell檔案複製之後再執行它來將shell檔案的換行字元的問題解決，從此之後就沒有再為了Windows / Unix-like不同環境的換行字元問題而煩惱過了，因此特別用這篇文章簡短記錄一下，也許有人也為了這個問題困擇了一段時間呢！</p>



<h2 class="wp-block-heading">Dockerfile內容參考範例</h2>



<pre class="wp-block-prismatic-blocks"><code class="language-docker">RUN apt-get install dos2unix;
COPY my-init.sh .
RUN dos2unix my-init.sh
CMD [&quot;bash&quot;, &quot;my-init.sh&quot;]</code></pre>
<p>這篇文章 <a href="https://tech.uccu.website/convert-shell-file-end-of-line-sequence-at-dockerfile.html">解決.sh檔案在Container內執行時的換行字元(CRLF/LF)問題</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tech.uccu.website/convert-shell-file-end-of-line-sequence-at-dockerfile.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">158</post-id>	</item>
		<item>
		<title>Linux container中修改json檔案設定值的方法</title>
		<link>https://tech.uccu.website/how-to-modify-json-file-in-linux-container.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-modify-json-file-in-linux-container</link>
					<comments>https://tech.uccu.website/how-to-modify-json-file-in-linux-container.html#respond</comments>
		
		<dc:creator><![CDATA[鳴人]]></dc:creator>
		<pubDate>Tue, 24 Nov 2020 09:10:21 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[appsettings.json]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[linux]]></category>
		<guid isPermaLink="false">https://tech.uccu.website/?p=151</guid>

					<description><![CDATA[<p>現在許多的程式設計都使用了json格式的檔案作為設定檔的儲存格式，可以跨平台在Linux環境執行的.Net C ... <a title="Linux container中修改json檔案設定值的方法" class="read-more" href="https://tech.uccu.website/how-to-modify-json-file-in-linux-container.html" aria-label="Read more about Linux container中修改json檔案設定值的方法">閱讀全文</a></p>
<p>這篇文章 <a href="https://tech.uccu.website/how-to-modify-json-file-in-linux-container.html">Linux container中修改json檔案設定值的方法</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>現在許多的程式設計都使用了json格式的檔案作為設定檔的儲存格式，可以跨平台在Linux環境執行的.Net Core也不例外，伴隨著appsettings.json檔案中許多的設定，不管是預設的設定，或是不同開發需求自行加入進去的設定值，全部都是json格式。</p>



<p>為了在docker啟動container的時候可以根據繫結的環境參數(environment, -e)值做出相對應的修改，因此需要有個方便的作法可以在container執行的時候動態修改json檔案。</p>



<p>這一篇文章就來介紹如何在Linux中透過jq套件修改json文件。</p>



<span id="more-151"></span>



<h2 class="wp-block-heading">先決條件</h2>



<p>Container中需要先安裝jq套件，所以必須在Dockerfile中先透過<em>apt-get install -y jq</em>指令(Ubuntu/Debian)安裝jq套件，以便Docker Image中有jq套件可以使用。</p>



<h2 class="wp-block-heading">使用方式</h2>



<p>假設在Dockerfile中定義了<em><strong>ENV&nbsp;LOG_LEVEL=Error</strong></em>，並且appsettings.json檔案中有段Serilog的設定如下：</p>



<pre class="wp-block-prismatic-blocks"><code class="language-json">{
    &quot;Serilog&quot;: {
        &quot;MinimumLevel&quot;: &quot;Debug&quot;,
        &quot;WriteTo&quot;: [
            {
                &quot;Name&quot;: &quot;File&quot;,
                &quot;Args&quot;: {
                    &quot;path&quot;: &quot;MyApp.log&quot;,
                    &quot;outputTemplate&quot;: &quot;{Timestamp:yyyy-MM-dd HH:mm:ss} RequestID:{RequestID} User:{UserID} {RequestPath} {SourceContext} [{Level:u3}] {Message:lj}{NewLine}{Exception}&quot;,
                    &quot;rollingInterval&quot;: &quot;Day&quot;
                }
            }
        ],
        &quot;Enrich&quot;: [ &quot;FromLogContext&quot; ]
    }
}</code></pre>



<p>可以看到在Serilog中有個MinimumLevel屬性設定的是Debug，這個設定會記錄大量的Log記錄，但是有時候在執行container的時候並不想要記錄這麼詳細的資訊，以降低檔案大小，減少儲存空間的耗用時，有個LOG_LEVEL的ENV設定就可以方便的調整設定值。</p>



<p>現在假設有個.Net Core的程式叫MyApp，Build完之後有個MyApp.dll檔案，在Dockerfile中設定了ENV和複製相關的執行檔案之外，還需要一個.sh檔案(Linux中的Shell檔，相當於Windows的.cmd或.bat)，假設這個檔案叫做app-init.sh。</p>



<p>接下來在app-init.sh檔案中要做下面這幾件事：</p>



<ol class="wp-block-list"><li>判斷container是不是第一次執行，以避免每次都進行修改appsettings.json的動作。</li><li>透過jq套件將appsettings.json的內容讀入記憶體。</li><li>找到MinimumLevel屬性，將值修改為LOG_LEVEL這個ENV所設定的值。</li><li>將jq套件修改後的內容儲存為appsettings.temp.json。</li><li>將原本的appsettings.json改名為appsettings.ori.json。</li><li>將前面的appsettings.temp.json改名為appsettings.json。</li><li>產生一個用來判斷是否執行過app-init.sh的檔案，例如：inited。</li><li>啟動MyApp。</li></ol>



<p>假設Dockerfile中設定的WORKDIR是/app，第7點的檔案是放在/app/inited，那麼app-init.sh的程式碼內容大概會是下面這個樣子：</p>



<pre class="wp-block-prismatic-blocks"><code class="language-bash">if [ -f &quot;/app/inited&quot; ]; then
    echo &quot;Container inited, skip this shell.&quot;
else
    cat appsettings.json #這行只是先輸出原本的設定值，用來查看用的
    jq &#039;.Serilog.MinimumLevel=env.LOG_LEVEL&#039; appsettings.json &gt; appsettings.temp.json

    cat appsettings.temp.json #查看儲存的檔案內容

    mv appsettings.json appsettings.ori.json #第5點，將原本的設定檔改名
    mv appsettings.temp.json appsettings.json #第6點，將jq儲存的暫存檔改為正式檔名

    echo &quot;Container inited.&quot; &gt; /app/inited #第7點，產生判斷是否init過的檔案
fi

dotnet MyApp.dll #第8點，啟動MyApp</code></pre>



<p>透過上面的app-init.sh檔案，在Container第一次執行的時候就會根據設定的內容修改appsettings.json檔案，產生的inited檔案可以避免container restart之後重複執行init的動作。</p>



<p>透過這樣的技巧，也可以修改appsettings.json中的資料庫連線字串，如果是像Serilog底下的WriteTo屬性是陣列(集合)型式的，則是用[0]、[1]這樣的方式設定，範例如下：</p>



<pre class="wp-block-prismatic-blocks"><code class="language-bash">jq &#039;.Serilog.MinimumLevel=env.LOG_LEVEL&#039; appsettings.json | \
jq &#039;.Serilog.WriteTo[0].Args.rollingInterval=env.LOG_ROLLING_INTERVAL&#039;  &gt; appsettings.temp.json</code></pre>
<p>這篇文章 <a href="https://tech.uccu.website/how-to-modify-json-file-in-linux-container.html">Linux container中修改json檔案設定值的方法</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tech.uccu.website/how-to-modify-json-file-in-linux-container.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">151</post-id>	</item>
		<item>
		<title>Linux(Ubuntu)磁碟分割</title>
		<link>https://tech.uccu.website/linux-format-disk.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=linux-format-disk</link>
					<comments>https://tech.uccu.website/linux-format-disk.html#respond</comments>
		
		<dc:creator><![CDATA[鳴人]]></dc:creator>
		<pubDate>Wed, 11 Nov 2020 10:16:52 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ubuntu]]></category>
		<guid isPermaLink="false">https://tech.uccu.website/?p=136</guid>

					<description><![CDATA[<p>在雲端上建立的Linux VM預設的空間都不大，或是有些其它需求另外增加一個資料磁碟的情況，做了幾次新增磁碟之 ... <a title="Linux(Ubuntu)磁碟分割" class="read-more" href="https://tech.uccu.website/linux-format-disk.html" aria-label="Read more about Linux(Ubuntu)磁碟分割">閱讀全文</a></p>
<p>這篇文章 <a href="https://tech.uccu.website/linux-format-disk.html">Linux(Ubuntu)磁碟分割</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>在雲端上建立的Linux VM預設的空間都不大，或是有些其它需求另外增加一個資料磁碟的情況，做了幾次新增磁碟之後的磁碟分割、格式化等動作，但是因為脫離GUI的環境要記下龐大的Linux指令是很困難的(年紀大了)，所以趁這次又要做一次的時候趕快把過程記錄下來。</p>



<p>一開始可以使用「sudo fdisk -l」的方式來列出目前系統中的磁碟(Disk)，看看有哪些磁碟(Disk)與分割區(Partition)。</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="511" height="485" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/0d3c8939-image.png?resize=511%2C485&#038;ssl=1" alt="" class="wp-image-137" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/0d3c8939-image.png?w=511&amp;ssl=1 511w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/0d3c8939-image.png?resize=300%2C285&amp;ssl=1 300w" sizes="auto, (max-width: 511px) 100vw, 511px" /><figcaption>系統中的磁碟資訊</figcaption></figure></div>



<p>從上圖看到系統中有三個不同的Disk，而我新增加的是最下面的/dev/sdc 250G大小的Disk，它就是我要下手的目標。</p>



<p>接下來輸入「sudo fdisk /dev/sdc」(後面沒數字)，執行fdisk進入操作模式。</p>



<p>一開始會出現上半部的訊息，如果常操作fdisk工具記得各種選項是做什麼用的，可以直接輸入選項的代號，不然可以輸入m來查看(如下半部)：</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="551" height="719" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/ea018de3-image.png?resize=551%2C719&#038;ssl=1" alt="" class="wp-image-138" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/ea018de3-image.png?w=551&amp;ssl=1 551w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/ea018de3-image.png?resize=230%2C300&amp;ssl=1 230w" sizes="auto, (max-width: 551px) 100vw, 551px" /><figcaption>fdisk選項</figcaption></figure></div>



<p>因為是一個新的完全空白的磁碟，所以選擇n來建立新的Partition，接下來會詢問是要建立主要分割區還是延伸分割區、分割區號碼、開始與結束磁區位置(就是要割多大)等，如果是使用預設值的話也可以直接按Enter不用輸入。</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="629" height="157" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/ce748140-image.png?resize=629%2C157&#038;ssl=1" alt="" class="wp-image-140" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/ce748140-image.png?w=629&amp;ssl=1 629w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/ce748140-image.png?resize=300%2C75&amp;ssl=1 300w" sizes="auto, (max-width: 629px) 100vw, 629px" /><figcaption>建立一個新的分割區</figcaption></figure></div>



<p>完成上面的步驟之後，這些改變只是暫時存在記憶體，再輸入w選項，將變更寫入磁碟之後離開。</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="352" height="68" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/a6f5c402-image.png?resize=352%2C68&#038;ssl=1" alt="" class="wp-image-143" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/a6f5c402-image.png?w=352&amp;ssl=1 352w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/a6f5c402-image.png?resize=300%2C58&amp;ssl=1 300w" sizes="auto, (max-width: 352px) 100vw, 352px" /><figcaption>將fdisk的變更寫入磁碟後離開</figcaption></figure></div>



<p>再輸入一次「sudo fdisk -l」指令重新查看列表，發現最下面多了/dev/sdc1的項目，這就是剛才分割的Parition了。</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="511" height="561" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/23d11dae-image.png?resize=511%2C561&#038;ssl=1" alt="" class="wp-image-145" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/23d11dae-image.png?w=511&amp;ssl=1 511w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/23d11dae-image.png?resize=273%2C300&amp;ssl=1 273w" sizes="auto, (max-width: 511px) 100vw, 511px" /></figure></div>



<p>fdisk是用來做磁碟分割使用，分割完之後還要format格式化才能儲存檔案，在Linux環境中使用mkfs(<strong><span style="color:#ff0000" class="has-inline-color">M</span></strong>a<strong><span style="color:#ff0000" class="has-inline-color">k</span></strong>e a Linux <strong><span style="color:#ff0000" class="has-inline-color">f</span></strong>ilesy<strong><span style="color:#ff0000" class="has-inline-color">s</span></strong>tem的縮寫)，選項的說明可以輸入「sudo mkfs &#8211;help」來查看。</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="580" height="243" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/f074fc44-image.png?resize=580%2C243&#038;ssl=1" alt="" class="wp-image-144" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/f074fc44-image.png?w=580&amp;ssl=1 580w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/f074fc44-image.png?resize=300%2C126&amp;ssl=1 300w" sizes="auto, (max-width: 580px) 100vw, 580px" /><figcaption>mkfs的選項</figcaption></figure></div>



<p>我打算將它格式化為xfs格式，所以就輸入「sudo mkfs -t xfs /dev/sdc1」(後面數字要正確)，系統使用預設的設定值格式化之後的資訊如下：</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="686" height="137" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/a4fe2eb2-image.png?resize=686%2C137&#038;ssl=1" alt="" class="wp-image-147" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/a4fe2eb2-image.png?w=686&amp;ssl=1 686w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/a4fe2eb2-image.png?resize=300%2C60&amp;ssl=1 300w" sizes="auto, (max-width: 686px) 100vw, 686px" /><figcaption>格式化後的資訊</figcaption></figure></div>



<p>格式化完成之後需要掛載起來，在Windows就是要給它個磁碟機代號(當然也可以掛在某個資料夾下)。</p>



<p>Windows做完格式化並設定完磁碟機代號後就可以使用了，就算重新開機還是會看得到新增的磁碟分割，但是Linux如果要開機時也會自動掛載起來的話，需要將相關資訊寫入/etc/fstab檔案中，在這之前會需要知道分割區的UUID，所以先輸入「sudo blkid」找到對應的UUID。</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="73" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/dcb8550d-image-1024x73.png?resize=1024%2C73&#038;ssl=1" alt="" class="wp-image-148" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/dcb8550d-image.png?resize=1024%2C73&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/dcb8550d-image.png?resize=300%2C21&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/dcb8550d-image.png?resize=768%2C55&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/11/dcb8550d-image.png?w=1107&amp;ssl=1 1107w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>找到要掛載的分割區UUID</figcaption></figure>



<p>將UUID裡面的值複製下來之後，輸入「sudo nano /etc/fstab」(我這裡用nano編輯器來修改，也可以用別的)，內容會長得像下面的樣子，分別是Device, Mount point, FileSystem, Parameters, dump, fsck，反正不是很熟就照著第一列的格式輸入大概就行了。</p>



<pre class="wp-block-code"><code>#
# /etc/fstab
# Created by anaconda on Thu Sep  7 20:55:27 2017
#
# Accessible filesystems, by reference, are maintained under &#039;/dev/disk&#039;
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=3c11fba3-32c7-4d0c-b614-aad5630504eb /                       xfs     defaults        0 0
UUID=ca02dd2d-a91b-4fb1-b24b-0fb19c18b89d /boot                   xfs     defaults        0 0
</code></pre>



<p>檔案儲存之後，如果要掛載的位置(資料夾)不存在，需要先建立之後再掛載，輸入「sudo mkdir 掛載路徑」建立完<strong><span style="color:#ff0000" class="has-inline-color">空的資料夾</span></strong>之後，最後再輸入「sudo mount -a」將fstab裡面設定的項目都掛載起來。</p>



<h3 class="wp-block-heading">參考來源</h3>



<ul class="wp-block-list"><li><a href="http://linux.vbird.org/linux_basic/0230filesystem/0230filesystem-fc4.php" target="_blank" rel="noreferrer noopener nofollow">http://linux.vbird.org/linux_basic/0230filesystem/0230filesystem-fc4.php</a></li><li><a href="https://blog.gtwang.org/linux/linux-add-format-mount-harddisk/" target="_blank" rel="noreferrer noopener nofollow">https://blog.gtwang.org/linux/linux-add-format-mount-harddisk/</a></li></ul>



<p></p>
<p>這篇文章 <a href="https://tech.uccu.website/linux-format-disk.html">Linux(Ubuntu)磁碟分割</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tech.uccu.website/linux-format-disk.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">136</post-id>	</item>
		<item>
		<title>Azure VM 開啟 Ping 網路規則</title>
		<link>https://tech.uccu.website/enable-azure-vm-ping.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=enable-azure-vm-ping</link>
					<comments>https://tech.uccu.website/enable-azure-vm-ping.html#respond</comments>
		
		<dc:creator><![CDATA[鳴人]]></dc:creator>
		<pubDate>Mon, 26 Oct 2020 03:46:03 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[微軟雲端Azure]]></category>
		<category><![CDATA[雲端]]></category>
		<guid isPermaLink="false">https://tech.uccu.website/?p=118</guid>

					<description><![CDATA[<p>Ping這個網路工具(指令)是時常被拿來測試網路是否通順的功能，除了可以測試機器的網路是否正常之外，有時候還會 ... <a title="Azure VM 開啟 Ping 網路規則" class="read-more" href="https://tech.uccu.website/enable-azure-vm-ping.html" aria-label="Read more about Azure VM 開啟 Ping 網路規則">閱讀全文</a></p>
<p>這篇文章 <a href="https://tech.uccu.website/enable-azure-vm-ping.html">Azure VM 開啟 Ping 網路規則</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>Ping這個網路工具(指令)是時常被拿來測試網路是否通順的功能，除了可以測試機器的網路是否正常之外，有時候還會拿來觀察網路延遲的時間。</p>



<p>這次的需求是為了知道簡單網路行為的耗用時間，也就是延遲時間，所以透過Ping這個簡單的網路測試功能來獲得Client端到Server端的網路耗用時間(ms)，用在計算某些服務耗用時間的扣除基準。</p>



<p>不過，雲端服務的防火牆預設是不開放任何網路封包從外面進入，必須根據需求在網路規則介面上建立，像是常用到的Web 80 Port，或是Windows遠端連線RDP的3389，所以這次需要在網路規則中加上Ping的允許規則。</p>



<span id="more-118"></span>



<p>Ping的網路規則和一般開啟Port Number不太一樣，Ping是透過ICMP協定傳送的封包，所以不是像一般設定TCP/UDP的規則，Port Number的部份不需要指定，直接填入*即可。</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="570" height="878" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/10/35d3f6d4-image.png?resize=570%2C878&#038;ssl=1" alt="" class="wp-image-119" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/10/35d3f6d4-image.png?w=570&amp;ssl=1 570w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/10/35d3f6d4-image.png?resize=195%2C300&amp;ssl=1 195w" sizes="auto, (max-width: 570px) 100vw, 570px" /></figure></div>



<p>如果是Linux的VM，可以輸入<code>cat /proc/sys/net/ipv4/icmp_echo_ignore_all</code>，看看顯示的值是0(啟用Ping回應)還是1(停用Ping回應)，如果是0的話，應該就可以正常Ping得到該台VM才是。</p>



<h3 class="wp-block-heading">【參考來源】</h3>



<ul class="wp-block-list"><li><a href="https://www.netadmin.com.tw/netadmin/zh-tw/technology/111381F2995A4AB48672E965F63133AE" target="_blank" rel="noreferrer noopener nofollow">搞懂ICMP協定及工具 抵擋「死亡之Ping」攻擊</a></li><li><a href="https://zh.wikipedia.org/zh-tw/%E4%BA%92%E8%81%94%E7%BD%91%E6%8E%A7%E5%88%B6%E6%B6%88%E6%81%AF%E5%8D%8F%E8%AE%AE%E7%AC%AC%E5%85%AD%E7%89%88" target="_blank" rel="noreferrer noopener nofollow">網際網路控制訊息協定第六版</a></li><li><a href="https://www.thomasmaurer.ch/2019/09/how-to-enable-ping-icmp-echo-on-an-azure-vm/" target="_blank" rel="noreferrer noopener nofollow">HOW TO ENABLE PING (ICMP ECHO) ON AN AZURE VM</a></li><li><a href="https://monovm.com/post/38/enable-ping-in-linux">enable ping in linux</a></li></ul>



<p></p>
<p>這篇文章 <a href="https://tech.uccu.website/enable-azure-vm-ping.html">Azure VM 開啟 Ping 網路規則</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tech.uccu.website/enable-azure-vm-ping.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">118</post-id>	</item>
		<item>
		<title>Linux指令筆記</title>
		<link>https://tech.uccu.website/linux-cmd-notes.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=linux-cmd-notes</link>
					<comments>https://tech.uccu.website/linux-cmd-notes.html#respond</comments>
		
		<dc:creator><![CDATA[鳴人]]></dc:creator>
		<pubDate>Thu, 22 Oct 2020 02:02:02 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://tech.uccu.website/?p=113</guid>

					<description><![CDATA[<p>最近時常與Linux的作業系統為舞，相較於使用了20幾年的Windows環境來說，Linux是個相對較陌生的環 ... <a title="Linux指令筆記" class="read-more" href="https://tech.uccu.website/linux-cmd-notes.html" aria-label="Read more about Linux指令筆記">閱讀全文</a></p>
<p>這篇文章 <a href="https://tech.uccu.website/linux-cmd-notes.html">Linux指令筆記</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>最近時常與Linux的作業系統為舞，相較於使用了20幾年的Windows環境來說，Linux是個相對較陌生的環境，以前玩過Linux系統的經驗仍然是以GUI的介面為主，但是在操作Docker的情況下，只有command line的模式，必須要將使用過的指令筆記下來，才不會在需要的時候重複花時間在網路大海裡撈針。</p>



<p>這篇文章主要是簡易的快速筆記，如果有較多的心得與內容整理，會再個別獨立寫成一篇篇的文章。</p>



<h2 class="wp-block-heading">【硬體類】</h2>



<h3 class="wp-block-heading">查看硬體資訊</h3>



<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<h4 class="wp-block-heading"><span style="color:#0000ff" class="has-inline-color">lshw</span></h4>



<p>這個指令會列出電腦上所有的硬體資訊，輸入內容很長一串。<br>實際上在使用的時候發現有些時候這個指令會無法使用，例如在Azure上的RedHat VM中就會找不到這個指令(沒有安裝package?)。</p>
</div></div>



<h3 class="wp-block-heading">查看CPU資訊</h3>



<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<h4 class="wp-block-heading"><span style="color:#0000ff" class="has-inline-color">lscpu</span></h4>



<p>這個指令會列出CPU的基本資訊，其中CPU(s)是CPU的核心數，這個部份如果是在VM中查詢的話，列出的是VM擁有幾個核心的資源，因為根據Model name的資料查詢，以下面的例子來說，8272CL應該有26核心。</p>



<pre class="wp-block-code"><code>Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                4
On-line CPU(s) list:   0-3
Thread(s) per core:    1
Core(s) per socket:    4
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 85
Model name:            Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz
Stepping:              7
CPU MHz:               2593.906
BogoMIPS:              5187.81
Hypervisor vendor:     Microsoft
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              1024K
L3 cache:              36608K
NUMA node0 CPU(s):     0-3
Flags:                 fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt avx512cd avx512bw avx512vl xsaveopt xsavec md_clear</code></pre>
</div></div>



<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<h4 class="wp-block-heading"><span style="color:#0000ff" class="has-inline-color">cat /proc/cpuinfo</span></h4>



<pre class="wp-block-code"><code>processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 85
model name      : Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz
stepping        : 7
microcode       : 0xffffffff
cpu MHz         : 2593.906
cache size      : 36608 KB
physical id     : 0
siblings        : 4
core id         : 0
cpu cores       : 4
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 21
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt avx512cd avx512bw avx512vl xsaveopt xsavec md_clear
bogomips        : 5187.81
clflush size    : 64
cache_alignment : 64
address sizes   : 46 bits physical, 48 bits virtual
power management:

processor       : 1
vendor_id       : GenuineIntel
cpu family      : 6
model           : 85
model name      : Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz
stepping        : 7
microcode       : 0xffffffff
cpu MHz         : 2593.906
cache size      : 36608 KB
physical id     : 0
siblings        : 4
core id         : 1
cpu cores       : 4
apicid          : 1
initial apicid  : 1
fpu             : yes
fpu_exception   : yes
cpuid level     : 21
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt avx512cd avx512bw avx512vl xsaveopt xsavec md_clear
bogomips        : 5187.81
clflush size    : 64
cache_alignment : 64
address sizes   : 46 bits physical, 48 bits virtual
power management:

processor       : 2
vendor_id       : GenuineIntel
cpu family      : 6
model           : 85
model name      : Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz
stepping        : 7
microcode       : 0xffffffff
cpu MHz         : 2593.906
cache size      : 36608 KB
physical id     : 0
siblings        : 4
core id         : 2
cpu cores       : 4
apicid          : 2
initial apicid  : 2
fpu             : yes
fpu_exception   : yes
cpuid level     : 21
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt avx512cd avx512bw avx512vl xsaveopt xsavec md_clear
bogomips        : 5187.81
clflush size    : 64
cache_alignment : 64
address sizes   : 46 bits physical, 48 bits virtual
power management:

processor       : 3
vendor_id       : GenuineIntel
cpu family      : 6
model           : 85
model name      : Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz
stepping        : 7
microcode       : 0xffffffff
cpu MHz         : 2593.906
cache size      : 36608 KB
physical id     : 0
siblings        : 4
core id         : 3
cpu cores       : 4
apicid          : 3
initial apicid  : 3
fpu             : yes
fpu_exception   : yes
cpuid level     : 21
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt avx512cd avx512bw avx512vl xsaveopt xsavec md_clear
bogomips        : 5187.81
clflush size    : 64
cache_alignment : 64
address sizes   : 46 bits physical, 48 bits virtual
power management:
</code></pre>
</div></div>



<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<h2 class="wp-block-heading">參考來源</h2>



<ul class="wp-block-list"><li><a href="https://blog.gtwang.org/linux/linux-hardware-information-command/" target="_blank" rel="noreferrer noopener nofollow">https://blog.gtwang.org/linux/linux-hardware-information-command/</a></li></ul>
</div></div>
<p>這篇文章 <a href="https://tech.uccu.website/linux-cmd-notes.html">Linux指令筆記</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tech.uccu.website/linux-cmd-notes.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">113</post-id>	</item>
		<item>
		<title>WSL啟動時，自動啟動Docker服務</title>
		<link>https://tech.uccu.website/auto-start-docker-service-when-wsl-start.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=auto-start-docker-service-when-wsl-start</link>
					<comments>https://tech.uccu.website/auto-start-docker-service-when-wsl-start.html#respond</comments>
		
		<dc:creator><![CDATA[鳴人]]></dc:creator>
		<pubDate>Thu, 10 Sep 2020 09:11:37 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[wsl]]></category>
		<guid isPermaLink="false">https://tech.uccu.website/?p=94</guid>

					<description><![CDATA[<p>如果有看前一篇文章，也就是在WSL中安裝原生的Docker環境，可能在電腦重新啟動之後輸入wsl進入Linux ... <a title="WSL啟動時，自動啟動Docker服務" class="read-more" href="https://tech.uccu.website/auto-start-docker-service-when-wsl-start.html" aria-label="Read more about WSL啟動時，自動啟動Docker服務">閱讀全文</a></p>
<p>這篇文章 <a href="https://tech.uccu.website/auto-start-docker-service-when-wsl-start.html">WSL啟動時，自動啟動Docker服務</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>如果有看前一篇文章，也就是在WSL中安裝原生的Docker環境，可能在電腦重新啟動之後輸入wsl進入Linux子系統時，會發現docker怎麼好像又不能使用了？</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="152" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/5682d84c-image-1024x152.png?resize=1024%2C152&#038;ssl=1" alt="Docker服務未啟動(Server無法連線)" class="wp-image-84" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/5682d84c-image.png?resize=1024%2C152&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/5682d84c-image.png?resize=300%2C45&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/5682d84c-image.png?resize=768%2C114&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/5682d84c-image.png?w=1351&amp;ssl=1 1351w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>重新啟動wsl之後輸入docker的指令無法使用</figcaption></figure>



<p>其實這只是因為電腦重新啟動後，WSL環境也是重新啟動，所有額外安裝的程式與服務都需要手動重新啟動它們，所以這時候只要再輸入<code>sudo service docker start</code>，再執行docker的指令就可以正常工作了。</p>



<p>不過每次WSL重新啟動之後都需要輸入指令讓docker服務啟動，說實在的有一點麻煩，因為通常用到WSL的時候就是要在裡面跑docker container，所以如果在輸入wsl進入Linux子系統環境的時候就能夠自動將服務啟動的話，那不是方便很多嗎？</p>



<p>這一篇文章就是說明該如何在Linux子系統設定自動啟動docker服務，這個概念其實就和Windows作業系統啟動的時候要執行什麼事情所做的設定是相同的概念，所以也不限於使用在WSL的環境喔！</p>



<span id="more-94"></span>



<h3 class="wp-block-heading">自動啟動Docker服務</h3>



<p>首先，進入WSL之後，輸入<code>cd ~</code>切換到使用者的根目錄，接著再輸入<code>sudo nano .bashrc</code>，透過nano編輯.bashrc這個檔案。</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="537" height="99" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/1fdf22ea-image.png?resize=537%2C99&#038;ssl=1" alt="" class="wp-image-95" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/1fdf22ea-image.png?w=537&amp;ssl=1 537w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/1fdf22ea-image.png?resize=300%2C55&amp;ssl=1 300w" sizes="auto, (max-width: 537px) 100vw, 537px" /><figcaption>切換到使用者根目錄編輯.bashrc檔案</figcaption></figure></div>



<p>接著會看到裡面有一堆的設定值，直接在最上面第一行將啟動docker的指令<code>sudo service docker start</code>輸入進去，然後按下鍵盤的ctrl+x離開，詢問要不要儲存檔案的時候按y，接著再直接按enter就行了。</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="233" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/b96156ef-image-1024x233.png?resize=1024%2C233&#038;ssl=1" alt="" class="wp-image-96" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/b96156ef-image.png?resize=1024%2C233&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/b96156ef-image.png?resize=300%2C68&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/b96156ef-image.png?resize=768%2C175&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/b96156ef-image.png?w=1297&amp;ssl=1 1297w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>在.bashrc檔案的第一行加入啟動docker服務的指令</figcaption></figure>



<p>到這個動作其實已經可以讓WSL在啟動的時候自動將docker服務啟動起來，不過這樣子只能算是完成了一半，因為在WSL啟動的時候仍然需要一個麻煩的動作：輸入密碼。</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="201" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/e0044eed-image-1024x201.png?resize=1024%2C201&#038;ssl=1" alt="" class="wp-image-97" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/e0044eed-image.png?resize=1024%2C201&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/e0044eed-image.png?resize=300%2C59&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/e0044eed-image.png?resize=768%2C151&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/e0044eed-image.png?resize=1536%2C302&amp;ssl=1 1536w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/e0044eed-image.png?w=1675&amp;ssl=1 1675w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>WSL啟動時因為利用sudo去啟動docker服務，所以需要輸入密碼</figcaption></figure>



<h3 class="wp-block-heading">省略輸入密碼設定</h3>



<p>其實輸入密碼的這個動作也是可以設定成不需要輸入，同樣是透過編輯設定就行。</p>



<p>進入WSL之後輸入<code>sudo visudo</code>，進入設定編輯畫面，這次我們選擇在最下面一行輸入設定值：</p>



<p><code>&lt;em&gt;帳號&lt;/em&gt; ALL=(ALL) NOPASSWD: ALL</code></p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="642" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/1897d48c-image-1024x642.png?resize=1024%2C642&#038;ssl=1" alt="" class="wp-image-98" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/1897d48c-image.png?resize=1024%2C642&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/1897d48c-image.png?resize=300%2C188&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/1897d48c-image.png?resize=768%2C482&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/1897d48c-image.png?w=1427&amp;ssl=1 1427w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>將WSL環境執行的帳號加入sudoer，執行sudo指令的時候不需要輸入密碼</figcaption></figure>



<p>輸入完之後，同樣按下鍵盤的ctrl+x離開，詢問要不要儲存檔案的時候按y，接著再直接按enter離開就行了。</p>



<p>完成之後同樣離開WSL環境，並且將WSL終止(<code>wsl -t &lt;em&gt;WSL子系統Distro名稱&lt;/em&gt;</code>)，重新輸入wsl進入Linux子系統，可以看到下圖與上面的差異，需要輸入密碼的步驟已經省略掉了。</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="128" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/49f7c810-image-1024x128.png?resize=1024%2C128&#038;ssl=1" alt="" class="wp-image-99" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/49f7c810-image.png?resize=1024%2C128&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/49f7c810-image.png?resize=300%2C37&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/49f7c810-image.png?resize=768%2C96&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/49f7c810-image.png?resize=1536%2C192&amp;ssl=1 1536w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/49f7c810-image.png?w=1673&amp;ssl=1 1673w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>進入WSL環境並且啟動docker服務已經不需要再輸入密碼了</figcaption></figure>



<h3 class="wp-block-heading">參考來源</h3>



<ul class="wp-block-list"><li><a aria-label="undefined (opens in a new tab)" href="https://superuser.com/questions/1343558/hot-to-make-wsl-run-services-at-startup" target="_blank" rel="noreferrer noopener nofollow">How to make WSL run services at startup</a></li></ul>
<p>這篇文章 <a href="https://tech.uccu.website/auto-start-docker-service-when-wsl-start.html">WSL啟動時，自動啟動Docker服務</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tech.uccu.website/auto-start-docker-service-when-wsl-start.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">94</post-id>	</item>
		<item>
		<title>同一台電腦可執行Windows與Linux Container？在WSL2安裝原生Docker環境</title>
		<link>https://tech.uccu.website/how-to-install-docker-on-wsl2.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-install-docker-on-wsl2</link>
					<comments>https://tech.uccu.website/how-to-install-docker-on-wsl2.html#respond</comments>
		
		<dc:creator><![CDATA[鳴人]]></dc:creator>
		<pubDate>Thu, 10 Sep 2020 09:10:50 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[wsl]]></category>
		<guid isPermaLink="false">https://tech.uccu.website/?p=70</guid>

					<description><![CDATA[<p>如果想要在同一台電腦中既可以執行Windows Container，又可以執行Linux Container， ... <a title="同一台電腦可執行Windows與Linux Container？在WSL2安裝原生Docker環境" class="read-more" href="https://tech.uccu.website/how-to-install-docker-on-wsl2.html" aria-label="Read more about 同一台電腦可執行Windows與Linux Container？在WSL2安裝原生Docker環境">閱讀全文</a></p>
<p>這篇文章 <a href="https://tech.uccu.website/how-to-install-docker-on-wsl2.html">同一台電腦可執行Windows與Linux Container？在WSL2安裝原生Docker環境</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>如果想要在同一台電腦中既可以執行Windows Container，又可以執行Linux Container，以便測試程式在不同環境之下執行的結果或是設定值的差異，該如何達到這樣的需求呢？</p>



<p>答案就是：利用Windows中的Linux子系統(Windows Subsystem for Linux, WSL)。</p>



<p>透過WSL安裝Linux子系統之後，可以在Linux子系統中安裝原生的Docker執行環境，在Windows環境中則是安裝Docker Desktop並且切換到使用Windows Container，這樣一來就可以在Windows環境執行Windows Container，Linux子系統中執行Linux Container了。</p>



<p><em>註：WSL是Windows 10的功能，版本又分為Version 1(WSL)與Version 2(WSL2)，WSL2只能在Windows 10 2004版(組建19041以上)執行。(<a href="https://docs.microsoft.com/zh-tw/windows/wsl/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener nofollow">參考官方wsl文件說明</a>)</em></p>



<p>在開始之前，先輸入<code class="language-bash">wsl -l -v</code>查看一下系統內安裝的Linux子系統是執行在哪一個版本(1或2)。<br>在Linux子系統中要執行原生的Docker，只能在Version 2的版本(WSL2)。</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="657" height="229" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/3955add2-image.png?resize=657%2C229&#038;ssl=1" alt="" class="wp-image-71" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/3955add2-image.png?w=657&amp;ssl=1 657w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/3955add2-image.png?resize=300%2C105&amp;ssl=1 300w" sizes="auto, (max-width: 657px) 100vw, 657px" /><figcaption>使用<code>wsl -l -v</code>查看系統中 Linux子系統執行的版本</figcaption></figure>



<span id="more-70"></span>



<p>先輸入<code class="language-bash">docker info</code>確認系統中沒有安裝docker。</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="943" height="247" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/7f0c8bfc-image.png?resize=943%2C247&#038;ssl=1" alt="" class="wp-image-72" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/7f0c8bfc-image.png?w=943&amp;ssl=1 943w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/7f0c8bfc-image.png?resize=300%2C79&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/7f0c8bfc-image.png?resize=768%2C201&amp;ssl=1 768w" sizes="auto, (max-width: 943px) 100vw, 943px" /><figcaption>輸入<code>docker info</code>確認系統中確實沒有安裝docker</figcaption></figure>



<p>接著，根據官方的安裝指引將Docker Engine安裝到Linux子系統中：</p>



<ul class="wp-block-list"><li>Ubuntu：<a aria-label="undefined (opens in a new tab)" href="https://docs.docker.com/engine/install/ubuntu/" target="_blank" rel="noreferrer noopener nofollow">https://docs.docker.com/engine/install/ubuntu/</a></li><li>Debian：<a aria-label="undefined (opens in a new tab)" href="https://docs.docker.com/engine/install/debian/" target="_blank" rel="noreferrer noopener nofollow">https://docs.docker.com/engine/install/debian/</a></li><li>CentOS：<a aria-label="undefined (opens in a new tab)" href="https://docs.docker.com/engine/install/centos/" target="_blank" rel="noreferrer noopener nofollow">https://docs.docker.com/engine/install/centos/</a></li><li>Fedora：<a href="https://docs.docker.com/engine/install/fedora/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener nofollow">https://docs.docker.com/engine/install/fedora/</a></li></ul>



<h4 class="wp-block-heading">更新系統中的套件</h4>



<p>先輸入<code class="language-bash">sudo apt-get update</code>更新系統中的套件。</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="906" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/4afb5ecb-image-1024x906.png?resize=1024%2C906&#038;ssl=1" alt="" class="wp-image-73" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/4afb5ecb-image.png?resize=1024%2C906&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/4afb5ecb-image.png?resize=300%2C265&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/4afb5ecb-image.png?resize=768%2C680&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/4afb5ecb-image.png?w=1269&amp;ssl=1 1269w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>先輸入<code>sudo apt-get</code>更新系統中的套件</figcaption></figure>



<h4 class="wp-block-heading">安裝需要的套件</h4>



<p>再輸入下列指令安裝docker需要的其它套件：</p>



<pre class="wp-block-prismatic-blocks"><code class="language-bash">sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common</code></pre>



<p><em>註：「\」符號是Linux指令的換行連接符號，用來將較長的指令換行輸入，實際上在系統中仍然是組合成一整行的指令，因此也可以將上面的指令直接輸入成一行。(記得拿掉「\」符號)</em></p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="827" height="175" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/5ee778d6-image.png?resize=827%2C175&#038;ssl=1" alt="" class="wp-image-74" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/5ee778d6-image.png?w=827&amp;ssl=1 827w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/5ee778d6-image.png?resize=300%2C63&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/5ee778d6-image.png?resize=768%2C163&amp;ssl=1 768w" sizes="auto, (max-width: 827px) 100vw, 827px" /><figcaption>安裝docker前需要安裝的套件</figcaption></figure>



<p>安裝上述幾個套件的過程中會碰到詢問y/n的問題，通常是告知會使用多少磁碟空間，輸入y繼續安裝就行了。</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="749" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/6958cf39-image-1024x749.png?resize=1024%2C749&#038;ssl=1" alt="" class="wp-image-75" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/6958cf39-image.png?resize=1024%2C749&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/6958cf39-image.png?resize=300%2C220&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/6958cf39-image.png?resize=768%2C562&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/6958cf39-image.png?w=1499&amp;ssl=1 1499w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>安裝apt-transport-https、ca-certificates、curl、gnupg-agent、software-properties-common套件與其相依的套件</figcaption></figure>



<h4 class="wp-block-heading">取得GPG Key</h4>



<p>接下來取得docker的GPG key：</p>



<pre class="wp-block-prismatic-blocks"><code class="language-bash">curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -</code></pre>



<p><em>註：「|」符號是Linux中的命令管線符號，用來將前一個命令執行的結果送到下一個命令的輸入。</em></p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="39" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/88c5a78e-image-1024x39.png?resize=1024%2C39&#038;ssl=1" alt="" class="wp-image-76" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/88c5a78e-image.png?resize=1024%2C39&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/88c5a78e-image.png?resize=300%2C11&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/88c5a78e-image.png?resize=768%2C29&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/88c5a78e-image.png?w=1505&amp;ssl=1 1505w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>透過curl取得docker的GPG key</figcaption></figure>



<p>接下來<strong>這一步可以跳過</strong>，只是用來驗證剛才取得的GPG key是否正確。</p>



<pre class="wp-block-prismatic-blocks"><code class="language-bash">sudo apt-key fingerprint 0EBFCD88</code></pre>



<p>輸入完之後會看到下面<code>9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88</code>的內容。</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="947" height="145" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/eb1ab3ee-image.png?resize=947%2C145&#038;ssl=1" alt="" class="wp-image-77" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/eb1ab3ee-image.png?w=947&amp;ssl=1 947w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/eb1ab3ee-image.png?resize=300%2C46&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/eb1ab3ee-image.png?resize=768%2C118&amp;ssl=1 768w" sizes="auto, (max-width: 947px) 100vw, 947px" /><figcaption>驗證取得的GPG key</figcaption></figure>



<h4 class="wp-block-heading">加入套件存放庫(Repository)</h4>



<p>接下來將docker官方的套件存放庫(repository)加入到Linux子系統中，這樣才能夠安裝docker engine：</p>



<pre class="wp-block-prismatic-blocks"><code class="language-bash">sudo add-apt-repository \
&quot;deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable&quot;</code></pre>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="319" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/a5c90088-image-1024x319.png?resize=1024%2C319&#038;ssl=1" alt="" class="wp-image-80" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/a5c90088-image.png?resize=1024%2C319&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/a5c90088-image.png?resize=300%2C94&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/a5c90088-image.png?resize=768%2C240&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/a5c90088-image.png?w=1087&amp;ssl=1 1087w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>將docker的套件庫加入到系統中</figcaption></figure>



<p><em>小提示：如果你發現你的網址輸入錯誤．也就是在輸入指令之後下面的訊息有顯示Err的字樣，那麼可以編輯套件庫清單的設定檔，將錯誤的網址修正或移除重新加入。</em>(<a aria-label="undefined (opens in a new tab)" href="https://unix.stackexchange.com/questions/219341/how-to-apt-delete-repository" target="_blank" rel="noreferrer noopener nofollow">參考來源</a>)</p>



<pre class="wp-block-prismatic-blocks"><code class="language-bash">sudo nano /etc/apt/sources.list</code></pre>



<h4 class="wp-block-heading">安裝Docker Engine</h4>



<p>輸入下面兩行指令安裝Docker Engine，第一行是更新套件指令，第二行則是安裝Docker的指令</p>



<pre class="wp-block-prismatic-blocks"><code class="language-bash">sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io</code></pre>



<p>安裝過程中會有個磁碟空間耗用的問題，輸入y就能繼續。<br>接著會碰到下面的問題，是詢問grub-pc套件要裝在哪一個磁碟分割：</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="423" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/f688bcfe-image-1024x423.png?resize=1024%2C423&#038;ssl=1" alt="" class="wp-image-81" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/f688bcfe-image.png?resize=1024%2C423&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/f688bcfe-image.png?resize=300%2C124&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/f688bcfe-image.png?resize=768%2C317&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/f688bcfe-image.png?resize=1536%2C635&amp;ssl=1 1536w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/f688bcfe-image.png?w=1619&amp;ssl=1 1619w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>選擇grub-pc套件要安裝的目標</figcaption></figure>



<p>grub-pc應該是一個啟動管理的套件，不太確定是上面哪個套件相依的需求，以上圖來看，Linux子系統抓到三個(實際上只有sda、sdb兩個)容量大小相同的項目。<br>透過空白鍵可以選擇/取消，想知道sda、sdb分別是什麼的話，可以再另外開一個cmd或powershell視窗，輸入wsl透過另外一個terminal進入查看：</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="867" height="565" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/b287d344-image.png?resize=867%2C565&#038;ssl=1" alt="" class="wp-image-82" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/b287d344-image.png?w=867&amp;ssl=1 867w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/b287d344-image.png?resize=300%2C196&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/b287d344-image.png?resize=768%2C500&amp;ssl=1 768w" sizes="auto, (max-width: 867px) 100vw, 867px" /><figcaption>透過<code>df -h</code>、<code>lsblk</code>、<code>sudo blkid</code>指令查看磁碟資訊</figcaption></figure>



<p>從上面可以發現sda、sdb其實是一樣的，只是檔案系統實際上掛載在sdb項目，所以選擇sda、sdb也許都可以，不過實際上選擇第一個sda項目的時候，安裝到一半會出現下面的錯誤訊息：</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="299" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/71a5ac8f-image-1024x299.png?resize=1024%2C299&#038;ssl=1" alt="" class="wp-image-83" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/71a5ac8f-image.png?resize=1024%2C299&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/71a5ac8f-image.png?resize=300%2C88&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/71a5ac8f-image.png?resize=768%2C224&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/71a5ac8f-image.png?w=1223&amp;ssl=1 1223w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>無法安裝在sda</figcaption></figure>



<p>既然無法安裝在sda，那麼就不要霸王硬上弓硬是要安裝在sda，所以選擇No之後，回到上面的選單項目，將sda取消，選擇第二個sdb試試。<br>沒有再出現上面無法安裝詢問是否要霸王硬上弓的問題，順利安裝完成。</p>



<p>輸入<code>docker info</code>查看安裝的結果，只顯示client資訊，server資訊則是無法連線，其實這只是docker service沒有啟動的關係。</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="152" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/5682d84c-image-1024x152.png?resize=1024%2C152&#038;ssl=1" alt="" class="wp-image-84" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/5682d84c-image.png?resize=1024%2C152&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/5682d84c-image.png?resize=300%2C45&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/5682d84c-image.png?resize=768%2C114&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/5682d84c-image.png?w=1351&amp;ssl=1 1351w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>輸入<code>sudo service docker start</code>啟動docker服務，再次輸入<code>docker info</code>查看docker的資訊卻發現…</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="149" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/afb2eb9d-image-1024x149.png?resize=1024%2C149&#038;ssl=1" alt="" class="wp-image-85" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/afb2eb9d-image.png?resize=1024%2C149&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/afb2eb9d-image.png?resize=300%2C44&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/afb2eb9d-image.png?resize=768%2C112&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/afb2eb9d-image.png?resize=1536%2C224&amp;ssl=1 1536w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/afb2eb9d-image.png?w=1559&amp;ssl=1 1559w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>看起來和上面那張截圖滿像的，不過最後有個關鍵字是「permission denied」。<br>既然如此，那使用sudo執行看看呢？(<code>sudo docker info</code>)</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="868" height="1024" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/9cd58616-image-868x1024.png?resize=868%2C1024&#038;ssl=1" alt="" class="wp-image-87" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/9cd58616-image.png?resize=868%2C1024&amp;ssl=1 868w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/9cd58616-image.png?resize=254%2C300&amp;ssl=1 254w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/9cd58616-image.png?resize=768%2C906&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/9cd58616-image.png?w=1123&amp;ssl=1 1123w" sizes="auto, (max-width: 868px) 100vw, 868px" /></figure>



<p>Bingo，能夠正常查看到docker的資訊了！</p>



<p>不過這樣每次要執行docker相關的指令都要輸入sudo有點麻煩，所以接著可以利用下面的指令，將docker加入特定的用戶群：</p>



<pre class="wp-block-prismatic-blocks"><code class="language-bash">sudo usermod -aG docker 帳號</code></pre>



<p>輸入完上面的指令之後，如果直接再次輸入docker info想要試試是否有效，會得到令人失望的結果。主要是因為當下使用的terminal沒有登出再重新登入取得最新的資訊，只要退出terminal之後再重新執行就可以正常了。</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="669" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/28de246d-image-1024x669.png?resize=1024%2C669&#038;ssl=1" alt="" class="wp-image-88" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/28de246d-image.png?resize=1024%2C669&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/28de246d-image.png?resize=300%2C196&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/28de246d-image.png?resize=768%2C502&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/28de246d-image.png?resize=1536%2C1003&amp;ssl=1 1536w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/28de246d-image.png?w=1557&amp;ssl=1 1557w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>輸入完<code>sudo usermod -aG docker &lt;em&gt;帳號&lt;/em&gt;</code>，需要離開wsl再重新進入才會生效</figcaption></figure>



<p>OK，這下子終於將docker順利安裝在WSL2裡面啦~</p>



<p>從下面的截圖也可以發現，在wsl裡面查看docker info和windows底下查看docker info的差異，證明兩個docker環境是彼此分開獨立的喔！</p>



<p>PS.Windows環境安裝Docker Desktop並且切換到Windows Container模式了，這樣一來就可以在一台電腦中同時執行Linux Container與Windows Container了。</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="1024" height="787" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/d696fac4-image-1024x787.png?resize=1024%2C787&#038;ssl=1" alt="" class="wp-image-90" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/d696fac4-image.png?resize=1024%2C787&amp;ssl=1 1024w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/d696fac4-image.png?resize=300%2C230&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/d696fac4-image.png?resize=768%2C590&amp;ssl=1 768w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/d696fac4-image.png?resize=1536%2C1180&amp;ssl=1 1536w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/08/d696fac4-image.png?w=1725&amp;ssl=1 1725w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption>同一台電腦中同時執行Windows Docker與Linux Docker環境</figcaption></figure>
<p>這篇文章 <a href="https://tech.uccu.website/how-to-install-docker-on-wsl2.html">同一台電腦可執行Windows與Linux Container？在WSL2安裝原生Docker環境</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tech.uccu.website/how-to-install-docker-on-wsl2.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">70</post-id>	</item>
		<item>
		<title>Windows 10 Home家用版安裝Hyper-V與Docker</title>
		<link>https://tech.uccu.website/windows10-home-install-hyperv-docker.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=windows10-home-install-hyperv-docker</link>
					<comments>https://tech.uccu.website/windows10-home-install-hyperv-docker.html#respond</comments>
		
		<dc:creator><![CDATA[鳴人]]></dc:creator>
		<pubDate>Tue, 19 May 2020 08:05:08 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[hyper-v]]></category>
		<category><![CDATA[windows 10 home]]></category>
		<category><![CDATA[wsl]]></category>
		<guid isPermaLink="false">https://tech.uccu.website/?p=30</guid>

					<description><![CDATA[<p>公司一開始配的電腦是Acer的套裝電腦，裡面搭配的是Windows 10 Home版，作為一個開發者，Home ... <a title="Windows 10 Home家用版安裝Hyper-V與Docker" class="read-more" href="https://tech.uccu.website/windows10-home-install-hyperv-docker.html" aria-label="Read more about Windows 10 Home家用版安裝Hyper-V與Docker">閱讀全文</a></p>
<p>這篇文章 <a href="https://tech.uccu.website/windows10-home-install-hyperv-docker.html">Windows 10 Home家用版安裝Hyper-V與Docker</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>公司一開始配的電腦是Acer的套裝電腦，裡面搭配的是Windows 10 Home版，作為一個開發者，Home版本的功能實在是不太符合需求，因為預設應該是沒有Hyper-V功能，如果要安裝Docker的話，也只能安裝Client工具…</p>



<p>不太想要動到OS重灌這一招，想到之前似乎有試過(看到)在Windows 10 Home版安裝Hyper-V與WSL，不過因為很久沒有寫部落格記錄，有些問題解決之後就沒有記錄，所以趁著這次解決這個問題並且將部落格從幾次亂搞之後最近放到Google Cloud Run上面執行，一併將這些操作記錄下來。</p>



<span id="more-30"></span>



<p class="has-text-align-left">首先，Windows 10 Home版打開控制台「程式和功能」中的「Windows 功能」應該不會有「Hyper-V平台」、「適用於 Linux 的 Windows 子系統」兩個選項。</p>



<p class="has-text-align-center"><img data-recalc-dims="1" loading="lazy" decoding="async" width="600" height="400" class="wp-image-33" style="width: 600px;" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/05/b94afa4b-windows10-home-windows-features.png?resize=600%2C400&#038;ssl=1" alt="Windows 10 Home家用版Windows功能" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/05/b94afa4b-windows10-home-windows-features.png?w=731&amp;ssl=1 731w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/05/b94afa4b-windows10-home-windows-features.png?resize=300%2C200&amp;ssl=1 300w" sizes="auto, (max-width: 600px) 100vw, 600px" /></p>



<p>從<a href="https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/hyper-v-requirements">Windows 10 Hyper-V System Requirements</a>的頁面說明中也有下面這段，明確表明Windows 10 Home的版本不能安裝。</p>



<p>The Hyper-V role&nbsp;<strong>cannot</strong>&nbsp;be installed on:</p>



<ul class="wp-block-list"><li>Windows 10 Home</li><li>Windows 10 Mobile</li><li>Windows 10 Mobile Enterprise</li></ul>



<p>不過這個其實有秘技可以讓Hyper-V安裝在Windows 10 Home，只需要將下面這段指令貼在記事本上，並且以.bat的副檔名儲存後透過管理員權限執行即可。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>pushd &#8220;%~dp0&#8221;<br>dir /b %SystemRoot%\servicing\Packages*Hyper-V*.mum &gt;hyper-v.txt<br>for /f %%i in (&#8216;findstr /i . hyper-v.txt 2^&gt;nul&#8217;) do dism /online /norestart /add-package:&#8221;%SystemRoot%\servicing\Packages\%%i&#8221;<br>del hyper-v.txt<br>Dism /online /enable-feature /featurename:Microsoft-Hyper-V -All /LimitAccess /ALL<br>pause</p></blockquote>



<p>如果也想要安裝Container功能的話，同樣將下面這段指令以.bat儲存後透過管理員權限執行。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>pushd &#8220;%~dp0&#8221;<br>dir /b %SystemRoot%\servicing\Packages*containers*.mum &gt;containers.txt<br>for /f %%i in (&#8216;findstr /i . containers.txt 2^&gt;nul&#8217;) do dism /online /norestart /add-package:&#8221;%SystemRoot%\servicing\Packages\%%i&#8221;<br>del containers.txt<br>Dism /online /enable-feature /featurename:Containers -All /LimitAccess /ALL<br>pause</p></blockquote>



<p>執行完之後重新開機應該就可以找到Hyper-V的功能了，不過到這裡為止，仍然無法安裝Docker。<br>或者是說，如果不是<a href="https://docs.docker.com/docker-for-windows/install-windows-home/">Windows 10 Home搭配Docker使用WSL2(Windows Subsystem for Linux, WSL)</a>，那麼就無法使用Docker。</p>



<p>再更精確一點的說法，就是<a href="https://docs.docker.com/docker-for-windows/install/">Docker需要Hyper-V與Container的功能</a>，如果是Windows Home安裝WSL2再加上Docker，那麼就是在WSL2裡面執行Container，跑的是Linux，如果只需要執行Linux的Container是OK的。</p>



<p>不過若是需要在Windows Container和Linux Container之間切換的話，Windows 10 Home版本一般來說是無法達成，而且Docker搭配WSL2跑Linux Container若是使用到Docker-Compose的話，可能還會有一點點問題…</p>



<p>所以為了在Windows 10 Home的版本正常執行Docker(Hyper-V都透過秘技安裝了，應該還有秘技可以讓Docker正常在Windows 10 Home版本安裝與執行吧！)，所以我繼續在網路上搜尋可能的秘技，想要解決在Windows 10 Home版本使用Docker的問題。</p>



<p>這次的秘技不需要再執行指令安裝什麼東西，需要的是執行regedit編輯Windows登錄檔，透過將「HKLM\Software\Microsoft\Windows NT\CurrentVersion」底下的EditionID從「Core」更改為「Professional」，改完之後不需要重新開機，就可以執行最新版本的Docker安裝檔。</p>



<figure class="wp-block-image size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="963" height="680" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/05/7f9b43ce-changewindowseditionid_windowsregistry.png?resize=963%2C680&#038;ssl=1" alt="" class="wp-image-34" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/05/7f9b43ce-changewindowseditionid_windowsregistry.png?w=963&amp;ssl=1 963w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/05/7f9b43ce-changewindowseditionid_windowsregistry.png?resize=300%2C212&amp;ssl=1 300w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/05/7f9b43ce-changewindowseditionid_windowsregistry.png?resize=768%2C542&amp;ssl=1 768w" sizes="auto, (max-width: 963px) 100vw, 963px" /><figcaption>將EditionID從「Core」更改為「Professional」，改完之後不需要重新開機，就可以執行最新版本的Docker安裝檔</figcaption></figure>



<p>上面的這個修改Windows登錄檔的位置要記下來，或者是寫成一個指令檔。<br>因為Windows過一段時間(不知多久)會自己將更改的值改回「Core」(如果你改完忘了改回來)，尤其是Windows Update完之後。</p>



<p>這會有什麼影響呢？</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-recalc-dims="1" loading="lazy" decoding="async" width="336" height="351" src="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/05/cdf1ffcb-dockerswitchcontainerneedtochangewindowsregistry.png?resize=336%2C351&#038;ssl=1" alt="" class="wp-image-35" srcset="https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/05/cdf1ffcb-dockerswitchcontainerneedtochangewindowsregistry.png?w=336&amp;ssl=1 336w, https://i0.wp.com/storage.googleapis.com/stateless-tech-uccu-website/2020/05/cdf1ffcb-dockerswitchcontainerneedtochangewindowsregistry.png?resize=287%2C300&amp;ssl=1 287w" sizes="auto, (max-width: 336px) 100vw, 336px" /><figcaption>EditionID為「Core」的情況下無法切換Container</figcaption></figure></div>



<p>會影響的就是Docker切換Windows Container與更新Docker版本，如果Docker發現新的版本，但是當你要執行更新安裝的時候發現有問題，可以試著將EditionID再改為「Professional」，之後應該就可以更新了。<br>註：要透過Docker結合WSL2執行Linux Container必須是切換到Linux Container模式才行。<br>(不過也可以選擇不要在Windows下操作Docker跑Linux Container，直接在WSL2裡面安裝獨立的Docker)參考來源：</p>



<p><span>參考來源</span></p>



<ul class="wp-block-list"><li><a href="https://forums.docker.com/t/installing-docker-on-windows-10-home/11722">Installing Docker on Windows 10 Home</a></li></ul>
<p>這篇文章 <a href="https://tech.uccu.website/windows10-home-install-hyperv-docker.html">Windows 10 Home家用版安裝Hyper-V與Docker</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tech.uccu.website/windows10-home-install-hyperv-docker.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">30</post-id>	</item>
	</channel>
</rss>
