Docker Init 功能介紹
Docker Init 是 Docker Desktop 4.18 版本引入的一項強大功能,旨在簡化容器化專案的初始設定流程。透過 docker init 命令,開發者可以快速為現有專案生成最佳化的 Docker 設定檔,包括 Dockerfile、Docker Compose 檔案以及 .dockerignore 檔案。
Docker Init 的核心價值
- 自動偵測專案類型:智慧識別專案使用的程式語言和框架
- 最佳實務配置:生成符合 Docker 最佳實務的設定檔
- 互動式體驗:透過問答方式引導使用者完成設定
- 降低入門門檻:讓 Docker 新手也能輕鬆上手容器化
- 標準化配置:確保團隊成員使用一致的 Docker 設定
安裝與版本需求
Docker Init 功能內建於 Docker Desktop 中,確保您的 Docker Desktop 版本為 4.18 或更高:
1
2
3
4
5
| # 檢查 Docker 版本
docker version
# 檢查 docker init 是否可用
docker init --help
|
輸出範例:
1
2
3
4
5
6
| Usage: docker init [OPTIONS]
Creates Docker-related starter files for your project
Options:
--version Display version of the init plugin
|
支援的專案類型
Docker Init 支援多種常見的程式語言和框架,並持續擴充支援範圍:
目前支援的專案類型
| 專案類型 | 說明 | 自動偵測 |
|---|
| Go | Go 語言專案 | 偵測 go.mod 檔案 |
| Python | Python 專案 | 偵測 requirements.txt、pyproject.toml |
| Node.js | Node.js 專案 | 偵測 package.json 檔案 |
| Rust | Rust 專案 | 偵測 Cargo.toml 檔案 |
| ASP.NET Core | .NET 專案 | 偵測 .csproj 檔案 |
| PHP | PHP with Apache | 偵測 composer.json 檔案 |
| Java | Java/Maven/Gradle | 偵測 pom.xml 或 build.gradle |
| Other | 通用模板 | 手動選擇 |
專案類型偵測邏輯
Docker Init 會掃描專案目錄中的特定檔案來判斷專案類型:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # Go 專案 - 存在 go.mod
my-go-project/
├── go.mod
├── go.sum
└── main.go
# Node.js 專案 - 存在 package.json
my-node-project/
├── package.json
├── package-lock.json
└── src/
└── index.js
# Python 專案 - 存在 requirements.txt 或 pyproject.toml
my-python-project/
├── requirements.txt
├── pyproject.toml
└── app.py
|
互動式設定流程
執行 docker init 命令後,會啟動一個互動式的設定精靈,引導您完成整個配置過程。
基本使用方式
1
2
3
4
5
| # 進入專案目錄
cd /path/to/your/project
# 執行 docker init
docker init
|
互動式問答範例(Node.js 專案)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| Welcome to the Docker Init CLI!
This utility will walk you through creating the following files with sensible defaults for your project:
- .dockerignore
- Dockerfile
- compose.yaml
- README.Docker.md
Let's get started!
? What application platform does your project use? Node
? What version of Node do you want to use? 20.10.0
? Which package manager do you want to use? npm
? What command do you want to use to start the app? npm start
? What port does your server listen on? 3000
CREATED: .dockerignore
CREATED: Dockerfile
CREATED: compose.yaml
CREATED: README.Docker.md
✔ Your Docker files are ready!
|
互動式問答範例(Python 專案)
1
2
3
4
5
6
7
8
9
10
11
12
13
| Welcome to the Docker Init CLI!
? What application platform does your project use? Python
? What version of Python do you want to use? 3.11
? What port does your server listen on? 8000
? What is the command to run your app? python -m uvicorn main:app --host 0.0.0.0
CREATED: .dockerignore
CREATED: Dockerfile
CREATED: compose.yaml
CREATED: README.Docker.md
✔ Your Docker files are ready!
|
非互動模式
如果您想要自動化設定過程,可以使用非互動模式:
1
2
3
4
5
| # 使用預設值(自動接受所有預設選項)
docker init --type node
# 指定特定設定
docker init --type python --port 8080
|
生成的檔案結構
Docker Init 會在專案根目錄生成以下檔案:
檔案結構概覽
1
2
3
4
5
| my-project/
├── .dockerignore # Docker 忽略規則
├── Dockerfile # 容器映像檔建構指令
├── compose.yaml # Docker Compose 設定
└── README.Docker.md # Docker 使用說明文件
|
.dockerignore 檔案
.dockerignore 檔案定義了建構映像檔時應該排除的檔案和目錄:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| # Include any files or directories that you don't want to be copied to your
# container here (e.g., local build artifacts, temporary files, etc.).
#
# For more help, visit the .dockerignore file reference guide at
# https://docs.docker.com/go/build-context-dockerignore/
**/.DS_Store
**/__pycache__
**/.venv
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/bin
**/charts
**/docker-compose*
**/compose.y*ml
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
|
README.Docker.md 檔案
這個檔案提供了如何使用生成的 Docker 設定的說明:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| ### Building and running your application
When you're ready, start your application by running:
`docker compose up --build`.
Your application will be available at http://localhost:3000.
### Deploying your application to the cloud
First, build your image, e.g.: `docker build -t myapp .`.
If your cloud uses a different CPU architecture than your development
machine, you'll want to build the image for that architecture:
`docker build --platform linux/amd64 -t myapp .`.
Then, push it to your registry: `docker push myregistry.com/myapp`.
### References
* [Docker's Node.js guide](https://docs.docker.com/language/nodejs/)
|
Dockerfile 最佳實務
Docker Init 生成的 Dockerfile 遵循多項最佳實務,確保映像檔安全、高效且可維護。
Node.js Dockerfile 範例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
| # syntax=docker/dockerfile:1
# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Dockerfile reference guide at
# https://docs.docker.com/go/dockerfile-reference/
# Want to help us make this template better? Share your feedback here:
# https://forms.gle/ybq9Krt8jtBL3iCk7
ARG NODE_VERSION=20.10.0
################################################################################
# Use node image for base image for all stages.
FROM node:${NODE_VERSION}-alpine as base
# Set working directory for all build stages.
WORKDIR /usr/src/app
################################################################################
# Create a stage for installing production dependencies.
FROM base as deps
# Download dependencies as a separate step to take advantage of Docker's caching.
# Leverage a cache mount to /root/.npm to speed up subsequent builds.
# Leverage bind mounts to package.json and package-lock.json to avoid having to copy them
# into this layer.
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=package-lock.json,target=package-lock.json \
--mount=type=cache,target=/root/.npm \
npm ci --omit=dev
################################################################################
# Create a stage for building the application.
FROM deps as build
# Download additional development dependencies before building, as some projects require
# "devDependencies" to be installed to build. If you don't need this, remove this step.
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=package-lock.json,target=package-lock.json \
--mount=type=cache,target=/root/.npm \
npm ci
# Copy the rest of the source files into the image.
COPY . .
# Run the build script.
RUN npm run build
################################################################################
# Create a new stage to run the application with minimal runtime dependencies
# where the necessary files are copied from the build stage.
FROM base as final
# Use production node environment by default.
ENV NODE_ENV production
# Run the application as a non-root user.
USER node
# Copy package.json so that package manager commands work if used.
COPY package.json .
# Copy the production dependencies from the deps stage and also
# the built application from the build stage into the image.
COPY --from=deps /usr/src/app/node_modules ./node_modules
COPY --from=build /usr/src/app/dist ./dist
# Expose the port that the application listens on.
EXPOSE 3000
# Run the application.
CMD npm start
|
Python Dockerfile 範例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| # syntax=docker/dockerfile:1
ARG PYTHON_VERSION=3.11
FROM python:${PYTHON_VERSION}-slim as base
# Prevents Python from writing pyc files.
ENV PYTHONDONTWRITEBYTECODE=1
# Keeps Python from buffering stdout and stderr.
ENV PYTHONUNBUFFERED=1
WORKDIR /app
# Create a non-privileged user that the app will run under.
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
# Download dependencies as a separate step to take advantage of Docker's caching.
# Leverage a cache mount to /root/.cache/pip to speed up subsequent builds.
RUN --mount=type=cache,target=/root/.cache/pip \
--mount=type=bind,source=requirements.txt,target=requirements.txt \
python -m pip install -r requirements.txt
# Switch to the non-privileged user to run the application.
USER appuser
# Copy the source code into the container.
COPY . .
# Expose the port that the application listens on.
EXPOSE 8000
# Run the application.
CMD python -m uvicorn main:app --host 0.0.0.0 --port 8000
|
Go Dockerfile 範例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
| # syntax=docker/dockerfile:1
ARG GO_VERSION=1.21
FROM golang:${GO_VERSION}-alpine AS build
WORKDIR /src
# Download dependencies as a separate step to take advantage of Docker's caching.
RUN --mount=type=cache,target=/go/pkg/mod/ \
--mount=type=bind,source=go.sum,target=go.sum \
--mount=type=bind,source=go.mod,target=go.mod \
go mod download -x
# Build the application.
RUN --mount=type=cache,target=/go/pkg/mod/ \
--mount=type=bind,target=. \
CGO_ENABLED=0 go build -o /bin/server .
################################################################################
FROM alpine:latest AS final
# Install any runtime dependencies that are needed to run your application.
RUN --mount=type=cache,target=/var/cache/apk \
apk --update add \
ca-certificates \
tzdata \
&& \
update-ca-certificates
# Create a non-privileged user that the app will run under.
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
USER appuser
# Copy the executable from the "build" stage.
COPY --from=build /bin/server /bin/
# Expose the port that the application listens on.
EXPOSE 8080
# What the container should run when it is started.
ENTRYPOINT [ "/bin/server" ]
|
Dockerfile 最佳實務解析
Docker Init 生成的 Dockerfile 採用了多項最佳實務:
1. Multi-stage Build(多階段建構)
1
2
3
4
5
6
7
8
9
10
| # 建構階段
FROM node:20-alpine AS build
WORKDIR /app
COPY . .
RUN npm ci && npm run build
# 執行階段
FROM node:20-alpine AS production
COPY --from=build /app/dist ./dist
CMD ["node", "dist/index.js"]
|
優點:
- 減少最終映像檔大小
- 分離建構工具和執行環境
- 提高安全性
2. 使用非 root 使用者
1
2
3
4
5
6
7
8
9
10
11
| # 建立非特權使用者
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "10001" \
appuser
USER appuser
|
優點:
3. 利用 BuildKit Cache Mount
1
2
3
| RUN --mount=type=cache,target=/root/.npm \
--mount=type=bind,source=package.json,target=package.json \
npm ci
|
優點:
4. 使用 Alpine 基礎映像檔
優點:
- 映像檔體積更小(約 5MB vs 約 1GB)
- 攻擊面更小
- 下載和部署更快
Docker Compose 整合
Docker Init 同時生成 Docker Compose 設定檔,方便管理多容器應用程式。
基本 compose.yaml 範例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
| # Comments are provided throughout this file to help you get started.
# If you need more help, visit the Docker Compose reference guide at
# https://docs.docker.com/go/compose-spec-reference/
# Here the instructions define your application as a service called "server".
# This service is built from the Dockerfile in the current directory.
# You can add other services your application may depend on here, such as a
# database or a cache. For examples, see the Awesome Compose repository:
# https://github.com/docker/awesome-compose
services:
server:
build:
context: .
ports:
- 3000:3000
# The commented out section below is an example of how to define a PostgreSQL
# database that your application can use. `depends_on` tells Docker Compose to
# start the database before your application. The `db-data` volume persists the
# database data between container restarts. The `db-password` secret is used
# to set the database password. You must create `db/password.txt` and add
# a password of your choosing to it before running `docker compose up`.
# depends_on:
# db:
# condition: service_healthy
# db:
# image: postgres
# restart: always
# user: postgres
# secrets:
# - db-password
# volumes:
# - db-data:/var/lib/postgresql/data
# environment:
# - POSTGRES_DB=example
# - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
# expose:
# - 5432
# healthcheck:
# test: [ "CMD", "pg_isready" ]
# interval: 10s
# timeout: 5s
# retries: 5
# volumes:
# db-data:
# secrets:
# db-password:
# file: db/password.txt
|
完整的多服務 compose.yaml 範例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
| services:
# 前端應用
frontend:
build:
context: ./frontend
ports:
- "3000:3000"
environment:
- API_URL=http://backend:8080
depends_on:
- backend
# 後端 API
backend:
build:
context: ./backend
ports:
- "8080:8080"
environment:
- DATABASE_URL=postgres://postgres:password@db:5432/myapp
- REDIS_URL=redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
secrets:
- db-password
# PostgreSQL 資料庫
db:
image: postgres:15-alpine
restart: always
environment:
POSTGRES_DB: myapp
POSTGRES_USER: postgres
POSTGRES_PASSWORD_FILE: /run/secrets/db-password
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
secrets:
- db-password
# Redis 快取
cache:
image: redis:7-alpine
restart: always
volumes:
- redis-data:/data
command: redis-server --appendonly yes
volumes:
postgres-data:
redis-data:
secrets:
db-password:
file: ./secrets/db-password.txt
|
Docker Compose 常用指令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| # 建構並啟動所有服務
docker compose up --build
# 在背景執行
docker compose up -d
# 查看服務狀態
docker compose ps
# 查看服務日誌
docker compose logs -f
# 停止所有服務
docker compose down
# 停止並刪除資料卷
docker compose down -v
# 重新建構特定服務
docker compose build backend
# 擴展服務實例數量
docker compose up -d --scale backend=3
|
開發環境覆寫設定
建立 compose.override.yaml 用於開發環境特定設定:
1
2
3
4
5
6
7
8
9
10
11
12
| # compose.override.yaml - 開發環境設定
services:
server:
build:
target: development
volumes:
- .:/usr/src/app
- /usr/src/app/node_modules
environment:
- NODE_ENV=development
- DEBUG=*
command: npm run dev
|
1
2
| # Docker Compose 會自動合併 compose.yaml 和 compose.override.yaml
docker compose up
|
自訂模板
Docker Init 支援使用自訂模板來滿足特定需求或團隊標準。
建立自訂模板結構
1
2
3
| # 建立模板目錄結構
mkdir -p ~/.docker/init-templates/my-template
cd ~/.docker/init-templates/my-template
|
自訂 Dockerfile 模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| # ~/.docker/init-templates/my-template/Dockerfile.tmpl
# syntax=docker/dockerfile:1
# 公司自訂模板
# 維護者:DevOps Team
ARG BASE_IMAGE={{.BaseImage}}
FROM ${BASE_IMAGE}
LABEL maintainer="devops@company.com"
LABEL org.opencontainers.image.source="https://github.com/company/{{.ProjectName}}"
WORKDIR /app
# 安裝公司標準安全工具
RUN apt-get update && apt-get install -y \
ca-certificates \
curl \
&& rm -rf /var/lib/apt/lists/*
# 建立標準使用者
RUN groupadd -r appgroup && useradd -r -g appgroup appuser
{{.CustomSteps}}
USER appuser
EXPOSE {{.Port}}
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:{{.Port}}/health || exit 1
CMD {{.StartCommand}}
|
自訂 compose.yaml 模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| # ~/.docker/init-templates/my-template/compose.yaml.tmpl
services:
{{.ServiceName}}:
build:
context: .
dockerfile: Dockerfile
image: company-registry.com/{{.ProjectName}}:${TAG:-latest}
ports:
- "${HOST_PORT:-{{.Port}}}:{{.Port}}"
environment:
- APP_ENV=${APP_ENV:-production}
- LOG_LEVEL=${LOG_LEVEL:-info}
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:{{.Port}}/health"]
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M
|
使用環境變數自訂設定
建立 .docker-init.env 檔案:
1
2
3
4
| # .docker-init.env
DOCKER_INIT_TEMPLATE=my-template
DOCKER_INIT_REGISTRY=company-registry.com
DOCKER_INIT_MAINTAINER=devops@company.com
|
透過 CLI 參數覆寫設定
1
2
3
4
5
6
7
8
| # 使用自訂模板
docker init --template my-template
# 指定基礎映像檔版本
docker init --type node --node-version 18
# 指定服務名稱和連接埠
docker init --type python --port 5000 --entry-point "gunicorn app:app"
|
實際應用範例
以下是幾個完整的實際應用案例,展示如何使用 Docker Init 容器化不同類型的專案。
範例一:Node.js Express API
專案結構:
1
2
3
4
5
6
7
8
9
10
| express-api/
├── src/
│ ├── routes/
│ │ └── api.js
│ ├── middleware/
│ │ └── auth.js
│ └── index.js
├── package.json
├── package-lock.json
└── .env.example
|
執行 docker init:
1
2
| cd express-api
docker init
|
生成的 Dockerfile:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| # syntax=docker/dockerfile:1
ARG NODE_VERSION=20.10.0
FROM node:${NODE_VERSION}-alpine as base
WORKDIR /usr/src/app
FROM base as deps
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=package-lock.json,target=package-lock.json \
--mount=type=cache,target=/root/.npm \
npm ci --omit=dev
FROM base as build
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=package-lock.json,target=package-lock.json \
--mount=type=cache,target=/root/.npm \
npm ci
COPY . .
RUN npm run build
FROM base as final
ENV NODE_ENV production
USER node
COPY package.json .
COPY --from=deps /usr/src/app/node_modules ./node_modules
COPY --from=build /usr/src/app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/index.js"]
|
建構和執行:
1
2
3
4
5
6
7
8
| # 建構映像檔
docker build -t express-api:latest .
# 執行容器
docker run -d -p 3000:3000 --name api express-api:latest
# 使用 Docker Compose
docker compose up -d
|
範例二:Python FastAPI 應用
專案結構:
1
2
3
4
5
6
7
8
9
10
11
| fastapi-app/
├── app/
│ ├── __init__.py
│ ├── main.py
│ ├── models.py
│ └── routers/
│ └── users.py
├── requirements.txt
├── pyproject.toml
└── tests/
└── test_main.py
|
requirements.txt:
1
2
3
4
5
| fastapi==0.104.1
uvicorn[standard]==0.24.0
pydantic==2.5.2
sqlalchemy==2.0.23
asyncpg==0.29.0
|
執行 docker init:
1
2
| cd fastapi-app
docker init
|
自訂 compose.yaml 加入資料庫:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| services:
api:
build:
context: .
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql+asyncpg://postgres:password@db:5432/fastapi_db
depends_on:
db:
condition: service_healthy
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: fastapi_db
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
volumes:
postgres-data:
|
執行測試:
1
2
3
4
5
6
7
8
| # 啟動服務
docker compose up -d
# 測試 API
curl http://localhost:8000/docs
# 查看日誌
docker compose logs -f api
|
範例三:Go Gin Web 應用
專案結構:
1
2
3
4
5
6
7
8
9
10
11
12
| gin-webapp/
├── cmd/
│ └── server/
│ └── main.go
├── internal/
│ ├── handlers/
│ │ └── user.go
│ └── middleware/
│ └── auth.go
├── go.mod
├── go.sum
└── Makefile
|
go.mod:
1
2
3
4
5
6
7
8
| module github.com/company/gin-webapp
go 1.21
require (
github.com/gin-gonic/gin v1.9.1
github.com/go-redis/redis/v9 v9.3.0
)
|
執行 docker init 後的完整設定:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| # syntax=docker/dockerfile:1
ARG GO_VERSION=1.21
# 建構階段
FROM golang:${GO_VERSION}-alpine AS build
WORKDIR /src
# 安裝必要工具
RUN apk add --no-cache git
# 下載相依套件
RUN --mount=type=cache,target=/go/pkg/mod/ \
--mount=type=bind,source=go.sum,target=go.sum \
--mount=type=bind,source=go.mod,target=go.mod \
go mod download -x
# 建構應用程式
RUN --mount=type=cache,target=/go/pkg/mod/ \
--mount=type=bind,target=. \
CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /bin/server ./cmd/server
# 執行階段
FROM alpine:3.19 AS final
# 安裝 CA 憑證
RUN apk --no-cache add ca-certificates tzdata
# 建立非特權使用者
RUN adduser -D -g '' appuser
USER appuser
# 複製執行檔
COPY --from=build /bin/server /bin/server
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
ENTRYPOINT ["/bin/server"]
|
範例四:全端應用(React + Node.js + PostgreSQL)
專案結構:
1
2
3
4
5
6
7
8
9
10
11
| fullstack-app/
├── frontend/
│ ├── src/
│ ├── package.json
│ └── Dockerfile
├── backend/
│ ├── src/
│ ├── package.json
│ └── Dockerfile
├── compose.yaml
└── README.md
|
根目錄 compose.yaml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
| services:
frontend:
build:
context: ./frontend
target: production
ports:
- "80:80"
depends_on:
- backend
environment:
- REACT_APP_API_URL=http://localhost:3000
backend:
build:
context: ./backend
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@db:5432/app
- REDIS_URL=redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
secrets:
- db-password
db:
image: postgres:15-alpine
restart: always
environment:
POSTGRES_DB: app
POSTGRES_USER: postgres
POSTGRES_PASSWORD_FILE: /run/secrets/db-password
volumes:
- postgres-data:/var/lib/postgresql/data
- ./backend/migrations:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
secrets:
- db-password
cache:
image: redis:7-alpine
restart: always
volumes:
- redis-data:/data
command: redis-server --appendonly yes
volumes:
postgres-data:
redis-data:
secrets:
db-password:
file: ./secrets/db-password.txt
|
frontend/Dockerfile:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # syntax=docker/dockerfile:1
# 建構階段
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 生產階段
FROM nginx:alpine AS production
COPY --from=build /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
|
部署指令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 建立密碼檔案
mkdir -p secrets
echo "your-secure-password" > secrets/db-password.txt
# 建構並啟動所有服務
docker compose up --build -d
# 查看所有服務狀態
docker compose ps
# 查看即時日誌
docker compose logs -f
# 執行資料庫遷移
docker compose exec backend npm run migrate
# 停止所有服務
docker compose down
|
總結
Docker Init 是一個強大的工具,能夠大幅簡化 Docker 容器化專案的初始設定流程。透過本文的介紹,您已經學會了:
- Docker Init 的核心功能:自動偵測專案類型並生成最佳化的 Docker 設定檔
- 支援的專案類型:包括 Node.js、Python、Go、Rust、Java 等多種語言
- 互動式設定流程:透過問答方式完成配置,降低使用門檻
- 生成的檔案結構:包含 Dockerfile、compose.yaml、.dockerignore 等完整設定
- Dockerfile 最佳實務:多階段建構、非 root 使用者、快取優化等
- Docker Compose 整合:多服務編排、環境變數管理、服務相依設定
- 自訂模板:根據團隊需求建立標準化的 Docker 設定模板
- 實際應用範例:從單一服務到全端應用的完整容器化方案
透過 Docker Init,無論您是 Docker 新手還是經驗豐富的開發者,都能快速建立符合最佳實務的容器化設定,加速開發流程並確保一致的部署品質。
延伸學習資源