When deploying Angular applications as containers, managing environment variables at build time has always been a challenge. With Angular 19, the CLI now supports passing variables directly at build time. In this article, I’ll demonstrate how to dockerize your Angular application and leverage build-time variables for seamless containerized deployment.
What Are Build-Time Variables?
Build-time variables allow you to inject configuration values during the build process. These variables are embedded into the application, enabling different behaviors or settings based on the build environment.
This approach is perfect for:
- Environment-Specific API Endpoints: Switch between development, staging, and production configurations seamlessly.
- Feature Flags: Enable or disable features dynamically at build time.
- Secure Secrets Management: Avoid exposing sensitive information in your source code.
Step-by-Step Guide: Dockerizing an Angular App with Build-Time Variables
Step 1: Define Variables in the Environment File
Start by defining your variables as constants in an environment.ts
file (or another dedicated file). You can optionally define default values and export them as an environment
object for reuse in your Angular project:
declare const apiKey: string;
declare const configuration: 'development' | 'production';
export const environment = {
apiKey,
configuration,
};
Step 2: Create a Dockerfile with Build Arguments
Use a Dockerfile to define how the build-time variables will be injected. Below is a basic example; for a more complex setup, check the linked GitHub repository at the end of the article:
# Stage 1: Build Angular app
FROM node:lts-alpine AS build
# Set working directory
WORKDIR /app
# Copy package files and install dependencies
COPY package.json package-lock.json ./
RUN npm install
# Copy source code
COPY . .
# Define build arguments and use them during the build
ARG API_KEY
ARG CONFIGURATION=production
ENV API_KEY=$API_KEY
ENV CONFIGURATION=$CONFIGURATION
RUN npm run build -- --configuration=$CONFIGURATION --define apiKey=\"$API_KEY\" --define configuration=\"$CONFIGURATION\"
# Stage 2: Serve the app using Nginx
FROM nginx:alpine
COPY nginx.conf /etc/nginx/nginx.conf
COPY --from=build /app/dist /usr/share/nginx/html
The new --define
option passes the variable to the bundler and replaces the placeholder values we created in the first step.
Step 3: Pass Build-Time Variables in Docker Compose
Create a docker-compose.yml file to pass values for the build arguments defined in the Dockerfile:
services:
webapp:
build:
context: .
args:
- API_KEY=YOUR_PRODUCTION_API_KEY
- CONFIGURATION=production
ports:
- "4200:80"
environment:
- NODE_ENV=production
This setup ensures that YOUR_PRODUCTION_API_KEY and production are injected into your Angular build process during container creation.
Step 4: Access Build-Time Variables in Your Application
In your Angular application, use the injected variables like this:
import { Component } from '@angular/core';
import { environment } from '../environment';
@Component({
selector: 'app-root',
template: `
<div class="container">
<h1>Angular Environment Variables Demo</h1>
<p>Configuration: {{ configuration }}</p>
<p>API Key: {{ apiKey }}</p>
</div>
`,
})
export class AppComponent {
protected readonly apiKey = environment.apiKey;
protected readonly configuration = environment.configuration;
}
Step 5: Configure Nginx for Production
Finally, configure Nginx to serve your Angular application:
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
Place this configuration file (nginx.conf) in your project directory, and it will be included in the Docker image during the build process.
Benefits of Combining Docker and Build-Time Variables
• Security: Embed secrets like API keys during the build process, avoiding exposure in source code or runtime environments.
• Environment Flexibility: Switch environments by modifying Docker Compose files without hardcoding changes.
• Streamlined CI/CD: Automate builds for multiple environments, enhancing deployment efficiency.
Conclusion
With Angular 19’s build-time variables and Docker, you can streamline application builds, manage environment-specific configurations effortlessly, and enhance security. This combination is essential for developers looking to create scalable and flexible deployment pipelines. As promised I created a GitHub repository with a extended Docker file that can be found here: https://github.com/danielsogl/ng-env-docker-demo
Try Dockerizing your Angular application today and share your experiences!
Top comments (0)