Scaffolding an Angular Application

This walkthrough covers how to add server-side rendering to an Angular project using Angular Universal and then package the result into a Docker container.

The complete code for the example application is hosted on GitHub at https://github.com/pavankjadda/angular-ssr-docker


Creating the Angular Application

If an Angular application already exists, this initial setup phase can be skipped.

  • Start by scaffolding a new project.
   ng new angular-ssr-docker
  • Next, install Angular Material components.
ng add @angular/material
  • Include the indigo-pink theme by adding the import statement below to the styles.scss file.
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
  • Generate two components: Login and Home.

    Routing Behavior

Integrating Angular Universal

Following the guidance provided in the official Angular documentation:

  • Add the Universal schematic to the project using the CLI command.
ng add @nguniversal/express-engine

Once the schematic completes, the project structure will reflect the following additions:

src/
  index.html                 app web page
  main.ts                    bootstrapper for client app
  main.server.ts             * bootstrapper for server app
  style.css                  styles for the app
  app/ ...                   application code
    app.server.module.ts     * server-side application module
server.ts                    * express web server
tsconfig.json                TypeScript base configuration
tsconfig.app.json            TypeScript browser application configuration
tsconfig.server.json         TypeScript server application configuration
tsconfig.spec.json           TypeScript tests configuration
  • The CLI automatically adds a serve-ssr target under the projects/angular-ssr-docker/architect section in angular.json. This target comes with two pre-configured profiles: development and production.

  • Executing npm run dev:ssr triggers the development profile, while a production build leverages the production settings.

  • Refer to the typical configuration snapshot below. If the application fails to launch for any reason, adjusting the development section as shown here may resolve the issue.

"configurations": {
  "development": {
    "browserTarget": "pdts:build",
    "serverTarget": "pdts:server",
    "proxyConfig": "src/proxy.conf.json"
  },

Screen Shot 2021-10-11 at 10.13.45 AM

  • Additional profiles, such as dev or test, can be defined in the configuration file as demonstrated above.
  • Proceed to open a terminal in the project root and start a mock backend using the JSON server.
json-server - watch db.json
  • In a separate terminal window within the same project directory, launch the development server.
npm run dev:ssr

Containerizing with Docker

A production build must be generated before creating the Docker image.

  1. Execute the build command below. Adjust the --configuration=dev flag to the appropriate environment profile, such as test or production, based on the deployment target.
sudo ng build --configuration=dev && sudo ng run pdts:server
  1. Create a file named Dockerfile in the project root with the following contents to define the image.
## Use Node Slim image
FROM node:14-slim

## Copy source code
COPY . .

## Start the application
CMD ["node", "dist/angular-ssr-docker/server/main.js"]
  1. Use the command below to build the Docker image from the Dockerfile.
docker build -t angular_ssr_docker .
  1. Run the container, mapping it to port 4000 by default. The host port can be altered by modifying the -p 5001:4000 flag.
docker run -p 4000:4000 angular_ssr_docker
  1. Finally, verify the deployment by visiting http://localhost:4000.

All the source files for this demonstration are available in the GitHub repository. Happy coding :)