Docker Init 容器初始化設定

Docker Init Container Initialization Configuration

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 支援多種常見的程式語言和框架,並持續擴充支援範圍:

目前支援的專案類型

專案類型說明自動偵測
GoGo 語言專案偵測 go.mod 檔案
PythonPython 專案偵測 requirements.txt、pyproject.toml
Node.jsNode.js 專案偵測 package.json 檔案
RustRust 專案偵測 Cargo.toml 檔案
ASP.NET Core.NET 專案偵測 .csproj 檔案
PHPPHP with Apache偵測 composer.json 檔案
JavaJava/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 基礎映像檔

1
FROM node:20-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 容器化專案的初始設定流程。透過本文的介紹,您已經學會了:

  1. Docker Init 的核心功能:自動偵測專案類型並生成最佳化的 Docker 設定檔
  2. 支援的專案類型:包括 Node.js、Python、Go、Rust、Java 等多種語言
  3. 互動式設定流程:透過問答方式完成配置,降低使用門檻
  4. 生成的檔案結構:包含 Dockerfile、compose.yaml、.dockerignore 等完整設定
  5. Dockerfile 最佳實務:多階段建構、非 root 使用者、快取優化等
  6. Docker Compose 整合:多服務編排、環境變數管理、服務相依設定
  7. 自訂模板:根據團隊需求建立標準化的 Docker 設定模板
  8. 實際應用範例:從單一服務到全端應用的完整容器化方案

透過 Docker Init,無論您是 Docker 新手還是經驗豐富的開發者,都能快速建立符合最佳實務的容器化設定,加速開發流程並確保一致的部署品質。

延伸學習資源

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy