Advanced Topics

Deploying Angular Applications

Learn how to build Angular apps for production and deploy them — build optimization, deployment platforms, environment configuration, and CI/CD.

Production Build

Building for Production

bash
# Production build (optimized by default)
ng build

# The output goes to dist/your-app-name/

Angular's production build automatically applies:

OptimizationDescription
Ahead-of-Time (AOT)Templates compiled at build time
Tree ShakingRemoves unused code
MinificationShrinks JavaScript and CSS
Dead Code EliminationRemoves unreachable code
BundlingCombines files into optimized chunks
Differential LoadingGenerates ES2015+ and ES5 bundles

Build Output

dist/my-app/
├── browser/
│   ├── index.html
│   ├── main-[hash].js        # Application code
│   ├── polyfills-[hash].js   # Browser polyfills
│   ├── runtime-[hash].js     # Webpack runtime
│   ├── styles-[hash].css     # Compiled styles
│   ├── chunk-[hash].js       # Lazy-loaded modules
│   └── assets/               # Static assets
│       ├── images/
│       └── fonts/
└── 3rdpartylicenses.txt

Build Configuration

In angular.json, customize production builds:

json
{
  "configurations": {
    "production": {
      "budgets": [
        {
          "type": "initial",
          "maximumWarning": "500kb",
          "maximumError": "1mb"
        },
        {
          "type": "anyComponentStyle",
          "maximumWarning": "4kb",
          "maximumError": "8kb"
        }
      ],
      "outputHashing": "all",
      "sourceMap": false,
      "optimization": true
    }
  }
}

Environment Configuration

Using environment.ts Files

typescript
// src/environments/environment.ts (development)
export const environment = {
  production: false,
  apiUrl: 'http://localhost:3000/api',
  analyticsId: '',
};

// src/environments/environment.prod.ts (production)
export const environment = {
  production: true,
  apiUrl: 'https://api.myapp.com',
  analyticsId: 'UA-XXXXX-Y',
};

Configuration in angular.json

json
{
  "configurations": {
    "production": {
      "fileReplacements": [
        {
          "replace": "src/environments/environment.ts",
          "with": "src/environments/environment.prod.ts"
        }
      ]
    }
  }
}

Using Environment Variables

typescript
import { environment } from '../environments/environment';

@Injectable({ providedIn: 'root' })
export class ApiService {
  private baseUrl = environment.apiUrl;

  getUsers() {
    return this.http.get<User[]>(`${this.baseUrl}/users`);
  }
}

Deployment Platforms

1. Static Hosting (Vercel, Netlify, GitHub Pages)

Angular SPAs can be deployed to any static hosting:

Vercel:

bash
npm install -g vercel
vercel

Create vercel.json:

json
{
  "rewrites": [
    { "source": "/(.*)", "destination": "/index.html" }
  ]
}

Netlify:

Create netlify.toml:

toml
[build]
  command = "ng build"
  publish = "dist/my-app/browser"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

GitHub Pages:

bash
ng add angular-cli-ghpages
ng deploy --base-href=/my-repo/

2. Cloud Platforms

Firebase Hosting:

bash
# Install Firebase CLI
npm install -g firebase-tools

# Initialize
firebase init hosting

# Deploy
ng build
firebase deploy

firebase.json:

json
{
  "hosting": {
    "public": "dist/my-app/browser",
    "ignore": ["firebase.json", "**/.*"],
    "rewrites": [
      { "source": "**", "destination": "/index.html" }
    ],
    "headers": [
      {
        "source": "**/*.@(js|css)",
        "headers": [
          { "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
        ]
      }
    ]
  }
}

AWS S3 + CloudFront:

bash
# Build
ng build

# Sync to S3
aws s3 sync dist/my-app/browser s3://my-bucket --delete

# Invalidate CloudFront cache
aws cloudfront create-invalidation --distribution-id EXXX --paths "/*"

3. Docker

dockerfile
# Stage 1: Build
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2: Serve with Nginx
FROM nginx:alpine
COPY --from=build /app/dist/my-app/browser /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80

nginx.conf:

nginx
server {
    listen 80;
    root /usr/share/nginx/html;
    index index.html;

    # SPA routing
    location / {
        try_files $uri $uri/ /index.html;
    }

    # Cache static assets
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    add_header X-XSS-Protection "1; mode=block";
}
bash
docker build -t my-angular-app .
docker run -p 80:80 my-angular-app

Server-Side Rendering (SSR)

For SEO and performance, enable Angular SSR:

bash
ng add @angular/ssr

This adds:

  • server.ts — Express server
  • app.config.server.ts — Server config
  • SSR build configuration
bash
# Build with SSR
ng build

# Start server
node dist/my-app/server/server.mjs

CI/CD Pipeline

GitHub Actions

yaml
# .github/workflows/deploy.yml
name: Deploy Angular App

on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        run: npm test -- --watch=false --browsers=ChromeHeadless

      - name: Run linting
        run: npm run lint

      - name: Build for production
        run: npm run build

      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.ORG_ID }}
          vercel-project-id: ${{ secrets.PROJECT_ID }}
          vercel-args: '--prod'

Pre-Deployment Checklist

TaskCommand / Action
Run testsng test --watch=false
Run lintingng lint
Check bundle sizeng build and review budgets
Set environment variablesVerify environment.prod.ts
Enable source maps (optional)For debugging in production
Configure error trackingAdd Sentry / LogRocket
Set up monitoringGoogle Analytics, performance monitoring
Test production build locallynpx http-server dist/my-app/browser
Configure caching headersSet immutable cache for hashed assets
Enable compressiongzip/brotli on server

Congratulations!

You've completed the entire Angular learning module! You now have a solid foundation covering:

  1. Getting Started — Setting up and understanding Angular projects
  2. TypeScript — The language powering Angular
  3. Components & Templates — Building UI with Angular's component model
  4. Services & DI — Managing data and business logic
  5. Routing — Navigation and code splitting
  6. Forms — Template-driven and reactive forms
  7. RxJS & State — Reactive programming and state management
  8. Advanced Topics — Material UI, testing, performance, and deployment

Keep building, and explore the Angular documentation at angular.dev for the latest features and best practices!