A Powerful Docker Container for an Nx Workspace Application

Discover how to easily create a Docker container for an Nx Workspace application with this step by step guide to creating a powerful site deployable in seconds with Docker

In a previous post, I briefly described the Nx Workspace and how to create Angular applications and libraries with Nrwl Extensions. I wanted the ability to run a prod build of the app in Docker for Windows so here is just one way of accomplishing that. With the Nx Workspace setup already I had to add just a few more files. This article assumes an Nx Workspace exists with an app named “client-demo”. It follows a similar approach to creating a static website using Docker. This article describes how to create a simple Docker container for an Nx Workspace Application.

NGINX

Using nxginx instead of a nanoserver due to size (~16 MB compared to 1+ GB) a nginx.conf file was needed. Place the file at the root of the Nx Workspace (the same level as the angular.json file):

// nginx.conf

worker_processes 1;

events {
worker_connections 1024;
}

http {
server {
listen 80;
server_name localhost;

root /usr/share/nginx/html;
index index.html index.htm;
include /etc/nginx/mime.types;

gzip on;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/css application/javascript;

location / {
try_files $uri $uri/ /index.html;
}
}
}

Dockerfile

It is now time for the Dockerfile. This file acts as a sort of definition file for a Docker Image. Place this file at the same level as the nginx.conf file:

// Dockerfile

FROM nginx:alpine
COPY nginx.conf /etc/nginx/nginx.conf
WORKDIR /usr/share/nginx/html
COPY dist/apps/client-demo .

Docker Compose

The Dockerfile is created. To use Docker Compose, create a docker-compose.yml file at the same level as the Dockerfile:

// docker-compose.yml

version: '3.1'

services:
app:
image: 'client-demo-app'
build: '.'
ports:
- 3000:80

Docker Ignore

When creating a Docker Image not every file is needed. In this case, only the dist/ folder is really needed. Using a .dockerignore file can help keep files and directories out of the build context. Place this file at the same level as the Dockerfile:

// .dockerignore

node_modules
.git
libs
tools
apps

Package.json

To leverage the files that have been created scripts can be added to the package.json file. This file should already exist within the Nx Workspace. Simply add the following scripts:

// package.json

...
"scripts": {
...
"client-demo-build": "ng build client-demo --prod",
"client-demo-image": "docker image build -f Dockerfile.client-demo -t client-demo-app .",
"client-demo-run": "docker-compose -f docker-compose.client-demo.yml up",
"client-demo-stop": "docker-compose -f docker-compose.client-demo.yml down",
"client-demo": "yarn client-demo-build && yarn client-demo-image && yarn client-demo-run"
},
...

Each of these scripts can run with npm run <script> or yarn <script>.

client-demo-build: This script runs ng build with the –prod flag to create a prod build of the Angular app.

client-demo-image: This script builds the client-demo-app image given a specific Dockerfile named Dockerfile.client-demo.

client-demo-run: This script uses docker-compose to run the app with docker-compose up. A specific file is specified with the ‘-f’ flag named docker-compose.client-demo.yml.

client-demo-stop: This script acts as the opposite of docker-compose up. As long as this script runs after the client-demo-run script, the app can be started and stopped any number of times.

client-demo: This script simply chains the execution of other scripts to create the prod build of the Angular app, create the Docker image, and serve the app. As it is written, yarn is required.

After creating the Nx Workspace, creating the Docker support files, adding the scripts to package.json and running npm run client-demo or yarn client-demo access the app from a browser at http://localhost:3000.

Docker Container for an Nx Workspace Application viewable from a browser
Default Nx Workspace application

Run npm run client-demo-stop or yarn client-demo-stop to stop the app.

An Introduction to the Nx Workspace

Learn how to create and maintain flexible angular applications with Nrwl Extensions

Angular development is great. It offers a great way to break problems into small, easily managed parts. With the Angular CLI, more power is at our fingertips. Narwhal Technologies Inc has created even more power by providing extensions to the Angular CLI. In this article, I will describe how to leverage the Nrwl Extensions to create and maintain flexible angular apps.

To learn how to install Nrwl, visit their getting started guide: https://nrwl.io/nx/guide-getting-started

Make sure to install Angular and Nrwl globally using npm. Here is a list of versions I used for this article:

node: 8.15.0
npm: 5.0.0
"@angular/cli": "~7.1.0"
"@nrwl/schematics": "7.4.0"

Creating an Nx Workspace

The Nx Workspace is a collection of Angular applications and libraries. When creating the workspace there will be a number of options available during generation. To start, run the following command:

create-nx-workspace <workspace-name>

This will begin the process of generating the workspace with the provided name.

After a few initial packages are installed, a prompt will display to choose the stylesheet format:

Stylesheet format prompt
stylesheet format prompt

Use the arrow keys to choose between CSS, SCSS, SASS, LESS, and Stylus. After the desired format is highlighted, press Enter.

The next prompt to display is the NPM scope. This will allow applications to reference libraries using an npm scope. For example, given a library called ‘my-lib’ and the npm scope is ‘my’, an application can import the library with the following statement:

import { MyLibModule } from '@my/my-lib';

To learn more about npm scopes check out their documentation: https://docs.npmjs.com/about-scopes

After specifying an NPM scope, press Enter. A third prompt will appear to specify which package manager to use:

NPM scope and package manager prompts
npm scope and package manager prompts

Use the arrow keys to choose between npm and Yarn. After the desired format is highlighted, press Enter.

Now that the generation process has everything it needs, it will continue to create the folder structure, files, and configuration:

Completed Nx Workspace generation
completed Nx Workspace generation

Project Structure

There are two important folders available after the workspace generation.

FolderDescription
/appsContains a collection of applications in the workspace.
/libsContains a collection of libraries in the workspace.

Adding Applications

Before adding an application with the CLI be sure to navigate into the workspace folder. In our example, the folder is ‘my-platform-workspace’. Then use the Angular CLI to generate the app:

PS C:\NoRepo\NxWorkspace> cd my-platform-workspace
PS C:\NoRepo\NxWorkspace\my-platform-workspace> ng g app <app name>

Tip

When using Visual Studio Code, open the Nx Workspace folder. This will default the command window to the necessary directory by default when using the built-in support called Terminals.

After adding the application, a number of prompts will display and the app generation will proceed:

Adding an application
adding an application

Running the application can be done using the Angular CLI as usual:

PS C:\NoRepo\NxWorkspace\my-platform-workspace> ng serve my-first-app

When the app is done building, go to http://localhost:4200 from a browser and see the default view:

Default app built with Nrwl Nx
default app built with Nrwl Nx

Adding a Library

Adding a library is as easy as adding an application with the following command:

ng g lib <library name>

Generally, a module should be created for libraries so they an be easily imported by applications. Once the library is created, components can be added to the library. Make sure to export any library components or other Angular objects (providers, pipes, etc) that need to be used by applications.

The Dependency Graph

Looking at package.json, there are a number of scripts that have been added. One that is nice to have is to generate and view a dependency graph of all of the applications and libraries in the workspace. A dependency graph can be generated using the following command:

npm run dep-graph

For example, I’ve added my-lib and my-lib2 to the my-first-app. This is the resulting dependency graph:

Sample dependency graph
sample dependency graph

Here we can see that the my-first-app-e2e (end-to-end) test application is dependent on the my-first-app application. The application is dependent on the libraries my-lib and my-lib2. This is a very simple example. This gains more value as more applications share more libraries.

It is also possible to get the JSON version of the dependency graph which can be used in various creative ways to help automate your workflow. This is all thanks to Nrwl Extensions and the power of Nx Workspaces.