容器化 Angular 應用程式

先決條件

開始之前,請確保您的系統上已安裝並可使用以下工具:

  • 您已安裝最新版本的 Docker Desktop
  • 您有一個 git 客戶端。本節中的示例使用基於命令列的 git 客戶端,但您可以使用任何客戶端。

Docker 新手?
Docker 基礎知識 指南開始,熟悉映象、容器和 Dockerfile 等關鍵概念。


概述

本指南將引導您完成使用 Docker 容器化 Angular 應用程式的完整過程。您將學習如何使用最佳實踐建立生產就緒的 Docker 映象,從而提高效能、安全性、可伸縮性和部署效率。

完成本指南後,您將:

  • 使用 Docker 容器化 Angular 應用程式。
  • 為生產構建建立和最佳化 Dockerfile。
  • 使用多階段構建最小化映象大小。
  • 使用自定義 NGINX 配置高效地提供應用程式。
  • 遵循最佳實踐構建安全且可維護的 Docker 映象。

獲取示例應用程式

克隆示例應用程式以與本指南一起使用。開啟終端,導航到您要工作的目錄,然後執行以下命令克隆 git 倉庫:

$ git clone https://github.com/kristiyan-velkov/docker-angular-sample

生成 Dockerfile

Docker 提供了一個互動式 CLI 工具 docker init,可幫助搭建容器化應用程式所需的配置檔案。這包括生成 Dockerfile.dockerignorecompose.yamlREADME.Docker.md

首先,導航到專案根目錄:

$ cd docker-angular-sample

然後執行以下命令:

$ docker init

您將看到類似於以下內容的輸出:

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!

CLI 將提示您一些關於應用程式設定的問題。為了一致性,請在提示時使用與以下示例中所示相同的回答:

問題回答
您的專案使用什麼應用程式平臺?節點
您想使用哪個版本的 Node?23.11.0-alpine
您想使用哪個包管理器?npm
您想在啟動伺服器之前執行 "npm run build" 嗎?
您的構建輸出到哪個目錄?dist
您想使用什麼命令來啟動應用程式?npm run start
您的伺服器監聽哪個埠?8080

完成後,您的專案目錄將包含以下新檔案:

├── docker-angular-sample/
│ ├── Dockerfile
│ ├── .dockerignore
│ ├── compose.yaml
│ └── README.Docker.md

構建 Docker 映象

docker init 生成的預設 Dockerfile 是通用 Node.js 應用程式的良好起點。然而,Angular 是一個編譯成靜態資產的前端框架,因此我們需要調整 Dockerfile,以最佳化 Angular 應用程式在生產環境中的構建和提供方式。

步驟 1:改進生成的 Dockerfile 和配置

在此步驟中,您將透過遵循最佳實踐來改進 Dockerfile 和配置檔案:

  • 使用多階段構建以保持最終映象的乾淨和精簡
  • 使用 NGINX(一個快速且安全的 Web 伺服器)提供應用程式
  • 僅包含所需內容以提高效能和安全性

這些更新有助於確保您的應用程式易於部署、快速載入併為生產做好準備。

注意

Dockerfile 是一個純文字檔案,其中包含構建 Docker 映象的分步說明。它自動化了應用程式及其依賴項和執行時環境的打包。
有關完整詳細資訊,請參閱 Dockerfile 參考

步驟 2:配置 Dockerfile

複製並用以下配置替換您現有的 Dockerfile 的內容:

# =========================================
# Stage 1: Build the Angular Application
# =========================================
# =========================================
# Stage 1: Build the Angular Application
# =========================================
ARG NODE_VERSION=22.14.0-alpine
ARG NGINX_VERSION=alpine3.21

# Use a lightweight Node.js image for building (customizable via ARG)
FROM node:${NODE_VERSION} AS builder

# Set the working directory inside the container
WORKDIR /app

# Copy package-related files first to leverage Docker's caching mechanism
COPY package.json package-lock.json ./

# Install project dependencies using npm ci (ensures a clean, reproducible install)
RUN --mount=type=cache,target=/root/.npm npm ci

# Copy the rest of the application source code into the container
COPY . .

# Build the Angular application
RUN npm run build 

# =========================================
# Stage 2: Prepare Nginx to Serve Static Files
# =========================================

FROM nginxinc/nginx-unprivileged:${NGINX_VERSION} AS runner

