

<?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>azure &#8211; Max的程式語言筆記</title>
	<atom:link href="https://stackoverflow.max-everyday.com/tag/azure/feed/" rel="self" type="application/rss+xml" />
	<link>https://stackoverflow.max-everyday.com</link>
	<description>我要當一個豬頭，快樂過每一天</description>
	<lastBuildDate>Wed, 15 Apr 2026 10:18:08 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://stackoverflow.max-everyday.com/wp-content/uploads/2017/02/max-stackoverflow-256.png</url>
	<title>azure &#8211; Max的程式語言筆記</title>
	<link>https://stackoverflow.max-everyday.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Azure Container Apps (ACA) 存取 VNet 內的資源</title>
		<link>https://stackoverflow.max-everyday.com/2026/04/azure-container-apps-vnet/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/04/azure-container-apps-vnet/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Wed, 15 Apr 2026 10:01:45 +0000</pubDate>
				<category><![CDATA[Azure 筆記]]></category>
		<category><![CDATA[電腦相關應用]]></category>
		<category><![CDATA[azure]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=8293</guid>

					<description><![CDATA[既然你已經從 Web App 遷移到 Azure...]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="559" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/azure-container-apps-vnet_clean-1024x559.jpg?v=1776247294" alt="" class="wp-image-8295" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/azure-container-apps-vnet_clean-1024x559.jpg?v=1776247294 1024w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/azure-container-apps-vnet_clean-600x327.jpg?v=1776247294 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/azure-container-apps-vnet_clean-768x419.jpg?v=1776247294 768w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/azure-container-apps-vnet_clean.jpg?v=1776247294 1408w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>既然你已經從 Web App 遷移到 <strong>Azure Container Apps (ACA)</strong>，網路架構的邏輯會稍微有些不同。ACA 本身就是建立在一個名為 <strong>Container Apps Environment</strong> 的容器環境中，因此 VNet 的整合是在「環境 (Environment)」層級設定的，而不是單獨在特定的 App 上。</p>



<p>存取 VNet 資源的流程主要分為：<strong>環境網路配置</strong>、<strong>基礎架構委派</strong>、以及 <strong>ACA 部署</strong>。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">1. 核心觀念：VNet 整合模式</h3>



<p>ACA 支援兩種網路模式：</p>



<ul class="wp-block-list">
<li><strong>External (外部)</strong>：環境有公網 IP，但後端可以存取 VNet 資源。</li>



<li><strong>Internal (內部)</strong>：環境沒有公網 IP，所有存取都必須透過 VNet（適合純內網系統）。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2. 實作流程與 CLI 指令</h3>



<h4 class="wp-block-heading">第一步：建立（或準備）Subnet 並設定委派</h4>



<p>與 Web App 相似，ACA 的 Subnet 也需要特定的委派，但它是委派給 <code>Microsoft.App/environments</code>。</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code># 定義變數 (假設 VNet 在不同的 RG)
$VNET_RG = "rg-network-shared"
$VNET_NAME = "vnet-pr-stg-twn-01"
$ACA_SUBNET_NAME = "snet-aca-integration" # 建議建立一個新的 Subnet

# 更新 Subnet 委派
az network vnet subnet update `
  --resource-group $VNET_RG `
  --vnet-name $VNET_NAME `
  --name $ACA_SUBNET_NAME `
  --delegations Microsoft.App/environments
</code></pre>



<h4 class="wp-block-heading">第二步：取得 Subnet ID</h4>



<p>跨 RG 操作時，直接拿 ID 最安全：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code>$SUBNET_ID = $(az network vnet subnet show `
  --resource-group $VNET_RG `
  --vnet-name $VNET_NAME `
  --name $ACA_SUBNET_NAME `
  --query id -o tsv)
</code></pre>



<h4 class="wp-block-heading">第三步：建立 Container Apps Environment 並綁定 VNet</h4>



<p>這是關鍵步驟。一旦 Environment 建立並綁定 VNet，該環境下所有的 Container Apps 都能直接存取該 VNet 內的資源。</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code>$ENVIRONMENT_NAME = "cae-pr-stg-twn-001"

az containerapp env create `
  --name $ENVIRONMENT_NAME `
  --resource-group $RESOURCE_GROUP `
  --location "taiwannorth" `
  --infrastructure-subnet-id $SUBNET_ID `
  --internal-client-ip-dns-mode "None"  # 如果需要外部存取設為 None，純內網設為 Internal
</code></pre>



<h4 class="wp-block-heading">第四步：部署 Container App 到該環境</h4>



<p>PowerShell</p>



<pre class="wp-block-code"><code>az containerapp create `
  --name "my-fast-app" `
  --resource-group $RESOURCE_GROUP `
  --environment $ENVIRONMENT_NAME `
  --image "${ACR_NAME}.azurecr.io/policy-app:v1" `
  --registry-server "${ACR_NAME}.azurecr.io" `
  --target-port 80 `
  --ingress 'external' # 允許外部流量進來
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3. 如何存取 VNet 內的資源？</h3>



<p>部署完成後，你的 Container App 就像是在 VNet 內的一台機器：</p>



<ul class="wp-block-list">
<li><strong>透過 IP 存取</strong>：你可以直接 ping 或連線 VNet 內 VM 的私有 IP。</li>



<li><strong>透過 DNS 存取</strong>：如果你 VNet 內有設定 <strong>Azure Private DNS Zones</strong>，你需要確保 ACA 環境關聯了該 Private DNS，這樣才能解析例如 <code>mydb.privatelink.database.azure.com</code> 這樣的域名。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4. 權限鬼打牆預警 (RBAC)</h3>



<p>因為你跨了 Resource Group，且不是 Owner：</p>



<ol start="1" class="wp-block-list">
<li><strong>Network Contributor</strong>：你的帳號必須在 <code>VNet RG</code> 擁有這個角色，否則無法將 ACA 環境掛載到該 Subnet。</li>



<li><strong>Managed Identity</strong>：如果你的 ACA 需要存取 Key Vault 或 SQL (存取權限控管)，建議幫 ACA 開啟 <code>System Assigned Identity</code>。</li>
</ol>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 總結</h3>



<p>ACA 的優勢在於<strong>一次設定，全家享用</strong>。只要把 <code>Environment</code> 塞進 VNet，之後在裡面建立的幾十個微服務就通通都能連內網了。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>寫一段建立新 Subnet 的指令</strong></p>



<p>既然要為 <strong>Azure Container Apps (ACA)</strong> 建立新的 Subnet，我們必須確保該 Subnet 的位址空間不與現有的資源衝突，並且正確設定 <strong>委派 (Delegation)</strong>。</p>



<p>在跨 Resource Group 的情境下，請執行以下 PowerShell 指令：</p>



<h3 class="wp-block-heading">1. 定義變數</h3>



<p>請根據你的實際環境修改位址範圍（例如 <code>10.0.2.0/24</code>）：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code>$VNET_RG = "rg-network-shared"         # VNet 所在的 RG
$VNET_NAME = "vnet-pr-stg-twn-01"       # 現有的 VNet 名稱
$NEW_SUBNET_NAME = "snet-aca-infra-01"  # 新 Subnet 的名字
$ADDRESS_PREFIX = "10.0.2.0/24"         # 確保此範圍在 VNet 內且未被使用
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2. 建立 Subnet 並設定委派</h3>



<p>我們使用 <code>az network vnet subnet create</code> 指令。關鍵在於 <code>--delegations</code>，這會告訴 Azure：「這個網段是給 ACA 環境專用的」。</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code>az network vnet subnet create `
  --resource-group $VNET_RG `
  --vnet-name $VNET_NAME `
  --name $NEW_SUBNET_NAME `
  --address-prefixes $ADDRESS_PREFIX `
  --delegations "Microsoft.App/environments"
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3. 取得新 Subnet 的 ID (供後續建立 ACA 環境使用)</h3>



<p>建立完成後，建議直接把 ID 存起來，這樣在建立 ACA Environment 時才不會因為名稱解析問題而「鬼打牆」：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code>$ACA_SUBNET_ID = $(az network vnet subnet show `
  --resource-group $VNET_RG `
  --vnet-name $VNET_NAME `
  --name $NEW_SUBNET_NAME `
  --query id -o tsv)

# 驗證一下有沒有抓到
echo $ACA_SUBNET_ID
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 執行前的注意事項 (避免再次鬼打牆)</h3>



<ul class="wp-block-list">
<li><strong>位址衝突</strong>：請先確認 <code>$ADDRESS_PREFIX</code> 沒有被 VNet 內其他的 Subnet 佔用。你可以執行 <code>az network vnet show -g $VNET_RG -n $VNET_NAME --query "subnets[].addressPrefix"</code> 來查看已使用的網段。</li>



<li><strong>Subnet 大小</strong>：ACA 規定最小必須是 <strong>/23</strong> (512 個 IP) 或 <strong>/27</strong> (32 個 IP)，具體取決於你的工作負載。對於測試環境，建議至少使用 <strong><code>/24</code></strong> 或 <strong><code>/23</code></strong>，因為 ACA 在升級（Rolling update）或擴展時會消耗大量 IP。</li>



<li><strong>權限</strong>：雖然你不是 Owner，但只要你在 <code>$VNET_RG</code> 擁有 <strong>Network Contributor</strong> 角色，就可以成功執行這段指令。</li>
</ul>



<p>下一步你就可以拿著 <code>$ACA_SUBNET_ID</code> 去執行 <code>az containerapp env create</code> 了。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>準備建立環境的完整指令</p>



<p>沒問題！我們直接把 <strong>建立 Subnet</strong> 到 <strong>建立 ACA 環境</strong> 的完整流程串起來。這組指令會確保你的 Container Apps 基礎設施能夠正確與 VNet 銜接。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">第一階段：建立 Subnet (跨 RG)</h3>



<p>請確保你已經定義了之前討論的變數（<code>$VNET_RG</code>, <code>$VNET_NAME</code> 等）。</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code># 1. 在指定的 VNet RG 下建立專屬 Subnet
az network vnet subnet create `
  --resource-group $VNET_RG `
  --vnet-name $VNET_NAME `
  --name $NEW_SUBNET_NAME `
  --address-prefixes $ADDRESS_PREFIX `
  --delegations "Microsoft.App/environments"

# 2. 獲取該 Subnet 的 Resource ID (這是建立環境的必要參數)
$ACA_SUBNET_ID = $(az network vnet subnet show `
  --resource-group $VNET_RG `
  --vnet-name $VNET_NAME `
  --name $NEW_SUBNET_NAME `
  --query id -o tsv)
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">第二階段：建立 ACA 環境 (Managed Environment)</h3>



<p>這是 ACA 的核心，「環境」決定了容器的網路邊界。</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code># 定義環境名稱
$ENVIRONMENT_NAME = "cae-pr-stg-twn-001"

# 建立環境並掛載到 VNet ID
az containerapp env create `
  --name $ENVIRONMENT_NAME `
  --resource-group $RESOURCE_GROUP `
  --location "taiwannorth" `
  --infrastructure-subnet-id $ACA_SUBNET_ID `
  --internal-client-ip-dns-mode "None"
</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 專業提示：</strong></p>



<ul class="wp-block-list">
<li><code>--internal-client-ip-dns-mode "None"</code>：這代表你的 ACA 會有一個公用 IP (External)。如果你希望這是一個<strong>純內網</strong>（外面完全連不到）的環境，請將此參數改為 <code>Internal</code>。</li>
</ul>
</blockquote>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">第三階段：部署第一個 Container App</h3>



<p>現在環境已經在 VNet 裡了，我們把你的 App 丟進去測試連通性。</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code>az containerapp create `
  --name "app-pr-stg-twn" `
  --resource-group $RESOURCE_GROUP `
  --environment $ENVIRONMENT_NAME `
  --image "${ACR_NAME}.azurecr.io/policy-app:v1" `
  --registry-server "${ACR_NAME}.azurecr.io" `
  --registry-username $ACR_USERNAME `
  --registry-password $ACR_PASSWORD `
  --target-port 80 `
  --ingress 'external' `
  --query "properties.configuration.ingress.fqdn"
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">網路架構圖解</h3>



<p>這套設定完成後，你的網路架構會長這樣：</p>



<h3 class="wp-block-heading">驗證 VNet 連通性</h3>



<p>部署成功後，你可以進入 ACA 的「主控台 (Console)」或是透過 <code>az containerapp exec</code> 嘗試 ping VNet 內的資源（例如資料庫的 Private IP）：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code># 進入容器內部測試
az containerapp exec --name "app-pr-stg-twn" --resource-group $RESOURCE_GROUP --command "ping 10.0.1.5"
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6d1.png" alt="🛑" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 避坑指南：關於「位置 (Location)」</h3>



<p>ACA 與 VNet 整合時，<strong>Region 必須完全一致</strong>。</p>



<ul class="wp-block-list">
<li>如果 VNet 在 <code>Japan East</code>，指令中的 <code>--location</code> 必須填 <code>japaneast</code>。</li>



<li>如果 VNet 在 <code>Taiwan North</code>，則填 <code>taiwannorth</code>。</li>
</ul>



<p>如果跨區建立，<code>az containerapp env create</code> 會報錯並告訴你 Subnet 不在該區域。</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/04/azure-container-apps-vnet/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Web App 存取 VNet 內的資源</title>
		<link>https://stackoverflow.max-everyday.com/2026/04/web-app-vnet/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/04/web-app-vnet/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Wed, 15 Apr 2026 09:22:11 +0000</pubDate>
				<category><![CDATA[Azure 筆記]]></category>
		<category><![CDATA[azure]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=8283</guid>

					<description><![CDATA[在 Azure 中，這項功能稱為 「輸出 VNe...]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="559" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/web-app-vnet_clean-1024x559.jpg?v=1776247613" alt="" class="wp-image-8298" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/web-app-vnet_clean-1024x559.jpg?v=1776247613 1024w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/web-app-vnet_clean-600x327.jpg?v=1776247613 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/web-app-vnet_clean-768x419.jpg?v=1776247613 768w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/web-app-vnet_clean.jpg?v=1776247613 1408w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>在 Azure 中，這項功能稱為 <strong>「輸出 VNet 整合」(Outbound VNet Integration)</strong>。它能讓你的 Web App 存取 VNet 內的資源（例如私有的資料庫或 VM），而不需要經過公網。</p>



<p>不過，要成功將 Web App 加入 VNet，你需要注意以下幾個關鍵點：</p>



<h3 class="wp-block-heading">1. 方案等級限制 (App Service Plan SKU)</h3>



<p>並非所有的 Web App 都能加入 VNet。你的 App Service Plan 必須是以下等級之一：</p>



<ul class="wp-block-list">
<li><strong>Basic</strong> (僅限較新的版本)</li>



<li><strong>Standard</strong></li>



<li><strong>Premium</strong> (v2 或 v3)</li>



<li><strong>Functions Premium</strong></li>
</ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>如果你是 <strong>Free</strong> 或 <strong>Shared</strong> 等級，則不支援 VNet 整合。</p>
</blockquote>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2. 子網段 (Subnet) 的特殊要求</h3>



<p>Web App 加入 VNet 不是隨便找個 Subnet 塞進去就好，它有「潔癖」：</p>



<ul class="wp-block-list">
<li><strong>必須是空的</strong>：該 Subnet 不能有其他資源（如 VM 或資料庫）。</li>



<li><strong>必須委派 (Delegation)</strong>：該 Subnet 必須專門「委派」給 <code>Microsoft.Web/serverFarms</code> 使用。</li>



<li><strong>足夠的 IP</strong>：建議至少保留 <code>/28</code> 位址空間（16 個 IP），因為 Web App 擴展時會消耗 IP。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3. 如何執行？(PowerShell 指令)</h3>



<p>既然你已經定義了變數，以下是將 Web App 整合進 VNet 的標準流程：</p>



<h4 class="wp-block-heading">A. 先幫 Subnet 設定委派 (如果還沒設定)</h4>



<p>PowerShell</p>



<pre class="wp-block-code"><code># 取得現有的 VNet 物件並設定 Subnet 委派
$vnet = Get-AzVirtualNetwork -Name $VNET_NAME -ResourceGroupName $RESOURCE_GROUP
$subnet = $vnet.Subnets | Where-Object { $_.Name -eq $SUBNET_NAME }

# 執行委派 (Delegation)
az network vnet subnet update `
  --resource-group $RESOURCE_GROUP `
  --vnet-name $VNET_NAME `
  --name $SUBNET_NAME `
  --delegations Microsoft.Web/serverFarms
</code></pre>



<h4 class="wp-block-heading">B. 執行 VNet 整合</h4>



<p>PowerShell</p>



<pre class="wp-block-code"><code>az webapp vnet-integration add `
  --resource-group $RESOURCE_GROUP `
  --name $WEB_APP_NAME `
  --vnet $VNET_NAME `
  --subnet $SUBNET_NAME
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4. 常見的坑（鬼打牆預警）</h3>



<ul class="wp-block-list">
<li><strong>區域限制 (Region)</strong>：Web App 和 VNet 最好在同一個 Region（你的變數看起來都是 <code>jpe</code> 日本東部，這沒問題）。</li>



<li><strong>路由問題</strong>：預設情況下，只有往 VNet 私有位址的流量會走 VNet。如果你希望連「上網」的流量都強迫走 VNet（例如要過防火牆），你需要開啟 <code>Route All</code> 設定。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>我目前的 RG 可以加入其他 RG 的 vnet </p>



<p>在 Azure 中，資源的「實體連線」<strong>（VNet 整合）與</strong>「邏輯分類」（Resource Group, RG）是解耦的。只要你的帳號在兩個 Resource Group 都擁有足夠的權限（通常是 <strong>Contributor</strong> 或 <strong>Network Contributor</strong>），就能跨組進行整合。</p>



<p>以下是跨 RG 加入 VNet 的操作要點與指令：</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">1. 核心邏輯：使用「資源 ID」</h3>



<p>當 VNet 在另一個 RG 時，單純傳入 VNet 名稱 <code>$VNET_NAME</code> 可能會讓 CLI 找不到對象。最穩健的做法是使用 <strong>完整資源 ID (Resource ID)</strong>。</p>



<h3 class="wp-block-heading">2. 指令實作</h3>



<p>首先，定義 VNet 所在的 RG 名稱（假設叫 <code>rg-network-shared</code>）：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code># 設定 VNet 所在的資源群組
$VNET_RG = "rg-network-shared" # 請換成你 VNet 實際所在的 RG 名稱

# 1. 取得 VNet 的子網段資源 ID (最保險的做法)
$SUBNET_ID = "/subscriptions/你的訂閱ID/resourceGroups/$VNET_RG/providers/Microsoft.Network/virtualNetworks/$VNET_NAME/subnets/$SUBNET_NAME"

# 2. 執行 VNet 整合
az webapp vnet-integration add `
  --name $WEB_APP_NAME `
  --resource-group $RESOURCE_GROUP `
  --vnet $VNET_NAME `
  --subnet $SUBNET_NAME `
  --subscription "你的訂閱ID" # 如果跨訂閱才需要，同訂閱可省略
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3. 關鍵權限檢查（鬼打牆預防）</h3>



<p>由於你提到你「目前不是 Owner」，跨 RG 操作最常卡在 <strong>RBAC 權限</strong>：</p>



<ul class="wp-block-list">
<li><strong>你的 RG ($RESOURCE_GROUP)</strong>：你需要有權限修改 Web App（Contributor）。</li>



<li><strong>VNet 的 RG ($VNET_RG)</strong>：你必須至少擁有該 Subnet 的 <strong>「Microsoft.Network/virtualNetworks/subnets/join/action」</strong> 權限。<br><strong>白話文</strong>：如果你在 VNet 那邊連讀取權都沒有，這條路會斷掉。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4. 區域 (Region) 依然是死穴</h3>



<p>雖然 RG 可以跨，但 <strong>Region 幾乎不能跨</strong>（除非使用特定進階功能）：</p>



<ul class="wp-block-list">
<li>你的 Web App 在 <code>Japan East</code>，VNet 也必須在 <code>Japan East</code>。</li>



<li>如果 Web App 在 <code>Taiwan North</code>，VNet 也必須在 <code>Taiwan North</code>。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">5. 總結流程圖</h3>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 建議操作步驟</h3>



<ol start="1" class="wp-block-list">
<li><strong>確認區域</strong>：先用 <code>az network vnet show --name $VNET_NAME -g $VNET_RG --query location</code> 確認 VNet 的位置。</li>



<li><strong>設定委派</strong>：確保該 Subnet 已經委派給 <code>Microsoft.Web/serverFarms</code>。</li>



<li><strong>執行整合</strong>：使用上面的 <code>az webapp vnet-integration add</code> 指令。</li>
</ol>



<p></p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/04/web-app-vnet/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Azure Container Apps vs Web Apps</title>
		<link>https://stackoverflow.max-everyday.com/2026/04/azure-container-apps-vs-web-apps/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/04/azure-container-apps-vs-web-apps/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Wed, 15 Apr 2026 09:14:52 +0000</pubDate>
				<category><![CDATA[Azure 筆記]]></category>
		<category><![CDATA[azure]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=8288</guid>

					<description><![CDATA[在 Azure 的生態系中，Container ...]]></description>
										<content:encoded><![CDATA[
<p>在 Azure 的生態系中，Container Apps (ACA) 和 Web App (主要指 App Service for Containers) 雖然都能執行容器化應用，但其底層邏輯與適用情境有明顯差異。</p>



<h3 class="wp-block-heading">核心定位與架構</h3>



<p><strong>Web App (App Service)</strong> 是成熟的 PaaS (平台即服務)，最初是為了託管網頁程式設計的。它將底層基礎設施封裝得非常完整，你只需要專注於程式碼或單個容器。它強調的是穩定性、整合性以及對傳統 Web 模式的支援。</p>



<p><strong>Container Apps (ACA)</strong> 則是建構在 Kubernetes (AKS) 之上的 Serverless 平台。它幫你隱藏了 K8s 的複雜性，但保留了微服務架構的靈活性。它適合由多個組件構成的系統，且具備更強的事件驅動擴展能力。</p>



<p>Kubernetes是用於自動部署、擴充和管理「容器化應用程式」的開源系統。Kubernetes 是在提供「跨主機叢集的自動部署、擴充以及執行應用程式容器的平台」。</p>



<h3 class="wp-block-heading">主要差異分析</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><td><strong>特性</strong></td><td><strong>Web App (App Service)</strong></td><td><strong>Container Apps (ACA)</strong></td></tr></thead><tbody><tr><td><strong>設計目標</strong></td><td>單體應用 (Monolith) 或單一 Web API</td><td>微服務架構 (Microservices)</td></tr><tr><td><strong>自動擴展</strong></td><td>基於 CPU/記憶體負載，速度較慢</td><td>基於 KEDA (事件驅動)，可從 0 擴展至 N</td></tr><tr><td><strong>計費模式</strong></td><td>預留實例 (按 App Service Plan 規格固定計費)</td><td>消耗制 (按實際執行的資源秒數計費)</td></tr><tr><td><strong>併發處理</strong></td><td>適合長連接、持續性流量</td><td>適合突發流量、背景作業、排程工作</td></tr><tr><td><strong>微服務特性</strong></td><td>較弱，通常需手動串接各個 App</td><td>內建 Dapr 與 Envoy，支援服務發現與流量切分</td></tr><tr><td><strong>複雜度</strong></td><td>極低，傳統開發者上手最快</td><td>中等，需了解容器與微服務基本概念</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">如何選擇</h3>



<p><strong>選擇 Web App 的時機：</strong></p>



<ul class="wp-block-list">
<li>你只需要執行一個單獨的 Web 網站或 API 伺服器。</li>



<li>你的應用流量相對穩定，不希望遇到 Serverless 的冷啟動問題。</li>



<li>你需要完整的 Windows 容器支援或特定的 IIS 整合。</li>



<li>你偏好預測每個月固定的帳單預算。</li>
</ul>



<p><strong>選擇 Container Apps 的時機：</strong></p>



<ul class="wp-block-list">
<li>你的系統是由多個互相溝通的微服務組成。</li>



<li>流量波動很大，甚至在沒人使用時希望縮減到零以節省成本。</li>



<li>你需要處理非 HTTP 的事件驅動任務（例如從 Queue 讀取訊息後處理）。</li>



<li>你想享有類 Kubernetes 的功能（如 Sidecar 模式），但不想管理整個 K8s 叢集。</li>
</ul>



<p>簡單來說，如果你做的是「一個網站」，選 Web App；如果你做的是「一套分散式系統」，選 Container Apps 會更合適。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Web App 可以有前端/後端機制?</p>



<p>在 Web App (App Service) 的架構中，確實可以實現前端與後端的機制，但具體的做法會根據你的專案規模與部署策略而有所不同。</p>



<h3 class="wp-block-heading">單一 Web App 模式 (Monolith)</h3>



<p>這是最傳統的做法，將前端網頁 (HTML/CSS/JS 或 React/Vue 編譯後的靜態檔案) 與後端程式 (Node.js, Python, Java, .NET) 打包在一起。當使用者存取網址時，同一個服務會負責處理 API 請求並回傳網頁內容。</p>



<p>這種方式的優點是管理簡單，只需要維護一個 App Service Plan 與一份部署流水線。缺點是當前端流量大增時，後端資源也會跟著被佔用，無法獨立擴展。</p>



<h3 class="wp-block-heading">前後端分離模式 (Decoupled)</h3>



<p>在 Azure 上更推薦的做法是將前端與後端拆分成兩個獨立的服務。</p>



<p>後端會部署在一個 Web App 中，專門處理 API 請求與資料庫互動。前端則有兩個選擇：第一是部署在另一個 Web App，第二則是使用 Azure Static Web Apps。</p>



<p>Azure Static Web Apps 是專門為 SPA (單頁式應用程式) 設計的服務，它將靜態檔案部署在全網域的邊緣節點，讀取速度更快，且成本通常比運行一個完整的 Web App 低很多。後端 Web App 則只需要開啟 CORS (跨來源資源共用) 設定，允許前端網址存取即可。</p>



<h3 class="wp-block-heading">VNet 整合與安全性</h3>



<p>如果你希望後端 API 不要暴露在網路上，只允許前端存取，可以透過虛擬網路 (VNet) 的機制。</p>



<p>你可以將後端 Web App 設定為僅接受來自前端服務的內部流量。這樣前端作為對外門戶，後端則隱藏在內網中，能有效提升系統的安全性。對於高中生理解來說，這就像是前端是餐廳的櫃檯，負責面對客人；後端是廚房，客人不能直接進去，只能透過櫃檯傳遞需求。</p>



<h3 class="wp-block-heading">選擇建議</h3>



<p>如果是小型專案或練習作品，採用單一 Web App 模式最省事。如果是正式的產品開發，建議將前端放在 Static Web Apps，後端放在 Web App，這樣不僅效能較好，開發時前後端團隊也可以各自獨立更新，互不干擾。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Container Apps 只能使用 Azure App Configuration, 無法使用 appsettings?</p>



<p>這是一個常見的誤解。事實上，Azure Container Apps (ACA) 當然可以使用 <code>appsettings.json</code>。</p>



<p>Container Apps 本質上就是執行你的容器映像檔。只要你的程式碼（例如 .NET）邏輯裡有讀取 <code>appsettings.json</code>，它在雲端執行時依然會去讀取該檔案。</p>



<h3 class="wp-block-heading">為什麼大家會討論這兩者的差異</h3>



<p>雖然可以使用 <code>appsettings.json</code>，但在雲原生環境中，我們通常會避免將機密資訊或變動頻繁的設定直接寫死在映像檔裡的 <code>appsettings.json</code>。這時會有幾種層次的處理方式：</p>



<h3 class="wp-block-heading">1. 容器環境變數 (Environment Variables)</h3>



<p>這是最直接的做法。ACA 允許你在部署時設定環境變數。對於 .NET 程式來說，環境變數會自動覆蓋 <code>appsettings.json</code> 中的同名設定。</p>



<ul class="wp-block-list">
<li>優點：簡單、快速。</li>



<li>缺點：如果設定值很多，管理起來很零碎。</li>
</ul>



<h3 class="wp-block-heading">2. ACA 內建的 Secrets</h3>



<p>對於資料庫密碼、API Key 等敏感資訊，ACA 有專門的 Secrets 管理介面。你可以先在 ACA 層級定義 Secret，再將其映射為環境變數讓程式讀取。</p>



<h3 class="wp-block-heading">3. Azure App Configuration</h3>



<p>這是一個外部的中心化設定管理服務。</p>



<ul class="wp-block-list">
<li><strong>適用時機：</strong> 當你有幾十個微服務（Container Apps），且希望在不重啟程式的情況下，改一個地方就讓所有服務同步更新設定（動態更新）。</li>



<li><strong>整合方式：</strong> 程式啟動時會連到 App Configuration 抓取設定，這同樣會覆蓋本地的 <code>appsettings.json</code>。</li>
</ul>



<h3 class="wp-block-heading">總結建議</h3>



<p>如果你只是單一服務，且設定不太會變動，繼續用 <code>appsettings.json</code> 配合 <strong>環境變數</strong> 覆蓋特定屬性是最平衡的做法。</p>



<p>如果你正在開發複雜的微服務架構，或是需要「功能開關」(Feature Flags)，這時才需要考慮引入 Azure App Configuration。所以並不是「只能」用它，而是它提供了更強大的集中管理能力。</p>



<p>對於一般的開發流程：</p>



<ol start="1" class="wp-block-list">
<li>開發環境：使用 <code>appsettings.Development.json</code>。</li>



<li>部署到 ACA：將正式環境的資料庫連線字串等，設定在 ACA 的 <strong>Secrets</strong> 或 <strong>Configuration</strong> 區塊，程式執行時會自動優先採用這些雲端設定。</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>create Container Apps 一定要選 容器應用程式環境, 容器應用程式環境 要怎麼增加vnet</p>



<p>在建立 Azure Container Apps (ACA) 時，<strong>容器應用程式環境 (Container Apps Environment)</strong> 是強制的，因為它就像是一個邏輯邊界，負責管理底層的網路、記錄檔 (Logging) 以及所有在裡面執行的 Container Apps。</p>



<p>如果你想要讓 ACA 具備 VNet 功能，必須在<strong>建立環境的當下</strong>就進行設定。</p>



<h3 class="wp-block-heading">為什麼一定要有環境</h3>



<p>環境 (Environment) 扮演了虛擬叢集的角色。同一個環境內的 Container Apps 可以透過內部名稱互相溝通，並共用同一個虛擬網路設定與 Log Analytics 工作區。你可以把它想像成一個專屬的社區，而 VNet 就是這個社區對外連線的專用道路。</p>



<h3 class="wp-block-heading">如何在建立時增加 VNet</h3>



<p>一旦環境建立完成，目前是不支援從「非 VNet 模式」切換成「VNet 模式」的。如果你需要加入 VNet，請參考以下步驟：</p>



<ul class="wp-block-list">
<li><strong>建立流程：</strong> 在建立 Container Apps 的過程中，進行到容器應用程式環境的設定分頁。</li>



<li><strong>網路分頁：</strong> 點選「建立新環境」或編輯現有環境設定時，找到 <strong>Networking (網路)</strong> 標籤。</li>



<li><strong>虛擬網路選項：</strong> 將「使用自有虛擬網路」勾選為 <strong>Yes (是)</strong>。</li>



<li><strong>子網路配置：</strong> 你需要指定一個現有的 VNet 以及一個專門給 ACA 使用的子網路 (Subnet)。
<ul class="wp-block-list">
<li>請注意：這個子網路必須是空的，且不能與其他服務共用。</li>



<li>子網路的大小至少需要 /27 或更寬（建議 /23），以應付未來自動擴展時需要的 IP 位址。</li>
</ul>
</li>
</ul>



<h3 class="wp-block-heading">外部與內部存取類型</h3>



<p>在設定 VNet 時，你還需要決定 <strong>VIP (虛擬 IP) 類型</strong>：</p>



<ul class="wp-block-list">
<li><strong>External (外部)：</strong> 你的 VNet 會有一個公開的實體 IP，外界可以透過網路存取環境內的服務，但內部通訊走 VNet。</li>



<li><strong>Internal (內部)：</strong> 整個環境完全隱藏在 VNet 內，沒有對外的公開 IP。這適合處理後端 API 或內部管理系統，安全性最高。</li>
</ul>



<h3 class="wp-block-heading">注意事項</h3>



<p>由於 ACA 底層是基於 Kubernetes 概念設計的，它對網路定義比較嚴格。如果你已經建立了一個「沒有 VNet」的環境，但現在需要連線到你私人網路裡的資料庫（例如位於 VNet 內的 SQL Server），唯一的做法是<strong>重新建立一個新的環境</strong>並在建立時勾選 VNet 整合。</p>



<p>如果你只是想連線到 Azure 其他有防火牆保護的服務（如 Key Vault），除了 VNet 之外，也可以考慮使用 <strong>Managed Identity (受控識別)</strong>，這在雲原生架構中通常比單純鎖 IP 更安全且彈性。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/04/azure-container-apps-vs-web-apps/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>azure web app 切換 plan</title>
		<link>https://stackoverflow.max-everyday.com/2026/04/azure-web-app-plan/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/04/azure-web-app-plan/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Wed, 15 Apr 2026 07:50:06 +0000</pubDate>
				<category><![CDATA[Azure 筆記]]></category>
		<category><![CDATA[azure]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=8284</guid>

					<description><![CDATA[由於你原本的 Web App 是在 F1 (Fr...]]></description>
										<content:encoded><![CDATA[
<p>由於你原本的 Web App 是在 <strong>F1 (Free)</strong> 等級，而 VNet 整合至少需要 <strong>B1 (Basic)</strong> 或以上，且你已經建立好了位於 <code>taiwannorth</code> 的新 Plan，現在我們需要把 Web App 「搬家」過去。</p>



<p>在 Azure 中，更改 Web App 的 Plan 主要是透過 <code>az webapp update</code> 指令完成。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">1. 執行搬家指令</h3>



<p>請執行以下指令將 Web App 切換到新的 Plan：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code>az webapp update `
  --name $WEB_APP_NAME `
  --resource-group $RESOURCE_GROUP `
  --plan $PLAN_NAME
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 搬家前的「鬼打牆」預警 (非常重要)</h3>



<p>在搬家過程中，你可能會遇到以下兩個常見限制，請先確認：</p>



<h4 class="wp-block-heading">A. 區域限制 (Region Match)</h4>



<p>你的 Web App 原本可能在 <code>japaneast</code> (從你之前的資源名稱 <code>jpe</code> 推測)，但你的新 Plan <code>asp-pr-stg-twn-b1-01</code> 是在 <code>taiwannorth</code>。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>注意：</strong> Azure <strong>不支援</strong>直接將現有的 Web App 跨區域移動 Plan。如果 Region 不同，上面的 <code>update</code> 指令會報錯。</p>



<ul class="wp-block-list">
<li><strong>解決方法：</strong> 如果區域不同，你必須刪除 Web App 重新建立在新的 Plan 下，或者在同區域建立一個 B1 Plan。</li>
</ul>
</blockquote>



<h4 class="wp-block-heading">B. 資源群組與 WebSpace 限制</h4>



<p>有時候同一個 Resource Group 內，不允許同時存在不同作業系統或特定類型的 Plan 混用。如果報錯「Requested features are not supported in the region」，通常代表你需要把新的 Plan 放在一個<strong>新的 Resource Group</strong> 裡，或者在同一個「WebSpace」內移動。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2. 套用完新 Plan 後，加入 VNet</h3>



<p>一旦成功切換到 B1 Plan，你就可以執行 VNet 整合了。根據你之前的變數，指令如下：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code># 1. 先為 Subnet 開啟委派 (Delegation)
az network vnet subnet update `
  --resource-group $RESOURCE_GROUP `
  --vnet-name $VNET_NAME `
  --name $SUBNET_NAME `
  --delegations Microsoft.Web/serverFarms

# 2. 將 Web App 接入 VNet
az webapp vnet-integration add `
  --name $WEB_APP_NAME `
  --resource-group $RESOURCE_GROUP `
  --vnet $VNET_NAME `
  --subnet $SUBNET_NAME
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3. 驗證狀態</h3>



<p>移動完成後，你可以確認 Web App 是否真的跑在新的 Plan 上：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code>az webapp show `
  --name $WEB_APP_NAME `
  --resource-group $RESOURCE_GROUP `
  --query "{Plan:appServicePlanId, SKU:sku}" `
  --output json
</code></pre>



<p><strong>你的 Web App 原本是在哪個 Region 呢？</strong> 如果原本在 <code>jpe</code> (日本東部) 而新 Plan 在 <code>taiwannorth</code> (台灣北部)，上述 <code>update</code> 指令會失敗，我們可能需要重新建立 Web App。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>又是一個 Azure CLI 的小陷阱！<code>az webapp update</code> 竟然不支援 <code>--plan</code> 參數，這確實有點不直覺。</p>



<p>在 Azure CLI 中，要更換 Web App 的 App Service Plan，正確的指令應該是：</p>



<h3 class="wp-block-heading"><strong><code>az webapp config set --plan</code></strong></h3>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">1. 修正後的搬家指令</h3>



<p>請改用這個指令來變更 Plan：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code>az webapp config set `
  --name $WEB_APP_NAME `
  --resource-group $RESOURCE_GROUP `
  --plan $PLAN_NAME
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2. 為什麼會報錯？</h3>



<ul class="wp-block-list">
<li><strong><code>az webapp update</code></strong>：主要用於更新 Web App 的一般屬性（如 HTTPS 設定、Tag、狀態等），但不處理基礎架構的更換。</li>



<li><strong><code>az webapp config set</code></strong>：專門處理 Web App 的「配置」層面，而 App Service Plan 被視為底層運行配置的一環，所以被歸類在這裡。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 再次提醒：區域 (Region) 檢查</h3>



<p>剛才提到你的 Web App 名稱有 <code>jpe</code> (Japan East)，而新 Plan 名稱有 <code>twn</code> (Taiwan North)。</p>



<p><strong>如果這兩個資源在不同的地理區域，指令執行後會噴出類似下方的錯誤：</strong></p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><code>Cannot move site to a different region.</code></p>
</blockquote>



<p><strong>如果真的跨區了，唯一的解法是：</strong></p>



<ol start="1" class="wp-block-list">
<li><strong>刪除</strong>原本在日本的 Web App（如果你沒有 Owner 權限刪除，可以先改名）。</li>



<li><strong>重新建立</strong>一個位於台灣 Plan 下的 Web App。</li>
</ol>



<p>PowerShell</p>



<pre class="wp-block-code"><code># 如果需要重新建立 (跨區時適用)
az webapp create `
  --resource-group $RESOURCE_GROUP `
  --plan $PLAN_NAME `
  --name $WEB_APP_NAME `
  --container-image-name "${ACR_NAME}.azurecr.io/policy-app:v1"
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4. 驗證是否成功</h3>



<p>執行完 <code>config set</code> 後，你可以用這行確認它現在跑在哪個 Plan 上：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code>az webapp show --name $WEB_APP_NAME --resource-group $RESOURCE_GROUP --query "appServicePlanId" -o tsv
</code></pre>



<p>你先試試看 <code>az webapp config set</code>，如果噴出 <code>Region</code> 相關的錯誤，我們就得走「重新建立」這條路了！</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/04/azure-web-app-plan/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>azure cli 的 server password 鬼打牆體驗</title>
		<link>https://stackoverflow.max-everyday.com/2026/04/azure-cli-server-password/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/04/azure-cli-server-password/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Wed, 15 Apr 2026 07:23:15 +0000</pubDate>
				<category><![CDATA[Azure 筆記]]></category>
		<category><![CDATA[azure]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=8279</guid>

					<description><![CDATA[看到這個結果，我們終於有進展了！URL 和 US...]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="559" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/azure-cli-server-password_clean-1024x559.jpg?v=1776237782" alt="" class="wp-image-8281" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/azure-cli-server-password_clean-1024x559.jpg?v=1776237782 1024w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/azure-cli-server-password_clean-600x327.jpg?v=1776237782 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/azure-cli-server-password_clean-768x419.jpg?v=1776237782 768w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/azure-cli-server-password_clean.jpg?v=1776237782 1408w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>看到這個結果，我們終於有進展了！<code>URL</code> 和 <code>USERNAME</code> 已經成功進去了，這證明 <strong>「檔案寫入法」</strong> 有效地解決了 Shell 解析的問題。</p>



<p>但是，<strong><code>DOCKER_REGISTRY_SERVER_PASSWORD</code> 依然是 <code>null</code></strong>。</p>



<p>這是一個非常經典的 <strong>Azure App Service 「安全特性」</strong>，而不是 Bug：</p>



<h3 class="wp-block-heading">1. 為什麼是 null？（真相大白）</h3>



<p>在 Azure 中，<strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">某些特定的連線字串或敏感 Key（如 ACR 密碼）在透過 <code>list</code> 指令查詢時，基於安全性考量，有時會被遮蔽或不顯示</mark>。</strong>神奇的是有些密碼會顯示, 有些又不顯示.</p>



<p>不過，你的狀況更像是該值<strong>根本沒有寫入成功</strong>，原因通常是：</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>密碼太長或包含特殊字元</strong>。即便用了 JSON，如果編碼格式不是純 UTF-8（無 BOM），Azure CLI 讀取該特定長欄位時仍可能失敗。</p>
</blockquote>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2. 終極暴力破解：直接在指令中完成</h3>



<p>既然變數和檔案都有鬼，我們直接用 <strong>「環境變數傳遞法」</strong>。請在 PowerShell 執行這段「一條龍」指令：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code># 直接把密碼塞進變數，並強迫用最原始的方式寫入
$RAW_PWD = "your-pwd"

az webapp config appsettings set `
  --name "app-pr-stg-jpe" `
  --resource-group "rg-pr-stg-jpe-001" `
  --settings "DOCKER_REGISTRY_SERVER_PASSWORD=$($RAW_PWD)"
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3. 如果還是 null，請改用 Portal 確認</h3>



<p>如果執行完上面的指令，回傳的 JSON 裡 <code>value</code> 還是 <code>null</code>，請不要理會 CLI 的輸出，<strong>直接去瀏覽器看</strong>：</p>



<ol start="1" class="wp-block-list">
<li>登入 <strong><a href="https://www.google.com/search?q=https://portal.azure.com" target="_blank" rel="noreferrer noopener">Azure Portal</a></strong>。</li>



<li>找到你的 Web App <code>app-pr-stg-jpe</code>。</li>



<li>左側選單點擊 <strong>Environment variables</strong> (或是舊版的 Configuration)。</li>



<li>在 <strong>App settings</strong> 標籤下，找到 <code>DOCKER_REGISTRY_SERVER_PASSWORD</code>。</li>



<li>點擊右邊的小眼睛（Show value）。</li>
</ol>



<p><strong>如果 Portal 裡有值，那就代表寫入成功了，單純是 CLI 顯示不出來。</strong></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4. 方案 B：換一個 Key 測試</h3>



<p>如果連 Portal 都是空的，請試試看寫入一個「非標準名稱」的 Key，測試是否是長度限制：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code>az webapp config appsettings set `
  --name "app-pr-stg-jpe" `
  --resource-group "rg-pr-stg-jpe-001" `
  --settings MY_TEST_PWD="your-pwd"
</code></pre>



<ul class="wp-block-list">
<li>如果 <code>MY_TEST_PWD</code> 有值，但 <code>DOCKER_..._PASSWORD</code> 沒值，那就是 Azure 對特定 Key 的保護機制。</li>



<li>如果 <code>MY_TEST_PWD</code> 也是 <code>null</code>，那就是你的 Token 權限雖然能發起請求，但無權寫入敏感字串（雖然這機率極低）。</li>
</ul>



<p><strong>請先試試第 2 步，然後直接去 Portal 確認！那是唯一的真理。</strong></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>恭喜！既然 <strong>Portal 裡有值</strong>，那就代表你的設定已經<strong>成功寫入 Azure 底層資料庫</strong>了。</p>



<p>你剛剛經歷的是 Azure CLI 在特定環境下常見的「視覺欺騙」現象。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">為什麼 CLI 一直顯示 <code>null</code>？</h3>



<p>這通常不是你的錯，而是以下幾個因素造成的：</p>



<ul class="wp-block-list">
<li><strong>敏感資訊保護 (Masking)</strong>：Azure CLI 為了防止密碼在終端機日誌（Logs）中以明文留下，有時會在回傳的 JSON 結果中將特定敏感名稱（如包含 <code>PASSWORD</code> 或 <code>SECRET</code> 的 Key）強制顯示為 <code>null</code>，即便寫入是成功的。</li>



<li><strong>非同步快取 (Cache Delay)</strong>：當你執行 <code>set</code> 指令時，CLI 會立即回傳一個狀態。有時這個回傳結果是從本地快取或近端節點抓取的，而資料還沒完全從後台同步回來，導致顯示為空。</li>



<li><strong>32-bit 轉 64-bit 的殘留行為</strong>：雖然你更新了 CLI，但某些設定檔（如 <code>~/.azure/config</code>）可能還殘留舊的解析偏好。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">下一步：驗證 Web App 是否能抓到 ACR 映像檔</h3>



<p>既然 App Settings 已經在 Portal 存好了，你的 Web App 現在應該具備拉取 Docker Image 的權限了。你可以執行以下指令來觸發重新啟動並檢查容器狀態：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code># 強制 Web App 重新啟動以套用新設定
az webapp restart --name "app-pr-stg-jpe" --resource-group "rg-pr-stg-jpe-001"

# 觀察 Container 的啟動日誌（看有沒有 Login Succeeded）
az webapp log tail --name "app-pr-stg-jpe" --resource-group "rg-pr-stg-jpe-001"
</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 小建議</h3>



<p>既然你現在不是 Owner，之後如果遇到類似的「靈異 <code>null</code>」，<strong>永遠以 Portal 的顯示為準</strong>。</p>



<p>如果你未來需要在 Script 中抓取這個值（而不是只靠眼睛看），可以試著在 <code>list</code> 指令後加上 <code>--include-show-all</code>（如果版本支援）或改用：</p>



<p><code>az webapp config appsettings list --name "app-pr-stg-jpe" -g "rg-pr-stg-jpe-001"</code></p>



<p>但通常只要 Portal 有，你的應用程式（Python/Node/FastAPI）就一定讀得到 <code>$DOCKER_REGISTRY_SERVER_PASSWORD</code>。</p>



<p>既然這關過了，接下來是要準備 Push 映像檔，還是要設定 CI/CD Pipeline 呢？</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<pre class="wp-block-code"><code>az webapp config appsettings list --name "app-pr-stg-jpe" -g "rg-pr-stg-jpe-001"
&#91;
  {
    "name": "DOCKER_REGISTRY_SERVER_PASSWORD",
    "slotSetting": false,
    "value": null
  },
  {
    "name": "DOCKER_REGISTRY_SERVER_URL",
    "slotSetting": false,
    "value": "https://arcprstgjpe001.azurecr.io"
  },
  {
    "name": "DOCKER_REGISTRY_SERVER_USERNAME",
    "slotSetting": false,
    "value": "arcprstgjpe001"
  }
]</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/04/azure-cli-server-password/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>azure 的 acrpull 失敗 AuthorizationFailed</title>
		<link>https://stackoverflow.max-everyday.com/2026/04/azure-acrpull-authorizationfailed/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/04/azure-acrpull-authorizationfailed/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Wed, 15 Apr 2026 02:11:15 +0000</pubDate>
				<category><![CDATA[Azure 筆記]]></category>
		<category><![CDATA[azure]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=8275</guid>

					<description><![CDATA[這個錯誤訊息代表你目前的帳號雖然可以建立資源，但...]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="559" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/azure-acrpull-authorizationfailed_clean-1024x559.jpg?v=1776219048" alt="" class="wp-image-8277" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/azure-acrpull-authorizationfailed_clean-1024x559.jpg?v=1776219048 1024w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/azure-acrpull-authorizationfailed_clean-600x327.jpg?v=1776219048 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/azure-acrpull-authorizationfailed_clean-768x419.jpg?v=1776219048 768w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/04/azure-acrpull-authorizationfailed_clean.jpg?v=1776219048 1408w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>這個錯誤訊息代表你目前的帳號雖然可以建立資源，但<strong>沒有權限指派角色（Role Assignment）</strong>。</p>



<p>Error message:</p>



<pre class="wp-block-preformatted">(AuthorizationFailed) The client 'max@your-company.com' with object id '7a85725f' does not have authorization to perform action 'Microsoft.Authorization/roleAssignments/write' over scope '/subscriptions/XXX/resourceGroups/rg-pr-stg-jpe-001/providers/Microsoft.ContainerRegistry/registries/arcprstgjpe001/providers/Microsoft.Authorization/roleAssignments/be44c8b3' or the scope is invalid. If access was recently granted, please refresh your credentials.<br>Code: AuthorizationFailed</pre>



<p>在 Azure 的權限體系中，建立資源只需要 Contributor (參與者) 權限，但指派權限（RBAC）則需要 <strong>Owner (擁有者)</strong> 或 <strong>User Access Administrator (使用者存取管理員)</strong> 權限。</p>



<h3 class="wp-block-heading">核心問題：權限不足</h3>



<p>你的帳號在該 Subscription 或 Resource Group 層級缺少 <code>Microsoft.Authorization/roleAssignments/write</code> 這個權限。</p>



<h3 class="wp-block-heading">解決方法</h3>



<p><strong>聯繫管理員提升權限</strong></p>



<p>你需要請該訂用帳戶的管理者，將你的帳號權限提升。</p>



<ul class="wp-block-list">
<li><strong>目標角色</strong>：Owner 或 User Access Administrator。</li>



<li><strong>範圍</strong>：建議在資源群組 <code>rg-pr-stg-jpe-001</code> 層級設定即可。</li>
</ul>



<p><strong>檢查目前的權限</strong></p>



<p>你可以執行以下指令，看看自己在該資源群組下到底有什麼角色：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code>az role assignment list --assignee max@microsoft.com --resource-group rg-pr-stg-jpe-001 --output table
</code></pre>



<p><strong>暫時繞過方法：使用 Admin User (不推薦用於正式環境)</strong></p>



<p>如果你急著測試 App Service 能否抓到影像，可以先避開 RBAC，直接開啟 ACR 的管理員帳號密碼：</p>



<p>PowerShell</p>



<pre class="wp-block-code"><code># 1. 開啟 ACR 管理員功能
az acr update --name arcprstgjpe001 --admin-enabled true

# 2. 取得帳號密碼
az acr credential show --name arcprstgjpe001
</code></pre>



<p>開啟後，你可以直接在 App Service 的部署設定中使用這組帳密，而不需要執行 <code>az role assignment</code>。</p>



<p>長期來看，要在 CI/CD 流程中自動化設定權限，你必須具備 <strong>Owner</strong> 角色。如果是公司內部的 PoC 環境，通常會直接給予開發負責人 Owner 權限以利測試。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>這兩個角色都擁有指派權限的能力，但它們在 <strong>對資源的操作權限</strong> 上有本質的區別。</p>



<h3 class="wp-block-heading">Owner (擁有者)</h3>



<p>這是權限最高的角色。</p>



<ul class="wp-block-list">
<li><strong>完全控制權</strong>：擁有者可以對該範圍（訂閱或資源群組）內的所有資源進行任何操作，包括建立、讀取、修改、刪除資源。</li>



<li><strong>權限管理</strong>：可以指派或移除其他人的 RBAC 角色。</li>



<li><strong>適用場景</strong>：通常給予專案負責人或系統管理員，因為他們需要處理資源的生命週期（如建立資料庫、刪除伺服器）以及團隊成員的權限。</li>
</ul>



<h3 class="wp-block-heading">User Access Administrator (使用者存取管理員)</h3>



<p>這是一個專注於 <strong>安全與合規</strong> 的角色。</p>



<ul class="wp-block-list">
<li><strong>無資源操作權</strong>：這個角色<strong>不能</strong>建立、啟動或刪除資源（如虛擬機、資料庫、ACR）。如果一個帳號只有這個角色，他連建立一個 Resource Group 都辦不到。</li>



<li><strong>權限管理</strong>：他唯一能做的就是管理角色指派。</li>



<li><strong>適用場景</strong>：通常給予公司的資安人員或稽核人員。他們負責審核與發放權限，但不會去動到工程師的資源配置，符合最小權限原則（Principle of Least Privilege）。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">比較表</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><td><strong>功能</strong></td><td><strong>Owner (擁有者)</strong></td><td><strong>User Access Administrator</strong></td></tr></thead><tbody><tr><td><strong>管理角色指派 (RBAC)</strong></td><td>可以</td><td>可以</td></tr><tr><td><strong>建立/刪除 Azure 資源</strong></td><td>可以</td><td><strong>不可以</strong></td></tr><tr><td><strong>查看/讀取 資源內容</strong></td><td>可以</td><td><strong>不可以</strong></td></tr><tr><td><strong>角色性質</strong></td><td>全能管理</td><td>純權限管理</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">針對你目前的問題</h3>



<p>你目前遇到 <code>AuthorizationFailed</code>，是因為你目前的身分（可能是 Contributor）雖然可以建立 ACR，但無權指派 <code>acrpull</code> 權限。</p>



<ul class="wp-block-list">
<li>如果你希望以後能 <strong>一條龍處理到底</strong>（建資源 + 設權限），你應該請管理員給你 <strong>Owner</strong>。</li>



<li>如果公司規範較嚴，不希望你擁有刪除所有東西的權限，但又要你能設權限，管理員則會給你 <strong>Contributor + User Access Administrator</strong> 的組合。</li>
</ul>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/04/azure-acrpull-authorizationfailed/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>在 Azure 中，不同 VNet 之間可以互相連線?</title>
		<link>https://stackoverflow.max-everyday.com/2026/04/azure-vnet-peering/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/04/azure-vnet-peering/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 07 Apr 2026 04:45:47 +0000</pubDate>
				<category><![CDATA[Azure 筆記]]></category>
		<category><![CDATA[azure]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=8255</guid>

					<description><![CDATA[在 Azure 中，不同 VNet 之間可以互相...]]></description>
										<content:encoded><![CDATA[
<p>在 Azure 中，不同 VNet 之間可以互相連線，但有幾個前提條件和不同的實作方式。</p>



<p>這正連接著你之前的問題：該用 <strong>VNet Peering</strong> 還是 <strong>Private Link</strong>？</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">1. 不同的 VNet 互連：主要方式</h3>



<h4 class="wp-block-heading"><strong>A. VNet Peering (虛擬網路對等互連) —— 最推薦</strong></h4>



<p>這是將兩個 VNet 打通最直接、效能最高的方式。</p>



<ul class="wp-block-list">
<li><strong>同區域 (Regional Peering)</strong>：連接同一個 Azure 區域內的 VNet。</li>



<li><strong>跨區域 (Global Peering)</strong>：連接不同 Azure 區域（例如：台灣與美國）的 VNet。</li>



<li><strong>特點</strong>：流量走的是 Microsoft 的私有骨幹網路，不會經過公用網際網路。連線後，兩邊的資源（如 VM）就像在同一個網路一樣，可以用私有 IP 直接互傳資料。</li>
</ul>



<h4 class="wp-block-heading"><strong>B. Private Link (私有連結)</strong></h4>



<p>如果你不想「打通整個網路」，只想讓 VNet A 的某台機器存取 VNet B 裡的「某個特定服務」（例如資料庫或你自己寫的 API），就用 Private Link。</p>



<ul class="wp-block-list">
<li><strong>優點</strong>：安全性最高，因為你只開放了「一個服務」而不是「整個網段」。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2. <strong>關鍵限制：IP 位址不能重疊</strong></h3>



<p>在你提供的 Microsoft FAQ 連結中，最重要的一點是：<strong>如果兩個 VNet 的 IP 位址範圍 (Address Space) 有重疊，它們就「無法」透過 VNet Peering 進行連線。</strong></p>



<ul class="wp-block-list">
<li><strong>錯誤範例</strong>：
<ul class="wp-block-list">
<li>VNet A: <code>10.0.0.0/16</code></li>



<li>VNet B: <code>10.0.0.0/16</code></li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>無法建立 Peering</strong>，因為路由器不知道 <code>10.0.0.1</code> 到底是指 A 還是 B。</li>
</ul>
</li>



<li><strong>正確範例</strong>：
<ul class="wp-block-list">
<li>VNet A: <code>10.1.0.0/16</code></li>



<li>VNet B: <code>10.2.0.0/16</code></li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>可以完美連線</strong>。</li>
</ul>
</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3. 如果 IP 真的重疊了怎麼辦？</h3>



<p>如果你接手了別人的專案，發現兩個 VNet 的 IP 範圍一模一樣，但又必須互連，這時你有兩種選擇：</p>



<ol start="1" class="wp-block-list">
<li><strong>使用 Private Link</strong>：Private Link <strong>不受 IP 重疊限制</strong>。因為它是在你的 VNet 裡產生一個新的 IP（端點），這個 IP 是你自己定的，不會衝突。</li>



<li><strong>使用 VPN Gateway (NAT)</strong>：透過 VPN 建立連線，並利用網路位址轉換 (NAT) 來避開衝突（複雜度較高）。</li>
</ol>



<h3 class="wp-block-heading">總結建議</h3>



<ul class="wp-block-list">
<li><strong>如果 IP 沒有重疊</strong>：請直接用 <strong>VNet Peering</strong>，這最簡單且速度最快。</li>



<li><strong>如果只想開放特定服務，或 IP 已重疊</strong>：請使用 <strong>Private Link</strong>。</li>



<li><strong>如果是跨專案的大型架構</strong>：建議採用上題提到的 <strong>Hub-Spoke</strong> 架構，統一規劃 IP 網段避免未來衝突。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>這組設定 <strong>絕對可以連線</strong>。</p>



<p>原因很簡單：<strong>這兩個 VNet 的 IP 位址範圍完全沒有重疊。</strong></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">1. 網路範圍分析</h3>



<p>我們來拆解這兩個網段：</p>



<ul class="wp-block-list">
<li><strong>VNet A (<code>10.0.1.0/24</code>)</strong>：
<ul class="wp-block-list">
<li>IP 範圍：<code>10.0.1.0</code> 到 <code>10.0.1.255</code></li>



<li>總可用位址：256 個（扣除 Azure 預留的 5 個，可用 251 個）。</li>
</ul>
</li>



<li><strong>VNet B (<code>10.2.0.0/16</code>)</strong>：
<ul class="wp-block-list">
<li>IP 範圍：<code>10.2.0.0</code> 到 <code>10.2.255.255</code></li>



<li>總可用位址：65,536 個。</li>
</ul>
</li>
</ul>



<p>因為 <code>10.0.x.x</code> 與 <code>10.2.x.x</code> 是不同的區塊，所以它們在路由上不會產生衝突。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2. 你該如何連通它們？</h3>



<p>針對你的需求，有兩種推薦做法：</p>



<h4 class="wp-block-heading"><strong>方案 A：VNet Peering（最推薦）</strong></h4>



<p>如果你希望 VNet A 的 VM 可以像在同一個辦公室一樣，直接透過 <code>10.2.0.5</code> 存取 VNet B 的機器。</p>



<ul class="wp-block-list">
<li><strong>優點</strong>：低延遲、高頻寬，設定最簡單。</li>



<li><strong>操作</strong>：在 VNet A 的設定頁面點擊「對等互連 (Peerings)」，並新增連線指向 VNet B（反向連線通常會自動建立）。</li>
</ul>



<h4 class="wp-block-heading"><strong>方案 B：Private Link（針對特定服務）</strong></h4>



<p>如果你只想讓 VNet A 存取 VNet B 裡的「特定資料庫」或「特定的 Load Balancer」，而不希望整個網路互通。</p>



<ul class="wp-block-list">
<li><strong>優點</strong>：安全性更高，符合最小權限原則。</li>



<li><strong>操作</strong>：在 VNet A 的子網段中建立一個 <strong>Private Endpoint</strong>，指向 VNet B 中的服務。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3. 注意事項（避坑指南）</h3>



<p>雖然這兩個 VNet 可以連線，但如果你之後要在這兩個 VNet 之間建立連線，請注意：</p>



<ol start="1" class="wp-block-list">
<li><strong>子網段 (Subnet) 規劃</strong>：確保你在 VNet 內部切分的 Subnet 也沒有超出上述範圍。</li>



<li><strong>DNS 解析</strong>：連線打通後，IP 雖然通了，但如果你想用「電腦名稱」存取（例如 <code>vm-prodb.internal</code>），你還需要設定 <strong>Azure Private DNS Zone</strong> 並關聯到這兩個 VNet。</li>



<li><strong>NSG 規則</strong>：記得在網路安全性群組 (NSG) 中放行來自對方網段的流量，否則封包會被防火牆擋住。</li>
</ol>



<p><strong>簡單總結：這兩個網段分得很開，你可以放心地進行 VNet Peering。</strong></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/04/azure-vnet-peering/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>azure Hub-Spoke（中樞與分支） 架構</title>
		<link>https://stackoverflow.max-everyday.com/2026/04/azure-hub-spoke/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/04/azure-hub-spoke/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 07 Apr 2026 03:31:54 +0000</pubDate>
				<category><![CDATA[Azure 筆記]]></category>
		<category><![CDATA[azure]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=8252</guid>

					<description><![CDATA[Hub-Spoke（中樞與分支） 它就像一個放射...]]></description>
										<content:encoded><![CDATA[
<p><strong>Hub-Spoke（中樞與分支）</strong> 它就像一個<strong>放射狀的交通樞紐</strong>：所有核心服務集中在「中樞」，而各個業務單位則在各自的「分支」中運行。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">1. 核心組件 (Components)</h2>



<h3 class="wp-block-heading"><strong>Hub (中樞 VNet)</strong></h3>



<p>這是網路的中央控制點，通常包含多個專案共用的<strong>共享服務</strong>：</p>



<ul class="wp-block-list">
<li><strong>Azure Firewall / NVA</strong>：負責檢查所有進出（東西向、南北向）的流量。</li>



<li><strong>VPN / ExpressRoute Gateway</strong>：連接公司地端機房（On-premises）。</li>



<li><strong>Azure Bastion</strong>：提供安全管理 VM 的跳板機。</li>



<li><strong>Shared Services</strong>：如 Active Directory (AD)、DNS 伺服器等。</li>
</ul>



<h3 class="wp-block-heading"><strong>Spoke (分支 VNet)</strong></h3>



<p>這是各個專案、開發環境或部門所擁有的隔離空間：</p>



<ul class="wp-block-list">
<li>每個專案擁有獨立的 VNet。</li>



<li><strong>不直接</strong>連接地端或公網。</li>



<li>透過 <strong>VNet Peering</strong> 連接到 Hub。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2. 流量是如何流動的？</h2>



<p>Hub-Spoke 架構最強大的地方在於<strong>強制流量經過中樞</strong>（透過使用者定義路由 UDR）：</p>



<ol start="1" class="wp-block-list">
<li><strong>分支對分支 (Spoke-to-Spoke)</strong>：專案 A 要連到專案 B 時，流量會先送往 Hub 的防火牆進行過濾，確認安全後再轉發到專案 B。</li>



<li><strong>分支對地端 (Spoke-to-On-prem)</strong>：所有專案共用 Hub 裡的 VPN Gateway，不需要每個專案都買一個昂貴的網關。</li>



<li><strong>分支對公網 (Spoke-to-Internet)</strong>：統一由 Hub 的防火牆出口，方便進行稽核與流量監控。</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">3. 為什麼要用這種架構？ (優點)</h2>



<ul class="wp-block-list">
<li><strong>節省成本</strong>：避免在多個 VNet 中重複部署昂貴的資源（如防火牆和網關）。</li>



<li><strong>中央管理 (Governance)</strong>：資安團隊只需要在 Hub 守好「大門」，就能管理所有專案的進出安全。</li>



<li><strong>隔離性 (Isolation)</strong>：不同專案（Spoke）之間預設是不通的，除非你在 Hub 設定了路由。這符合「最小權限」原則。</li>



<li><strong>突破限制</strong>：單個 VNet 有資源配額上限，透過多個 Spoke 可以繞過這些限制。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4. 搭配 Private Link 的進階用法</h2>



<p>在 Hub-Spoke 環境下，<strong>Private Link</strong> 扮演了畫龍點睛的角色：</p>



<ul class="wp-block-list">
<li><strong>中央私有端點</strong>：你可以把 Private Endpoint 放在 Hub 的一個專門子網段內。</li>



<li><strong>跨分支存取</strong>：所有 Spoke 都可以透過 VNet Peering 存取 Hub 裡那個唯一的 Private IP 來連到資料庫，這樣你就不需要在每個專案裡都建立一大堆 Endpoint。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">5. 什麼時候不建議用？</h2>



<p>如果你的規模非常小（只有 1-2 個 VNet），且沒有連回地端的需求，Hub-Spoke 可能會增加過多的<strong>複雜性</strong>與<strong>維運成本</strong>。這種情況下，簡單的 VNet Peering 就足夠了。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>小撇步</strong>：如果你不想手動管理這些路由和連線，Azure 提供了一種託管服務叫 <strong>Azure Virtual WAN</strong>，它本質上就是「服務化的 Hub-Spoke」，會幫你自動處理好所有的自動路由。</p>
</blockquote>



<p>你目前的公司架構，是否已經面臨多個專案需要統一管控安全出口的問題了呢？</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/04/azure-hub-spoke/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>azure Private Link  與 vnet 差異</title>
		<link>https://stackoverflow.max-everyday.com/2026/04/azure-private-link-vnet/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/04/azure-private-link-vnet/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 07 Apr 2026 03:27:32 +0000</pubDate>
				<category><![CDATA[Azure 筆記]]></category>
		<category><![CDATA[azure]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=8250</guid>

					<description><![CDATA[簡單來說，Azure VNet 是你的「雲端辦公...]]></description>
										<content:encoded><![CDATA[
<p>簡單來說，<strong>Azure VNet</strong> 是你的「雲端辦公室（基礎建設）」，而 <strong>Azure Private Link</strong> 則是通往這個辦公室的一條「VIP 專用通道」。</p>



<p>這兩者並非競爭關係，而是<strong>互補關係</strong>。你通常是在 VNet 內部部署 Private Link。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">1. 核心概念對比</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><td><strong>特性</strong></td><td><strong>Azure Virtual Network (VNet)</strong></td><td><strong>Azure Private Link</strong></td></tr></thead><tbody><tr><td><strong>本質</strong></td><td><strong>基礎設施</strong>：在 Azure 中邏輯隔離的私有網路。</td><td><strong>連線技術</strong>：將外部服務帶入 VNet 的技術。</td></tr><tr><td><strong>角色</strong></td><td>它是你部署資源（如 VM）的<strong>容器</strong>。</td><td>它是存取 PaaS（如 SQL, Storage）的<strong>路徑</strong>。</td></tr><tr><td><strong>主要功能</strong></td><td>提供 IP 位址空間、子網劃分、路由。</td><td>透過<strong>私有 IP</strong> 存取服務，完全避開公用網路。</td></tr><tr><td><strong>連線對象</strong></td><td>VM、Load Balancer、VPN/ExpressRoute。</td><td>Azure PaaS (SQL, Web App)、自建服務。</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2. Azure VNet (虛擬網路)</h2>



<p>VNet 是雲端中的私有網路。你可以控制其 IP 位址空間、劃分子網（Subnets），並在其中運行虛擬機器（VM）。</p>



<ul class="wp-block-list">
<li><strong>內部通訊</strong>：VNet 內的 VM 預設可以互相通訊。</li>



<li><strong>對外通訊</strong>：如果你需要 VNet A 連結 VNet B，你會使用 <strong>VNet Peering</strong>。</li>



<li><strong>安全性</strong>：使用網路安全性群組 (NSG) 來過濾流量。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">3. Azure Private Link (私有連結)</h2>



<p>當你想從 VNet 內存取 Azure 的 PaaS 服務（例如 <strong>Azure SQL</strong> 或 <strong>Storage Account</strong>）時，傳統做法是透過公用 IP 存取。<strong>Private Link</strong> 改變了這一點：</p>



<ul class="wp-block-list">
<li><strong>Private Endpoint (私有端點)</strong>：它會在你的 VNet 中產生一個<strong>虛擬網卡 (NIC)</strong>，並分配一個你 VNet 範圍內的<strong>私有 IP</strong>。</li>



<li><strong>安全隔離</strong>：你的流量會透過 Microsoft 的骨幹網路傳輸，<strong>絕不會經過公用網際網路</strong>。</li>



<li><strong>防止資料外洩</strong>：因為該私有端點只對應到特定的服務實例（例如：某個特定的資料庫），而不是整個雲端服務區塊，這大幅降低了資料被非法導向外部的風險。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4. 什麼時候該用哪一個？</h2>



<ul class="wp-block-list">
<li><strong>如果你要建置網路環境</strong>：你需要 <strong>VNet</strong>。它是所有網路操作的基礎。</li>



<li><strong>如果你要連接兩組 VM 網路</strong>：使用 <strong>VNet Peering</strong>（VNet 對等互連）。</li>



<li><strong>如果你要從 VNet 安全地存取資料庫或儲存體</strong>：使用 <strong>Private Link</strong>。</li>



<li><strong>如果你是服務提供者</strong>：你想把自己的服務私密地分享給其他客戶，而不暴露在公網上，你會建立 <strong>Private Link Service</strong>。</li>
</ul>



<h3 class="wp-block-heading">總結一句話：</h3>



<p><strong>VNet</strong> 決定了你的資源「住在哪裡」，而 <strong>Private Link</strong> 決定了你的資源如何「不出門且安全地」與外部服務溝通。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>在 Azure 的多專案、多子網段（Subnet）環境下，這並不是「二選一」的問題，而是<strong>如何將兩者結合使用</strong>的架構設計問題。</p>



<p>針對你的情境，核心邏輯如下：</p>



<h3 class="wp-block-heading">1. 跨專案的基礎網路連線：使用 VNet Peering</h3>



<p>如果你的「不同專案」位於不同的 VNet 中，且你希望這些專案內部的虛擬機器（VM）或服務能夠互相溝通，你首先需要解決的是<strong>網路打通</strong>的問題。</p>



<ul class="wp-block-list">
<li><strong>解決方案</strong>：<strong>VNet Peering（虛擬網路對等互連）</strong>。</li>



<li><strong>做法</strong>：將專案 A 的 VNet 與專案 B 的 VNet 建立 Peering。</li>



<li><strong>結果</strong>：兩個 VNet 就像在同一個網路內一樣，可以透過私有 IP 互通。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2. 跨專案存取 PaaS 服務：使用 Private Link</h3>



<p>如果你的情境是：專案 A 有一個 VM，需要存取專案 B 裡面的 <strong>Azure SQL 資料庫</strong>或 <strong>Storage Account</strong>，且你不希望透過公用網路。</p>



<ul class="wp-block-list">
<li><strong>解決方案</strong>：<strong>Azure Private Link (Private Endpoint)</strong>。</li>



<li><strong>做法</strong>：
<ol start="1" class="wp-block-list">
<li>在專案 B 的資料庫上啟用 Private Link。</li>



<li>在專案 A 的 VNet/Subnet 中建立一個 <strong>Private Endpoint（私有端點）</strong>。</li>
</ol>
</li>



<li><strong>結果</strong>：專案 A 的子網段會多出一個私有 IP，專案 A 的 VM 只要存取這個 IP，就能連到專案 B 的資料庫，完全不需要 VNet Peering 也能運作。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3. 決策指南：我該選哪一個？</h3>



<p>請根據你的<strong>通訊對象</strong>來決定：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><td><strong>你的需求場景</strong></td><td><strong>推薦方案</strong></td></tr></thead><tbody><tr><td><strong>兩個專案的 VM 之間要互傳資料</strong></td><td><strong>VNet Peering</strong> (建立大範圍的網路連線)</td></tr><tr><td><strong>從專案 A 存取專案 B 的資料庫 (PaaS)</strong></td><td><strong>Private Link</strong> (最安全，針對單一服務)</td></tr><tr><td><strong>不同專案共用同一個防火牆 (Hub-Spoke)</strong></td><td><strong>VNet Peering</strong> (將各專案連至中心 VNet)</td></tr><tr><td><strong>安全性要求極高，禁止任何公網存取</strong></td><td><strong>Private Link</strong> (確保資料存取路徑唯一且私有)</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4. 實務建議：Hub-Spoke 架構</h3>



<p>在企業環境中，通常會採用 <strong>Hub-Spoke（中樞與分支）</strong> 架構：</p>



<ol start="1" class="wp-block-list">
<li><strong>Hub VNet</strong>：放置防火牆（Azure Firewall）或 VPN Gateway。</li>



<li><strong>Spoke VNet (各專案)</strong>：每個專案擁有自己的 VNet 和子網段，並透過 <strong>VNet Peering</strong> 連接到 Hub。</li>



<li><strong>Private Link</strong>：各專案需要存取資料庫時，在各自的子網段內建立 <strong>Private Endpoint</strong>。</li>
</ol>



<h3 class="wp-block-heading">總結</h3>



<ul class="wp-block-list">
<li>如果你要連通的是「整個網路環境」，請用 <strong>VNet Peering</strong>。</li>



<li>如果你要存取的是「特定的 PaaS 服務（如 SQL, Web App, Storage）」，請用 <strong>Private Link</strong>。</li>
</ul>



<p>在跨專案的情況下，通常會先用 <strong>VNet Peering</strong> 把網路架構搭起來，再針對敏感的資料庫使用 <strong>Private Link</strong> 來加強安全。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/04/azure-private-link-vnet/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Docker 不允許兩個容器使用同一個名稱</title>
		<link>https://stackoverflow.max-everyday.com/2026/03/docker-%e4%b8%8d%e5%85%81%e8%a8%b1%e5%85%a9%e5%80%8b%e5%ae%b9%e5%99%a8%e4%bd%bf%e7%94%a8%e5%90%8c%e4%b8%80%e5%80%8b%e5%90%8d%e7%a8%b1/</link>
					<comments>https://stackoverflow.max-everyday.com/2026/03/docker-%e4%b8%8d%e5%85%81%e8%a8%b1%e5%85%a9%e5%80%8b%e5%ae%b9%e5%99%a8%e4%bd%bf%e7%94%a8%e5%90%8c%e4%b8%80%e5%80%8b%e5%90%8d%e7%a8%b1/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Fri, 27 Mar 2026 06:34:07 +0000</pubDate>
				<category><![CDATA[Azure 筆記]]></category>
		<category><![CDATA[azure]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=8153</guid>

					<description><![CDATA[error message: ✘ Contain...]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="559" src="https://stackoverflow.max-everyday.com/wp-content/uploads/2026/03/Gemini_Generated_Image_3cqmrb3cqmrb3cqm_clean-1024x559.jpg" alt="" class="wp-image-8155" srcset="https://stackoverflow.max-everyday.com/wp-content/uploads/2026/03/Gemini_Generated_Image_3cqmrb3cqmrb3cqm_clean-1024x559.jpg?v=1774593223 1024w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/03/Gemini_Generated_Image_3cqmrb3cqmrb3cqm_clean-600x327.jpg?v=1774593223 600w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/03/Gemini_Generated_Image_3cqmrb3cqmrb3cqm_clean-768x419.jpg?v=1774593223 768w, https://stackoverflow.max-everyday.com/wp-content/uploads/2026/03/Gemini_Generated_Image_3cqmrb3cqmrb3cqm_clean.jpg?v=1774593223 1408w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>error message:</p>



<pre class="wp-block-preformatted">✘ Contain… Error response from daemon: Conflict. The container name "/mssql_db" is already in use by container "44a71682bce20940b5cf17810ef89e8999a070708b0262b275e796fe845e0b7f". You have to remove (or rename) that container to be able to reuse that name. 0.0s<br>Error response from daemon: Conflict. The container name "/mssql_db" is already in use by container "44a71682bce20940b5cf17810ef89e8999a070708b0262b275e796fe845e0b7f". You have to remove (or rename) that container to be able to reuse that name.</pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>這個錯誤訊息代表你的電腦裡已經有一個名字叫做 mssql_db 的容器在執行，或者雖然停止了但名稱還被佔用著。Docker 不允許兩個容器使用同一個名稱。</p>



<h3 class="wp-block-heading">解決方法</h3>



<p>你可以選擇以下其中一種方式來處理：</p>



<h3 class="wp-block-heading">移除舊的容器</h3>



<p>如果你不需要原本那個容器，可以直接刪除它，讓新的設定生效。請在終端機輸入：</p>



<p>Bash</p>



<pre class="wp-block-code"><code>docker rm -f mssql_db
</code></pre>



<p>執行完後，再次執行 docker compose up 就可以正常啟動了。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">使用 Compose 自動重新建立</h3>



<p>你可以加上參數，讓 Docker Compose 自動處理掉衝突的容器：</p>



<p>Bash</p>



<pre class="wp-block-code"><code>docker compose up --force-recreate
</code></pre>



<p>這樣它會強制移除舊的容器並根據你現在的 yaml 檔案重新建立一個。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">修改名稱</h3>



<p>如果你想保留原本的容器，那就必須修改 docker-compose.yml 檔案中的 container_name。例如改名為 mssql_db_new：</p>



<p>YAML</p>



<pre class="wp-block-code"><code>services:
  db:
    image: mcr.microsoft.com/azure-sql-edge
    container_name: mssql_db_new
</code></pre>



<p>修改完存檔後，再重新執行啟動指令即可。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">目前電腦上有哪些容器正在跑嗎？</h2>



<p>你可以使用以下指令來查看電腦上目前正在執行的容器：</p>



<p>Bash</p>



<pre class="wp-block-code"><code>docker ps
</code></pre>



<p>這個指令會列出所有正在運作中的容器，包含它們的 ID、名稱、使用的映像檔以及埠號對應。</p>



<p>如果你想看到所有的容器，包含那些已經停止（Exited）但名稱還佔用著空間的容器，請使用：</p>



<p>Bash</p>



<pre class="wp-block-code"><code>docker ps -a
</code></pre>



<p>這能幫你確認剛才報錯的 mssql_db 是不是處於停止狀態但還沒被移除。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">欄位說明</h3>



<p>在輸出的表格中，你可以特別留意這幾項：</p>



<ul class="wp-block-list">
<li>NAMES：容器的名稱，剛才報錯的 mssql_db 就會出現在這一欄。</li>



<li>STATUS：顯示 Up 代表正在跑，Exited 代表已停止。</li>



<li>PORTS：顯示容器對外的連接埠。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">刪掉後, 需要重新下載 image?</h2>



<p>不需要重新下載 image。</p>



<p>刪除容器（Container）只是把那個正在跑的執行個體移除，原本下載好的映像檔（Image）會保留在你的電腦裡。</p>



<h3 class="wp-block-heading">為什麼不需要重載</h3>



<p>映像檔就像是軟體的安裝光碟，而容器是由光碟執行起來的一個程式。你把執行中的程式關掉並刪除，光碟檔案還是會在你的硬碟裡。</p>



<p>當你下一次執行 docker compose up 時，Docker 會檢查本地端是否已經有 <a target="_blank" rel="noreferrer noopener" href="https://www.google.com/search?q=https://mcr.microsoft.com/azure-sql-edge">mcr.microsoft.com/azure-sql-edge</a>，如果有，它就會直接秒速啟動，不需要再從網路上下載好幾百 MB 的資料。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">如何安全刪除並重啟</h3>



<p>你可以按照以下步驟操作：</p>



<ol start="1" class="wp-block-list">
<li>移除那個狀態為 Exited 的舊容器：</li>
</ol>



<p>Bash</p>



<pre class="wp-block-code"><code>docker rm mssql_db
</code></pre>



<ol start="2" class="wp-block-list">
<li>重新啟動你的專案：</li>
</ol>



<p>Bash</p>



<pre class="wp-block-code"><code>docker compose up -d
</code></pre>



<p>加上 -d 參數可以讓它在背景執行，這樣你就不會因為關掉視窗而導致容器停止。</p>



<p>需要我幫你確認你的資料卷（Volumes）是否會保留原本資料庫裡的資料嗎？</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2026/03/docker-%e4%b8%8d%e5%85%81%e8%a8%b1%e5%85%a9%e5%80%8b%e5%ae%b9%e5%99%a8%e4%bd%bf%e7%94%a8%e5%90%8c%e4%b8%80%e5%80%8b%e5%90%8d%e7%a8%b1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
