從零開始的 Docker 容器化指南: Vue3 + .NET Core + SQL Server

目錄

Docker 基礎概念

Docker 是一個開放原始碼的容器化平台,它可以讓我們將應用程式和其依賴項打包成一個獨立的容器。容器就像是一個輕量級的虛擬機,可以在任何支援 Docker 的環境中運行。

主要優點:

  • 環境一致性
  • 快速部署
  • 資源效率
  • 易於擴展

環境準備

  1. 安裝 Docker Desktop

    1
    2
    3
    4
    5
    6
    7
    8
    # Windows/Mac 下載並安裝 Docker Desktop
    https://www.docker.com/products/docker-desktop/

    # Linux (Ubuntu) 安裝 Docker Engine
    sudo apt update
    sudo apt install docker.io
    sudo systemctl start docker
    sudo systemctl enable docker
  2. 確認安裝

    1
    2
    docker --version
    docker-compose --version

SQL Server 容器設定

  1. 建立 SQL Server 容器

    1
    2
    3
    4
    5
    6
    docker pull mcr.microsoft.com/mssql/server:2019-latest

    docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=YourStrong@Passw0rd" \
    -p 1433:1433 --name sqlserver \
    -v sqlvolume:/var/opt/mssql \
    -d mcr.microsoft.com/mssql/server:2019-latest
  2. 確認容器運行狀態

    1
    docker ps

.NET Core API 容器化

  1. 在專案根目錄建立 Dockerfile

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
    WORKDIR /src
    COPY ["YourProject.csproj", "./"]
    RUN dotnet restore
    COPY . .
    RUN dotnet build -c Release -o /app/build

    FROM mcr.microsoft.com/dotnet/aspnet:6.0
    WORKDIR /app
    COPY --from=build /app/build .
    ENTRYPOINT ["dotnet", "YourProject.dll"]
  2. 設定 .dockerignore

    1
    2
    3
    bin/
    obj/
    node_modules/
  3. 建立映像檔和容器

    1
    2
    docker build -t myapi .
    docker run -d -p 5000:80 --name api myapi

Vue3 前端容器化

  1. 建立 Dockerfile

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    FROM node:16 as build-stage
    WORKDIR /app
    COPY package*.json ./
    RUN npm install
    COPY . .
    RUN npm run build

    FROM nginx:stable-alpine as production-stage
    COPY --from=build-stage /app/dist /usr/share/nginx/html
    EXPOSE 80
    CMD ["nginx", "-g", "daemon off;"]
  2. 建立映像檔和容器

    1
    2
    docker build -t myvue .
    docker run -d -p 8080:80 --name frontend myvue

使用 Docker Compose 整合服務

  1. 建立 docker-compose.yml

    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
    version: '3.8'

    services:
    db:
    image: mcr.microsoft.com/mssql/server:2019-latest
    environment:
    - ACCEPT_EULA=Y
    - SA_PASSWORD=YourStrong@Passw0rd
    ports:
    - "1433:1433"
    volumes:
    - sqlvolume:/var/opt/mssql

    api:
    build:
    context: ./api
    dockerfile: Dockerfile
    ports:
    - "5000:80"
    depends_on:
    - db
    environment:
    - ConnectionStrings__DefaultConnection=Server=db;Database=YourDB;User=sa;Password=YourStrong@Passw0rd;

    frontend:
    build:
    context: ./frontend
    dockerfile: Dockerfile
    ports:
    - "8080:80"
    depends_on:
    - api

    volumes:
    sqlvolume:
  2. 啟動所有服務

    1
    docker-compose up -d
  3. 檢查服務狀態

    1
    docker-compose ps

資源管理與監控

容器資源限制

為了確保系統穩定性,我們需要為容器設定適當的資源限制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# docker-compose.yml
services:
api:
deploy:
resources:
limits:
cpus: '0.5' # 限制最多使用 50% CPU
memory: 512M # 限制最大記憶體使用量
reservations:
cpus: '0.25' # 保證至少 25% CPU
memory: 256M # 保證最少記憶體

db:
deploy:
resources:
limits:
memory: 2G
volumes:
- sqlvolume:/var/opt/mssql
storage_opts:
size: '10G' # 限制容器儲存空間

監控工具設定

1. Portainer 安裝

Portainer 提供了直覺的 Web 介面來管理 Docker 容器:

1
2
3
4
5
docker volume create portainer_data
docker run -d -p 9000:9000 --name=portainer --restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce

安裝完成後可以訪問 http://localhost:9000 進行設定。

