容器化 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 容器开发您的应用程序,从而在任何机器上实现一致、隔离和可重现的开发环境。

© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.