<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Container on Bill.Lin&#39;s Notes</title>
		<link>https://xinqilin.github.io/post/container/</link>
		<description>Recent content in Container on Bill.Lin&#39;s Notes</description>
		<generator>Hugo</generator>
		<language>zh-tw</language>
		
		
		
		
			<lastBuildDate>Mon, 15 Jan 2024 00:00:00 +0800</lastBuildDate>
		
			<atom:link href="https://xinqilin.github.io/post/container/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>Docker Compose V2 遷移指南</title>
				<link>https://xinqilin.github.io/post/container/docker-compose-v2-migration/</link>
				<pubDate>Mon, 15 Jan 2024 00:00:00 +0800</pubDate>
				<guid>https://xinqilin.github.io/post/container/docker-compose-v2-migration/</guid>
				<description>&lt;h2 id=&#34;v1-vs-v2-的本質差異&#34;&gt;V1 vs V2 的本質差異&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;&#x9;&lt;thead&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;V1&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;V2&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/thead&gt;&#xA;&#x9;&lt;tbody&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;執行檔&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;docker-compose&lt;/code&gt;（Python）&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;docker compose&lt;/code&gt;（Go，Docker CLI plugin）&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;安裝方式&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;獨立 binary，另行安裝&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Docker Desktop 內建；Linux 用 &lt;code&gt;docker compose plugin&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;version:&lt;/code&gt; 欄位&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;必填（決定語法版本）&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;strong&gt;已廢棄&lt;/strong&gt;，出現時忽略並發出警告&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;網路命名&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;&amp;lt;project&amp;gt;_default&lt;/code&gt;（底線）&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;&amp;lt;project&amp;gt;-default&lt;/code&gt;（連字號）&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;啟動指令&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;docker-compose up&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;docker compose up&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;V1 已於 &lt;strong&gt;2023 年 7 月正式 EOL&lt;/strong&gt;，不再維護。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;移除-version-欄位&#34;&gt;移除 &lt;code&gt;version:&lt;/code&gt; 欄位&lt;/h2&gt;&#xA;&lt;p&gt;V1 時代的 &lt;code&gt;version: &amp;quot;3.9&amp;quot;&lt;/code&gt; 決定 Compose 文件語法版本。V2 不再有版本差異，統一支援最新語法。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# V1 寫法（過時，V2 會警告）&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;3.9&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-app:latest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# V2 正確寫法（刪除 version 欄位）&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;my-app:latest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;移除後不影響任何功能，僅消除 &lt;code&gt;the attribute version is obsolete&lt;/code&gt; 警告。&lt;/p&gt;</description>
			</item>
			<item>
				<title>Dockerfile 進階多階段建構</title>
				<link>https://xinqilin.github.io/post/container/multi-stage-build-advanced/</link>
				<pubDate>Mon, 15 Jan 2024 00:00:00 +0800</pubDate>
				<guid>https://xinqilin.github.io/post/container/multi-stage-build-advanced/</guid>
				<description>&lt;h2 id=&#34;基礎複習builder--runtime-模式&#34;&gt;基礎複習：Builder + Runtime 模式&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-dockerfile&#34; data-lang=&#34;dockerfile&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Stage 1: 建構&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;eclipse-temurin:21-jdk&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;builder&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;WORKDIR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/app&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt; . .&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; ./mvnw package -q -DskipTests&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Stage 2: 執行（只複製 jar，不含 JDK 與 source code）&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;eclipse-temurin:21-jre-jammy&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt; --from&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;builder /app/target/app.jar /app.jar&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;ENTRYPOINT&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;java&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;-jar&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;/app.jar&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;多階段建構的目的：&lt;strong&gt;最終 image 只含執行所需的檔案&lt;/strong&gt;，不含原始碼、建構工具、測試依賴。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;cache-mount加速重複建構&#34;&gt;Cache Mount：加速重複建構&lt;/h2&gt;&#xA;&lt;p&gt;每次 &lt;code&gt;docker build&lt;/code&gt; 若依賴沒有改變，Maven/npm 都會重新下載套件，非常耗時。&lt;code&gt;--mount=type=cache&lt;/code&gt; 讓套件管理器的 cache 跨 build 持久化。&lt;/p&gt;</description>
			</item>
			<item>
				<title>Docker MySQL：容器化部署與設定</title>
				<link>https://xinqilin.github.io/post/container/docker-mysql/</link>
				<pubDate>Tue, 18 Jan 2022 23:56:44 +0800</pubDate>
				<guid>https://xinqilin.github.io/post/container/docker-mysql/</guid>
				<description>&lt;h2 id=&#34;概述&#34;&gt;概述&lt;/h2&gt;&#xA;&lt;p&gt;在現代開發流程中，使用 Docker 部署資料庫已成為主流。將 MySQL 運行在 Docker 容器中，可以帶來許多好處：環境隔離、快速部署、版本控制、以及方便的遷移。這篇文章將引導您如何在 Docker 中設定和管理 MySQL 容器。&lt;/p&gt;&#xA;&lt;h2 id=&#34;啟動-mysql-容器&#34;&gt;啟動 MySQL 容器&lt;/h2&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;鏡像選擇&lt;/strong&gt;：&lt;code&gt;mysql/mysql-server&lt;/code&gt; 是 Oracle 的私有版本（不同於 Docker Hub 官方鏡像），現已標記為 deprecated。請使用官方 &lt;code&gt;mysql&lt;/code&gt; 鏡像（&lt;code&gt;docker.io/library/mysql&lt;/code&gt;）。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;使用 &lt;code&gt;docker run&lt;/code&gt; 指令可以快速啟動一個 MySQL 容器。以下是一個常用的範例，包含了密碼設定、埠映射和字元集設定。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker run &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --name mysql-server &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    -e &lt;span class=&#34;nv&#34;&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your_strong_password &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    -p 3306:3306 &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    -d &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    mysql:8.0 &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --character-set-server&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;utf8mb4 &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --collation-server&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;utf8mb4_unicode_ci &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --skip-character-set-client-handshake&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;指令參數說明&#34;&gt;指令參數說明&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;--name mysql-server&lt;/code&gt;: 為容器指定一個易於識別的名稱，這裡命名為 &lt;code&gt;mysql-server&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;-e MYSQL_ROOT_PASSWORD=your_strong_password&lt;/code&gt;: 設定 MySQL &lt;code&gt;root&lt;/code&gt; 使用者的密碼。&lt;strong&gt;請務必將 &lt;code&gt;your_strong_password&lt;/code&gt; 替換為您自己的強密碼&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;-p 3306:3306&lt;/code&gt;: 將主機的 3306 埠映射到容器的 3306 埠。這樣您就可以從主機透過 3306 埠連接到容器內的 MySQL 服務。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;-d&lt;/code&gt;: 以背景模式 (detached mode) 運行容器，讓容器在背景執行。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;mysql:8.0&lt;/code&gt;: 指定要使用的 Docker 映像檔。使用 Docker Hub 官方 &lt;code&gt;mysql&lt;/code&gt; 鏡像。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;--character-set-server=utf8mb4&lt;/code&gt;: 設定 MySQL 伺服器的預設字元集為 &lt;code&gt;utf8mb4&lt;/code&gt;，以支援更廣泛的字元，包括表情符號。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;--collation-server=utf8mb4_unicode_ci&lt;/code&gt;: 設定伺服器的預設排序規則為 &lt;code&gt;utf8mb4_unicode_ci&lt;/code&gt;，這是一種不區分大小寫和重音的排序規則。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;--skip-character-set-client-handshake&lt;/code&gt;: 禁用客戶端字元集握手。這有助於確保客戶端和伺服器之間的字元集一致性，避免亂碼問題。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;字元集設定的等效配置&#34;&gt;字元集設定的等效配置&lt;/h3&gt;&#xA;&lt;p&gt;上述字元集相關的 &lt;code&gt;docker run&lt;/code&gt; 參數，在 MySQL 的配置檔 (&lt;code&gt;my.cnf&lt;/code&gt;) 中，等效於以下設定：&lt;/p&gt;</description>
			</item>
			<item>
				<title>Docker Compose 完整指南：多容器應用程式的定義與執行</title>
				<link>https://xinqilin.github.io/post/container/docker-compose/</link>
				<pubDate>Mon, 26 Jul 2021 02:21:13 +0800</pubDate>
				<guid>https://xinqilin.github.io/post/container/docker-compose/</guid>
				<description>&lt;h2 id=&#34;概述&#34;&gt;概述&lt;/h2&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;版本說明&lt;/strong&gt;：&lt;code&gt;docker-compose&lt;/code&gt;（帶連字號，v1 Python 實作）自 2023 年 7 月已停止維護（EOL）。現行版本為 &lt;code&gt;docker compose&lt;/code&gt;（空格，v2 Go 實作，已整合進 Docker Desktop 與 Docker Engine）。本文使用 &lt;code&gt;docker compose&lt;/code&gt; 指令。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;在現代應用程式開發中，一個專案往往由多個服務組成，例如前端、後端 API、資料庫、快取等。這些服務各自運行在不同的容器中，而 Docker Compose 正是為了解決這種多容器應用程式的定義與管理而生。&lt;/p&gt;&#xA;&lt;p&gt;Docker Compose 允許您使用一個 YAML 檔案 (&lt;code&gt;docker-compose.yml&lt;/code&gt;) 來定義應用程式的所有服務、網路和儲存卷，然後透過單一指令啟動、停止或管理整個應用程式堆疊。這極大地簡化了開發、測試和部署的流程。&lt;/p&gt;&#xA;&lt;h2 id=&#34;常用-docker-compose-指令&#34;&gt;常用 Docker Compose 指令&lt;/h2&gt;&#xA;&lt;p&gt;以下是 Docker Compose 的一些常用指令，用於管理您的多容器應用程式：&lt;/p&gt;&#xA;&lt;table&gt;&#xA;&#x9;&lt;thead&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th style=&#34;text-align: left&#34;&gt;指令&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th style=&#34;text-align: left&#34;&gt;說明&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th style=&#34;text-align: left&#34;&gt;範例&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/thead&gt;&#xA;&#x9;&lt;tbody&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose version&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;顯示 Docker Compose 的版本資訊。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose version&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose --help&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;顯示 Docker Compose 的幫助訊息。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose --help&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose up&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;啟動並建立所有服務的容器。如果容器已存在，則會重新建立。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose up&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose up -d&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;在背景模式 (detached mode) 啟動並建立所有服務的容器。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose up -d&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose down&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;停止並移除所有服務的容器、網路和預設儲存卷。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose down&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose exec &amp;lt;service_name&amp;gt; &amp;lt;command&amp;gt;&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;在指定服務的容器中執行指令。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose exec microService /bin/bash&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose ps&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;列出所有服務的容器狀態。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose ps&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose top&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;顯示服務容器的運行進程。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose top&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose logs &amp;lt;service_name&amp;gt;&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;顯示指定服務容器的日誌輸出。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose logs microService&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose config&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;驗證 &lt;code&gt;docker-compose.yml&lt;/code&gt; 檔案的語法是否正確，並顯示解析後的配置。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose config&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose config -q&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;靜默模式驗證配置，只在有錯誤時輸出訊息。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose config -q&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose restart &amp;lt;service_name&amp;gt;&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;重新啟動指定服務的容器。若未指定服務，則重新啟動所有服務。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose restart microService&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose start &amp;lt;service_name&amp;gt;&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;啟動指定服務的容器。若未指定服務，則啟動所有已停止的服務。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose start microService&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose stop &amp;lt;service_name&amp;gt;&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;停止指定服務的容器。若未指定服務，則停止所有運行中的服務。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker compose stop microService&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h3 id=&#34;常用組合指令&#34;&gt;常用組合指令&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 驗證配置後，停止並重新啟動所有服務&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose config -q &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker compose down &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker compose up -d&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;docker-composeyml-檔案結構詳解&#34;&gt;&lt;code&gt;docker-compose.yml&lt;/code&gt; 檔案結構詳解&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;docker-compose.yml&lt;/code&gt; 是 Docker Compose 的核心配置檔案，它使用 YAML 語法來定義應用程式的服務。&lt;/p&gt;</description>
			</item>
			<item>
				<title>Docker 網路模式詳解：容器間通訊與外部連接</title>
				<link>https://xinqilin.github.io/post/container/docker-network/</link>
				<pubDate>Mon, 26 Jul 2021 02:21:13 +0800</pubDate>
				<guid>https://xinqilin.github.io/post/container/docker-network/</guid>
				<description>&lt;h2 id=&#34;概述&#34;&gt;概述&lt;/h2&gt;&#xA;&lt;p&gt;Docker 網路是容器化應用程式的基石，它決定了容器如何與外部世界通訊，以及容器之間如何互相連接。理解 Docker 的網路模式對於建構穩健、可擴展的容器化應用程式至關重要。本文將詳細介紹 Docker 提供的幾種主要網路模式及其應用場景。&lt;/p&gt;&#xA;&lt;h2 id=&#34;docker-網路模式&#34;&gt;Docker 網路模式&lt;/h2&gt;&#xA;&lt;p&gt;Docker 提供了多種網路驅動程式，每種驅動程式都提供不同的網路功能。最常用的包括 &lt;code&gt;bridge&lt;/code&gt;、&lt;code&gt;host&lt;/code&gt;、&lt;code&gt;none&lt;/code&gt; 和 &lt;code&gt;container&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;h3 id=&#34;1-bridge-橋接模式&#34;&gt;1. Bridge (橋接模式)&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;說明&lt;/strong&gt;：這是 Docker 的預設網路模式。當您不指定網路模式時，Docker 會自動為容器分配一個 IP 位址，並將其連接到一個名為 &lt;code&gt;docker0&lt;/code&gt; 的虛擬橋接器上。每個容器都會獲得一個獨立的網路堆疊。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;工作原理&lt;/strong&gt;：&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Docker 會在主機上建立一個名為 &lt;code&gt;docker0&lt;/code&gt; 的虛擬橋接器。&lt;/li&gt;&#xA;&lt;li&gt;每個容器都會建立一對虛擬乙太網卡 (veth pair)，其中一端連接到容器內的 &lt;code&gt;eth0&lt;/code&gt;，另一端連接到 &lt;code&gt;docker0&lt;/code&gt; 橋接器。&lt;/li&gt;&#xA;&lt;li&gt;容器可以透過 &lt;code&gt;docker0&lt;/code&gt; 橋接器與同一橋接器上的其他容器通訊，也可以透過主機的網路介面與外部網路通訊。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;優點&lt;/strong&gt;：提供良好的隔離性，容器間預設不直接暴露埠。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;缺點&lt;/strong&gt;：容器需要透過埠映射才能從外部訪問。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;2-host-主機模式&#34;&gt;2. Host (主機模式)&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;說明&lt;/strong&gt;：在主機模式下，容器不會有自己的獨立網路堆疊，而是直接使用主機的網路堆疊。這意味著容器會直接使用主機的 IP 位址和埠。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;工作原理&lt;/strong&gt;：容器內的應用程式會直接綁定到主機的網路介面和埠上。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;優點&lt;/strong&gt;：網路效能最佳，因為沒有額外的網路層。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;缺點&lt;/strong&gt;：&#xA;&lt;ul&gt;&#xA;&lt;li&gt;容器不再與主機隔離，容器內應用程式使用的埠不能與主機上已佔用的埠衝突。&lt;/li&gt;&#xA;&lt;li&gt;安全性較低，因為容器直接暴露在主機網路中。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;使用方式&lt;/strong&gt;：&lt;code&gt;--network host&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;3-none-無網路模式&#34;&gt;3. None (無網路模式)&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;說明&lt;/strong&gt;：在無網路模式下，容器會建立一個獨立的網路堆疊，但不會對其進行任何網路配置。容器將沒有網路介面，無法與外部通訊。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;工作原理&lt;/strong&gt;：容器只包含一個 &lt;code&gt;lo&lt;/code&gt; (loopback) 介面。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;優點&lt;/strong&gt;：適用於只需要計算資源而不需要網路連接的特殊場景，或者需要手動配置網路的進階情況。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;缺點&lt;/strong&gt;：容器無法進行任何網路通訊，除非手動配置。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;使用方式&lt;/strong&gt;：&lt;code&gt;--network none&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;4-container-容器模式&#34;&gt;4. Container (容器模式)&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;說明&lt;/strong&gt;：在容器模式下，新建立的容器不會有自己的網路堆疊，而是與另一個已存在的容器共享其網路堆疊。這意味著兩個容器會共享同一個 IP 位址和埠空間。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;工作原理&lt;/strong&gt;：兩個容器共享同一個網路命名空間。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;優點&lt;/strong&gt;：適用於需要緊密協同工作的應用程式，例如主應用程式容器和一個代理或日誌收集容器。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;缺點&lt;/strong&gt;：兩個容器會共享埠，可能導致埠衝突。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;使用方式&lt;/strong&gt;：&lt;code&gt;--network container:&amp;lt;name_or_id&amp;gt;&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;常用-docker-網路指令&#34;&gt;常用 Docker 網路指令&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;&#x9;&lt;thead&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th style=&#34;text-align: left&#34;&gt;指令&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th style=&#34;text-align: left&#34;&gt;說明&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th style=&#34;text-align: left&#34;&gt;範例&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/thead&gt;&#xA;&#x9;&lt;tbody&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker network ls&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;列出所有 Docker 網路。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker network ls&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker network prune&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;刪除所有未使用的網路。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker network prune&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker network inspect &amp;lt;network_name_or_id&amp;gt;&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;顯示指定網路的詳細資訊，包括連接到該網路的容器。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker network inspect bridge&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker inspect &amp;lt;container_id&amp;gt;&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;顯示指定容器的詳細資訊，包括其網路配置。&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;docker inspect &amp;lt;container_id&amp;gt;&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;自訂網路-user-defined-bridge-networks&#34;&gt;自訂網路 (User-defined Bridge Networks)&lt;/h2&gt;&#xA;&lt;p&gt;雖然 Docker 預設的 &lt;code&gt;bridge&lt;/code&gt; 網路 (&lt;code&gt;docker0&lt;/code&gt;) 已經足夠應付許多情況，但強烈建議您建立&lt;strong&gt;自訂橋接網路 (User-defined Bridge Networks)&lt;/strong&gt;。自訂網路提供了更好的隔離性、內建的 DNS 解析和更靈活的配置。&lt;/p&gt;</description>
			</item>
			<item>
				<title>Selenium Grid Multi-Architecture Docker 映像建構</title>
				<link>https://xinqilin.github.io/post/container/dockerfile-multi-arch-selenium/</link>
				<pubDate>Sun, 25 Jul 2021 02:21:13 +0800</pubDate>
				<guid>https://xinqilin.github.io/post/container/dockerfile-multi-arch-selenium/</guid>
				<description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;檔名說明&lt;/strong&gt;：本文原名 &lt;code&gt;Dockerfile-docker_in_docker.md&lt;/code&gt;，但實際內容是 Selenium 多架構映像建構，與 DinD（Docker in Docker）技術無關。標題已更正以符合實際內容。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;概述&#34;&gt;概述&lt;/h2&gt;&#xA;&lt;p&gt;在自動化測試和網路爬蟲等場景中，經常需要將應用程式與瀏覽器自動化工具 (如 Selenium) 打包到同一個 Docker 容器中。此外，為了支援不同的運行環境（例如 ARM64 或 x86_64 架構，以及 Firefox 或 Chrome 瀏覽器），我們需要一個靈活的建構流程。&lt;/p&gt;&#xA;&lt;p&gt;本文將深入解析一個多階段 Dockerfile，它展示了如何：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;建構一個包含 Node.js 應用程式的基礎映像檔。&lt;/li&gt;&#xA;&lt;li&gt;利用這個基礎映像檔，為不同的 CPU 架構和瀏覽器環境建立多個最終的 Selenium 應用程式映像檔。&lt;/li&gt;&#xA;&lt;li&gt;透過一個通用的 &lt;code&gt;entrypoint.sh&lt;/code&gt; 腳本，在容器啟動時自動判斷環境並執行對應的測試。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;dockerfile-詳解&#34;&gt;Dockerfile 詳解&lt;/h2&gt;&#xA;&lt;p&gt;這個 Dockerfile 採用了多階段建構 (Multi-stage Builds) 的方式，以確保最終映像檔的輕量化和模組化。&lt;/p&gt;&#xA;&lt;h3 id=&#34;第一階段應用程式建構-build-階段&#34;&gt;第一階段：應用程式建構 (&lt;code&gt;build&lt;/code&gt; 階段)&lt;/h3&gt;&#xA;&lt;p&gt;這個階段負責準備 Node.js 環境並打包應用程式。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-dockerfile&#34; data-lang=&#34;dockerfile&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ubuntu:22.04&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;build&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# 設定環境變數&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;ENV&lt;/span&gt; NVM_DIR /opt/nvm          &lt;span class=&#34;c1&#34;&gt;# NVM (Node Version Manager) 的安裝目錄&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;ENV&lt;/span&gt; NODE_VERSION v16.13.2     &lt;span class=&#34;c1&#34;&gt;# 指定要安裝的 Node.js 版本&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;ENV&lt;/span&gt; APP_DIR /app              &lt;span class=&#34;c1&#34;&gt;# 應用程式的工作目錄&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# 建立必要的目錄&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; -d &lt;span class=&#34;nv&#34;&gt;$APP_DIR&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; mkdir -p &lt;span class=&#34;nv&#34;&gt;$APP_DIR&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; -d &lt;span class=&#34;nv&#34;&gt;$NVM_DIR&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; mkdir -p &lt;span class=&#34;nv&#34;&gt;$NVM_DIR&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# 更新套件列表並安裝 curl (用於下載 NVM)&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; apt-get update &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get install curl -y&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# 安裝 NVM 和指定版本的 Node.js&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# 從 GitHub 下載 NVM 安裝腳本&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; curl -o &lt;span class=&#34;nv&#34;&gt;$NVM_DIR&lt;/span&gt;/install.sh https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# 執行 NVM 安裝腳本（只安裝 NVM 本身，尚未安裝 Node.js）&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; /bin/bash &lt;span class=&#34;nv&#34;&gt;$NVM_DIR&lt;/span&gt;/install.sh&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# 使用 NVM 安裝並啟用指定版本的 Node.js（必須在 PATH 設定前完成）&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; . &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NVM_DIR&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/nvm.sh&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; nvm install &lt;span class=&#34;nv&#34;&gt;$NODE_VERSION&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; nvm use &lt;span class=&#34;nv&#34;&gt;$NODE_VERSION&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; nvm &lt;span class=&#34;nb&#34;&gt;alias&lt;/span&gt; default &lt;span class=&#34;nv&#34;&gt;$NODE_VERSION&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# 安裝完成後再設定 PATH，確保路徑實際存在&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;ENV&lt;/span&gt; PATH &lt;span class=&#34;nv&#34;&gt;$NVM_DIR&lt;/span&gt;/versions/node/&lt;span class=&#34;nv&#34;&gt;$NODE_VERSION&lt;/span&gt;/bin:&lt;span class=&#34;nv&#34;&gt;$PATH&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# 複製應用程式檔案&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;test&lt;/span&gt; /app/test          &lt;span class=&#34;c1&#34;&gt;# 複製 &amp;#39;test&amp;#39; 目錄&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt; *.js /app/              &lt;span class=&#34;c1&#34;&gt;# 複製所有 .js 檔案&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt; *.json /app/            &lt;span class=&#34;c1&#34;&gt;# 複製所有 .json 檔案&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt; *.sh /app/              &lt;span class=&#34;c1&#34;&gt;# 複製所有 .sh 腳本&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; chmod &lt;span class=&#34;m&#34;&gt;0755&lt;/span&gt; /app/*.sh     &lt;span class=&#34;c1&#34;&gt;# 為腳本添加執行權限&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# 設定工作目錄並安裝 Node.js 依賴&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;WORKDIR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$APP_DIR&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; npm install&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;第二階段selenium-瀏覽器映像檔建構-多個-from-階段&#34;&gt;第二階段：Selenium 瀏覽器映像檔建構 (多個 &lt;code&gt;FROM&lt;/code&gt; 階段)&lt;/h3&gt;&#xA;&lt;p&gt;這個 Dockerfile 為不同的 CPU 架構 (ARM64, x86_64) 和瀏覽器 (Firefox, Chrome) 定義了多個最終映像檔。每個階段都從一個預先建構好的 Selenium 映像檔開始，並將第一階段建構好的應用程式複製進來。&lt;/p&gt;</description>
			</item>
			<item>
				<title>Dockerfile 基礎：建構 Docker 映像檔的核心指令</title>
				<link>https://xinqilin.github.io/post/container/dockerfile-basic/</link>
				<pubDate>Sat, 24 Jul 2021 02:21:13 +0800</pubDate>
				<guid>https://xinqilin.github.io/post/container/dockerfile-basic/</guid>
				<description>&lt;h2 id=&#34;概述&#34;&gt;概述&lt;/h2&gt;&#xA;&lt;p&gt;Dockerfile 是一個包含一系列指令的文字檔案，Docker 引擎會讀取這些指令，並自動建構出 Docker 映像檔 (Image)。它定義了映像檔的內容、運行環境以及啟動時執行的指令。理解 Dockerfile 是掌握 Docker 容器化技術的關鍵一步。&lt;/p&gt;&#xA;&lt;h2 id=&#34;dockerfile-核心指令詳解&#34;&gt;Dockerfile 核心指令詳解&lt;/h2&gt;&#xA;&lt;h3 id=&#34;1-基礎指令&#34;&gt;1. 基礎指令&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;code&gt;FROM&lt;/code&gt;：指定基礎映像檔。Dockerfile 的第一條指令必須是 &lt;code&gt;FROM&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;語法&lt;/strong&gt;：&lt;code&gt;FROM &amp;lt;image&amp;gt;[:&amp;lt;tag&amp;gt;]&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;範例&lt;/strong&gt;：&lt;code&gt;FROM ubuntu:18.04&lt;/code&gt; (使用 Ubuntu 18.04 作為基礎映像檔)&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;注意&lt;/strong&gt;：如果未指定 &lt;code&gt;tag&lt;/code&gt;，預設為 &lt;code&gt;latest&lt;/code&gt;。建議明確指定版本，以確保建構的可重複性。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;code&gt;MAINTAINER&lt;/code&gt;：指定映像檔的維護者資訊。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;語法&lt;/strong&gt;：&lt;code&gt;MAINTAINER &amp;lt;name&amp;gt; [email]&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;範例&lt;/strong&gt;：&lt;code&gt;MAINTAINER Bill.Lin &amp;lt;zzx123bill@gmail.com&amp;gt;&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;注意&lt;/strong&gt;：此指令已過時，建議使用 &lt;code&gt;LABEL&lt;/code&gt; 指令來替代，例如 &lt;code&gt;LABEL maintainer=&amp;quot;Bill.Lin &amp;lt;zzx123bill@gmail.com&amp;gt;&amp;quot;&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;2-執行指令&#34;&gt;2. 執行指令&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;code&gt;RUN&lt;/code&gt;：在建構映像檔時執行命令。每個 &lt;code&gt;RUN&lt;/code&gt; 指令都會在映像檔中建立一個新的層 (layer)。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;語法&lt;/strong&gt;：&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;RUN &amp;lt;command&amp;gt;&lt;/code&gt; (shell 模式，預設使用 &lt;code&gt;/bin/sh -c&lt;/code&gt; 執行)&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;RUN [&amp;quot;executable&amp;quot;, &amp;quot;param1&amp;quot;, &amp;quot;param2&amp;quot;]&lt;/code&gt; (exec 模式，直接執行可執行檔)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;範例 (shell 模式)&lt;/strong&gt;：&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-dockerfile&#34; data-lang=&#34;dockerfile&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; apt-get update -y &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get install nginx -y&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;注意&lt;/strong&gt;：使用 &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; 將多個命令串聯起來，可以減少映像檔層數，優化映像檔大小。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;範例 (exec 模式)&lt;/strong&gt;：&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-dockerfile&#34; data-lang=&#34;dockerfile&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;./test.php&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;dev&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;offline&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# 等同於在容器內執行 `./test.php dev offline`&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;code&gt;CMD&lt;/code&gt;：設定容器啟動時預設執行的命令。如果 &lt;code&gt;docker run&lt;/code&gt; 命令後帶有參數，&lt;code&gt;CMD&lt;/code&gt; 的命令會被覆蓋。一個 Dockerfile 中只能有一個 &lt;code&gt;CMD&lt;/code&gt;，多個 &lt;code&gt;CMD&lt;/code&gt; 只有最後一個生效。&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