2. 日誌管理

在 docker-compose.yml 中加入日誌設定:

1
2
3
4
5
6
7
services:
api:
logging:
driver: "json-file"
options:
max-size: "200m"
max-file: "10"

開發環境設定

Hot Reload 配置

為了提升開發效率,我們可以設定 Hot Reload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# docker-compose.override.yml
services:
api:
volumes:
- .:/app
- /app/bin
- /app/obj
environment:
- ASPNETCORE_ENVIRONMENT=Development
- DOTNET_USE_POLLING_FILE_WATCHER=true
entrypoint: dotnet watch run

frontend:
volumes:
- ./src:/app/src
command: npm run dev

Debug 設定

在 VS Code 中設定容器除錯:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// .vscode/launch.json
{
"configurations": [
{
"name": "Docker .NET Core Attach",
"type": "coreclr",
"request": "attach",
"processName": "YourProject",
"pipeTransport": {
"pipeProgram": "docker",
"pipeArgs": ["exec", "-i", "api"],
"debuggerPath": "/vsdbg/vsdbg"
}
}
]
}

網路配置

網路隔離

為了提高安全性,我們可以將服務分配到不同的網路:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# docker-compose.yml
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # 只允許內部存取

services:
api:
networks:
- backend
- frontend

db:
networks:
- backend

frontend:
networks:
- frontend

部署與維護

CI/CD 整合

以下是一個使用 GitHub Actions 的範例:

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
# .github/workflows/docker-publish.yml
name: Docker Build and Push

on:
push:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: user/myapp:latest

環境變數管理

建立不同環境的設定檔:

1
2
3
4
5
6
7
# .env.development
DB_PASSWORD=dev_password
API_URL=http://localhost:5000

# .env.production
DB_PASSWORD=${PROD_DB_PASSWORD}
API_URL=https://api.example.com

自動化部署腳本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
# deploy.sh

# 拉取最新映像檔
docker-compose pull

# 使用生產環境設定檔
export COMPOSE_FILE=docker-compose.yml:docker-compose.prod.yml

# 更新服務
docker-compose up -d --remove-orphans

# 清理舊映像檔
docker image prune -f

常見問題與解決方案

1. SQL Server 連線問題

  • 確認連線字串中的主機名稱使用服務名稱 (db)
  • 確認 SA 密碼符合複雜度要求
  • 檢查防火牆設定

2. .NET Core API 容器化問題

  • 確保 Dockerfile 中的專案名稱正確
  • 檢查 ASPNETCORE_URLS 環境變數設定
  • 確認 API 監聽的埠號設定

3. Vue3 建置問題

  • 確保 node_modules 已被正確忽略
  • 檢查 nginx 設定是否正確
  • 確認環境變數檔案 (.env) 設定

4. 效能優化相關

映像檔優化

  • 使用多階段建置減少映像檔大小
  • 選用 alpine 版本的基礎映像檔
  • 適當使用 .dockerignore 排除不必要檔案

容器效能優化

  • 設定適當的記憶體和 CPU 限制
  • 使用 Volume 而非 bind mount
  • 定期清理未使用的容器和映像檔

網路效能

  • 使用內部網路進行容器間通訊
  • 合理設計網路拓撲
  • 需要時使用 DNS 快取

安全性建議

除了之前提到的最佳實踐外,還要注意:

容器安全

1
2
3
4
5
6
7
services:
api:
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp

機密管理

使用 Docker Secrets:

1
2
3
4
5
6
7
8
services:
api:
secrets:
- db_password

secrets:
db_password:
file: ./secrets/db_password.txt

最佳實踐建議

  1. 映像檔優化

    • 使用多階段建置減少映像檔大小
    • 善用 .dockerignore 排除不必要檔案
    • 選擇適當的基礎映像檔
  2. 安全性考量

    • 不要在映像檔中存儲敏感資訊
    • 定期更新基礎映像檔
    • 使用非 root 使用者運行容器
  3. 開發流程

    • 使用 docker-compose.override.yml 管理開發環境設定
    • 實作健康檢查機制
    • 建立完整的 CI/CD 流程

結論

透過本文的說明,我們完成了一個完整的 Docker 容器化環境設定,包含了 SQL Server 資料庫、.NET Core API 後端和 Vue3 前端。這樣的架構不僅方便開發和測試,也便於部署和擴展。

記得定期備份資料,並持續優化容器配置以提升效能和安全性。若有任何問題,歡迎參考 Docker 官方文件或社群資源尋求協助。

參考資源