It is useful now to integrate an Angular application in Docker.
With the help of Kubernetes a developer can increase scalability and support a DevOps approach to application development.

At Skaffolder we experienced how to integrate an Angular application and use Docker and Kubernetes. Here is how we did this in a few steps:

Prepare the Dockerfile

In order to create a Dockerfile we used a 2 stage approach. It allows to build the image on a NodeJS image and run it on an image from NGINX.

Here the Dockerfile step-by-step:

We started our image from NodeJS 8 Alpine version in order to have a lite image

FROM node:8-alpine as builder

Installing GIT and angluar-cli to allow building the Docker image

# Intall global dependencies
RUN apk add --no-cache git
RUN npm install -g @angular/cli@6.0.8

Now with the command WORKDIR we can create a folder and copy our sources in there with the command ADD

# Copy source
WORKDIR /source
ADD . /source

Running npm install in order to install the Angular dependencies

# Install dependencies
RUN npm install

Buil the image for production environment

# Build
RUN npm run build:prod

Now we can start the second stage of our Docker image from nginx:alpine in order to have a clean image without the source files and the NodeJS overhead

# ----------------------------------
# Prepare production environment
FROM nginx:alpine
# ----------------------------------

Clean the nginx deafult folder

# Clean nginx
RUN rm -rf /usr/share/nginx/html/*

And copy our build files from the stage builder

# Copy dist
WORKDIR /usr/share/nginx/html

COPY --from=builder /source/dist /usr/share/nginx/html

Now we have to copy the nginx.conf file that we will show next

COPY nginx.conf /etc/nginx/nginx.conf

Set the permission to allow nginx to run and provide css files.

# Permission
RUN chown root /usr/share/nginx/html/*
RUN chmod 755 /usr/share/nginx/html/*

Expose the port where nginx is running

# Expose port
EXPOSE 2000

Start the nginx server

# Start
CMD ["nginx", "-g", "daemon off;"]

Here there is the nginx.conf file we used

worker_processes 1;

events { worker_connections 1024; }

http {
    server {
        listen       2000;
        server_name  localhost;
        include /etc/nginx/mime.types;

        location / {
            root   /usr/share/nginx/html;
            index  index.html;
            try_files $uri $uri/ /index.html;
        }

    }
}

Pack it all together

In order to simplify the process we created a Docker image skaffolder/angular6-base to start with, in this images GIT, angular-cli and some dependencies of our version of node_modules (in /source/node_modules) are installed in order to speed up the build process.

This is the complete Dockerfile

# Create image based on the Skaffolder Node ES6 image
FROM skaffolder/angular6-base as builder

# Copy source files
WORKDIR /build 
COPY . /build

# Move source file with node_modules
RUN mv /source/node_modules /build/node_modules

# Install dependencies
RUN npm install

# Build prod
RUN npm run build:prod

# ----------------------------------
# Prepare production environment
FROM nginx:alpine
# ----------------------------------

# Clean nginx
RUN rm -rf /usr/share/nginx/html/*

# Copy dist
COPY --from=builder /build/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf

WORKDIR /usr/share/nginx/html

# Permission
RUN chown root /usr/share/nginx/html/*
RUN chmod 755 /usr/share/nginx/html/*

# Expose port
EXPOSE 2000

# Start
CMD ["nginx", "-g", "daemon off;"]

Build the docker image

In order to build the Docker image let's run:

docker build -t my-image-id .

And push it on the public Docekr repository or our private one.

docker push my-image-id

Publish on Kubernetes

To publish on Kubernetes cluster you have to create it on your provider and connect your local pc to it.

We used Google Cloud with GKE, but the process is the same for all the providers.

We need to create a Kubernetes conf file and execute it.
Let's create my-angular-app.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-angular-app
spec:
  replicas: 1
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        name: my-angular-app
    spec:
      containers: 
        - image: my-image-id
          name: client
          resources:
            limits:
              cpu: 1
              memory: 512M
            requests:
              cpu: 0.1
              memory: 256M}
      restartPolicy: Always
status: {}

And deploy it running kubectl apply -f my-angular-app.yaml

Now you can login in your GKE console and expose the pod creating an ingress.

It will provide you an IP address to access your app :-)

How we used it here at Skaffolder
At Skaffolder we provide an automation tool that provides you code in many programming languages starting from the documentation.
Right now we provide you the code on your GitHub, the next feature will be providing you an application up and running on Kubernetes infrastructure.

We welcome your feedback, reach us on our Slack Channel