# Use a built-in non-root user for security best practices
USER nginx

# Copy custom Nginx config
COPY nginx.conf /etc/nginx/nginx.conf

# Copy the static build output from the build stage to Nginx's default HTML serving directory
COPY --chown=nginx:nginx --from=builder /app/dist/*/browser /usr/share/nginx/html

# Expose port 8080 to allow HTTP traffic
# Note: The default NGINX container now listens on port 8080 instead of 80 
EXPOSE 8080

# Start Nginx directly with custom config
ENTRYPOINT ["nginx", "-c", "/etc/nginx/nginx.conf"]
CMD ["-g", "daemon off;"]
注意

我們使用 nginx-unprivileged 而不是標準的 NGINX 映象來遵循安全最佳實踐。在最終映象中以非 root 使用者身份執行:

  • 減少攻擊面
  • 與 Docker 關於容器加固的建議一致
  • 有助於符合生產環境中更嚴格的安全策略

步驟 3:配置 .dockerignore 檔案

.dockerignore 檔案告訴 Docker 在構建映象時要排除哪些檔案和資料夾。

注意

這有助於:

  • 減少映象大小
  • 加快構建過程
  • 防止敏感或不必要的檔案(如 .env.gitnode_modules)被新增到最終映象中。

要了解更多資訊,請訪問 .dockerignore 參考

複製並用以下配置替換您現有的 .dockerignore 的內容:

# ================================
# Node and build output
# ================================
node_modules
dist
out-tsc
.angular
.cache
.tmp

# ================================
# Testing & Coverage
# ================================
coverage
jest
cypress
cypress/screenshots
cypress/videos
reports
playwright-report
.vite
.vitepress

# ================================
# Environment & log files
# ================================
*.env*
!*.env.production
*.log
*.tsbuildinfo

# ================================
# IDE & OS-specific files
# ================================
.vscode
.idea
.DS_Store
Thumbs.db
*.swp

# ================================
# Version control & CI files
# ================================
.git
.gitignore

# ================================
# Docker & local orchestration
# ================================
Dockerfile
Dockerfile.*
.dockerignore
docker-compose.yml
docker-compose*.yml

# ================================
# Miscellaneous
# ================================
*.bak
*.old
*.tmp

步驟 4:建立 nginx.conf 檔案

為了在容器內高效地提供您的 Angular 應用程式,您將使用自定義設定配置 NGINX。此配置針對性能、瀏覽器快取、gzip 壓縮和客戶端路由支援進行了最佳化。

在專案根目錄中建立一個名為 nginx.conf 的檔案,並新增以下內容:

注意

要了解有關配置 NGINX 的更多資訊,請參閱 官方 NGINX 文件

worker_processes auto;

pid /tmp/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    # Logging
    access_log off;
    error_log  /dev/stderr warn;

    # Performance
    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
    keepalive_timeout  65;
    keepalive_requests 1000;

    # Compression
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_min_length 256;
    gzip_comp_level 6;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/javascript
        application/x-javascript
        application/json
        application/xml
        application/xml+rss
        font/ttf
        font/otf
        image/svg+xml;

    server {
        listen       8080;
        server_name  localhost;

        root /usr/share/nginx/html;
        index index.html;

        # Angular Routing
        location / {
            try_files $uri $uri/ /index.html;
        }

        # Static Assets Caching
        location ~* \.(?:ico|css|js|gif|jpe?g|png|woff2?|eot|ttf|svg|map)$ {
            expires 1y;
            access_log off;
            add_header Cache-Control "public, immutable";
        }

        # Optional: Explicit asset route
        location /assets/ {
            expires 1y;
            add_header Cache-Control "public, immutable";
        }
    }
}

步驟 5:構建 Angular 應用程式映象

有了自定義配置,您現在可以為您的 Angular 應用程式構建 Docker 映象了。

更新後的設定包括:

  • 更新後的設定包括一個為 Angular 量身定製的乾淨、生產就緒的 NGINX 配置。
  • 高效的多階段 Docker 構建,確保最終映象小巧安全。

完成上述步驟後,你的專案目錄現在應該包含以下檔案

├── docker-angular-sample/
│ ├── Dockerfile
│ ├── .dockerignore
│ ├── compose.yaml
│ ├── nginx.conf
│ └── README.Docker.md

現在您的 Dockerfile 已配置完畢,您可以為您的 Angular 應用程式構建 Docker 映象了。

注意

docker build 命令使用 Dockerfile 中的指令將您的應用程式打包成一個映象。它包含當前目錄(稱為構建上下文)中的所有必要檔案。

從專案根目錄執行以下命令:

$ docker build --tag docker-angular-sample .

此命令的作用:

  • 使用當前目錄中的 Dockerfile (.)
  • 將應用程式及其依賴項打包到 Docker 映象中
  • 將映象標記為 docker-angular-sample,以便您以後可以引用它

步驟 6:檢視本地映象

構建 Docker 映象後,您可以使用 Docker CLI 或 Docker Desktop 檢視本地計算機上可用的映象。由於您已經在終端中工作,讓我們使用 Docker CLI。

要列出所有本地可用的 Docker 映象,請執行以下命令:

$ docker images

示例輸出

REPOSITORY                TAG               IMAGE ID       CREATED         SIZE
docker-angular-sample     latest            34e66bdb9d40   14 seconds ago   76.4MB

此輸出提供了有關映象的關鍵詳細資訊:

  • 倉庫 – 分配給映象的名稱。
  • 標籤 – 一個版本標籤,有助於識別不同的構建(例如,最新)。
  • 映象 ID – 映象的唯一識別符號。
  • 建立時間 – 映象構建時的時間戳。
  • 大小 – 映象使用的總磁碟空間。

如果構建成功,您應該會看到列出的 docker-angular-sample 映象。


執行容器化應用程式

在前面的步驟中,您為 Angular 應用程式建立了一個 Dockerfile,並使用 docker build 命令構建了一個 Docker 映象。現在是時候在容器中執行該映象並驗證您的應用程式是否按預期工作了。

docker-angular-sample 目錄中,在終端中執行以下命令。

$ docker compose up --build

開啟瀏覽器並訪問 https://:8080 檢視應用程式。您應該會看到一個簡單的 Angular Web 應用程式。

在終端中按 ctrl+c 停止您的應用程式。

在後臺執行應用程式

您可以透過新增 -d 選項將應用程式與終端分離執行。在 docker-angular-sample 目錄中,在終端中執行以下命令。

$ docker compose up --build -d

開啟瀏覽器並訪問 https://:8080 檢視應用程式。您應該會看到您的 Angular 應用程式在瀏覽器中執行。

要確認容器正在執行,請使用 docker ps 命令:

$ docker ps

這將列出所有活動的容器及其埠、名稱和狀態。查詢暴露埠 8080 的容器。

示例輸出

CONTAINER ID   IMAGE                          COMMAND                  CREATED             STATUS             PORTS                    NAMES
eb13026806d1   docker-angular-sample-server   "nginx -c /etc/nginx…"   About a minute ago  Up About a minute  0.0.0.0:8080->8080/tcp   docker-angular-sample-server-1

要停止應用程式,請執行:

$ docker compose down
注意

有關 Compose 命令的更多資訊,請參閱Compose CLI 參考


摘要

在本指南中,您學習瞭如何使用 Docker 容器化、構建和執行 Angular 應用程式。透過遵循最佳實踐,您建立了一個安全、最佳化且生產就緒的設定。

你完成了什麼

  • 使用 docker init 初始化您的專案,以搭建基本的 Docker 配置檔案。
  • 將預設的 Dockerfile 替換為多階段構建,該構建編譯 Angular 應用程式並使用 Nginx 提供靜態檔案。
  • 替換預設的 .dockerignore 檔案,以排除不必要的檔案,保持映象乾淨高效。
  • 使用 docker build 構建您的 Docker 映象。
  • 使用 docker compose up 執行容器,包括在前臺和分離模式下。
  • 透過訪問 https://:8080 驗證應用程式是否正在執行。
  • 學習瞭如何使用 docker compose down 停止容器化應用程式。

您現在擁有一個完全容器化的 Angular 應用程式,它在 Docker 容器中執行,並可自信、一致地部署到任何環境中。


探索官方參考資料和最佳實踐以提升您的 Docker 工作流


後續步驟

您的 Angular 應用程式現已容器化,您可以進入下一步了。

在下一節中,您將學習如何使用 Docker 容器開發您的應用程式,從而在任何機器上實現一致、隔離和可重現的開發環境。