You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Angular应用Dockerfile实现单镜像多环境容器部署

实现单镜像多环境部署Angular应用

要实现构建一次镜像,运行多环境容器,核心思路是把环境配置从构建时固化改为运行时动态注入,下面提供两种可行方案:


方案一:编译多环境产物,运行时切换目录

这种方案适合需要保留各环境独立编译产物的场景,步骤如下:

1. 调整Angular构建配置

修改项目根目录的angular.json,为每个环境指定独立的输出目录:

"architect": {
  "build": {
    "options": {
      "outputPath": "dist"
    },
    "configurations": {
      "local": {
        "outputPath": "dist/local",
        "fileReplacements": [
          {
            "replace": "src/environments/environment.ts",
            "with": "src/environments/environment.local.ts"
          }
        ]
      },
      "prod": {
        "outputPath": "dist/prod",
        "fileReplacements": [
          {
            "replace": "src/environments/environment.ts",
            "with": "src/environments/environment.prod.ts"
          }
        ],
        "optimization": true
      },
      "staging": {
        "outputPath": "dist/staging",
        "fileReplacements": [
          {
            "replace": "src/environments/environment.ts",
            "with": "src/environments/environment.staging.ts"
          }
        ]
      }
    }
  }
}

2. 修改Dockerfile

# Stage 1: 构建所有环境的Angular产物
FROM node:14.10-alpine AS node

WORKDIR /app

# 缓存依赖,加快后续构建
COPY package*.json ./
RUN npm install

# 拷贝项目代码
COPY . .

# 编译所有需要的环境(按需调整环境列表)
RUN npm run build:local && npm run build:prod && npm run build:staging

# 清理无用源码
RUN rm -rf src

# Stage 2: 基于Nginx创建最终镜像
FROM nginx:alpine

# 拷贝所有环境的编译产物
COPY --from=node /app/dist /usr/share/nginx/html

# 拷贝自定义Nginx配置(默认根目录为/usr/share/nginx/html)
COPY ./nginx-custom.conf /etc/nginx/conf.d/default.conf

# 添加启动脚本,用于动态切换环境目录
COPY ./entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh

# 设置启动入口
ENTRYPOINT ["entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

3. 创建启动脚本entrypoint.sh

#!/bin/sh

# 默认使用local环境
TARGET_ENV=${ENV:-local}

# 修改Nginx配置中的根目录为对应环境的子目录
sed -i "s|root /usr/share/nginx/html;|root /usr/share/nginx/html/${TARGET_ENV};|" /etc/nginx/conf.d/default.conf

# 启动Nginx
exec nginx -g 'daemon off;'

4. 构建与运行

  • 构建镜像(无需指定环境参数):
    docker build --pull --rm -f "Dockerfile" -t angular-app:latest "."
    
  • 运行不同环境容器:
    # 启动local环境,映射端口8080
    docker run --rm -d -p 8080:80/tcp -e ENV=local angular-app:latest
    
    # 启动prod环境,映射端口8081
    docker run --rm -d -p 8081:80/tcp -e ENV=prod angular-app:latest
    
    # 启动staging环境,映射端口8082
    docker run --rm -d -p 8082:80/tcp -e ENV=staging angular-app:latest
    

方案二:运行时动态注入配置文件(推荐)

这种方案更轻量化,仅编译一次应用,通过外部配置文件动态注入环境参数,步骤如下:

1. 调整Angular项目配置

(1)创建外部配置文件

在src/assets/config/目录下创建env.json,存放可动态修改的配置:

{
  "apiUrl": "http://localhost:3000/api",
  "environment": "local"
}

(2)添加配置服务

创建src/app/services/config.service.ts,用于加载外部配置:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, tap } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ConfigService {
  private configData: any;

  constructor(private http: HttpClient) {}

  loadConfig(): Observable<any> {
    return this.http.get('/assets/config/env.json').pipe(
      tap(data => this.configData = data)
    );
  }

  getConfig(): any {
    return this.configData;
  }
}

(3)配置应用初始化加载

修改src/app/app.module.ts,让应用启动时先加载配置:

import { NgModule, APP_INITIALIZER } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { ConfigService } from './services/config.service';

// 初始化函数:加载配置
export function initConfig(configService: ConfigService) {
  return () => configService.loadConfig();
}

@NgModule({
  declarations: [/* 你的组件 */],
  imports: [HttpClientModule],
  providers: [
    ConfigService,
    {
      provide: APP_INITIALIZER,
      useFactory: initConfig,
      deps: [ConfigService],
      multi: true
    }
  ],
  bootstrap: [/* 根组件 */]
})
export class AppModule { }

(4)在应用中使用配置

在组件或服务中通过ConfigService获取动态配置:

import { Component, OnInit } from '@angular/core';
import { ConfigService } from './services/config.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
  apiUrl: string;

  constructor(private configService: ConfigService) {}

  ngOnInit(): void {
    this.apiUrl = this.configService.getConfig().apiUrl;
  }
}

2. 修改Dockerfile

# Stage 1: 构建Angular应用(仅编译一次)
FROM node:14.10-alpine AS node

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

# 编译为生产模式(或你需要的基础模式)
RUN npm run build:prod

RUN rm -rf src

# Stage 2: Nginx镜像
FROM nginx:alpine

# 拷贝编译产物
COPY --from=node /app/dist /usr/share/nginx/html

# 拷贝自定义Nginx配置
COPY ./nginx-custom.conf /etc/nginx/conf.d/default.conf

# 拷贝默认配置文件
COPY ./src/assets/config/env.json /usr/share/nginx/html/assets/config/env.json

# 添加启动脚本,动态替换配置
COPY ./entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh

ENTRYPOINT ["entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

3. 创建启动脚本entrypoint.sh

#!/bin/sh

# 设置默认环境参数,可通过docker run的-e参数覆盖
API_URL=${API_URL:-http://localhost:3000/api}
ENVIRONMENT=${ENVIRONMENT:-local}

# 生成新的env.json文件
cat > /usr/share/nginx/html/assets/config/env.json <<EOF
{
  "apiUrl": "$API_URL",
  "environment": "$ENVIRONMENT"
}
EOF

# 启动Nginx
exec nginx -g 'daemon off;'

4. 构建与运行

  • 构建镜像:
    docker build --pull --rm -f "Dockerfile" -t angular-app:latest "."
    
  • 运行不同环境容器:
    # Local环境
    docker run --rm -d -p 8080:80/tcp -e API_URL=http://local-api:3000/api angular-app:latest
    
    # Production环境
    docker run --rm -d -p 8081:80/tcp -e API_URL=http://prod-api:3000/api -e ENVIRONMENT=prod angular-app:latest
    

内容的提问来源于stack exchange,提问作者Abdelrahman Hamdy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 15:44:50