To deploy an Angular application into Kubernetes, the application needs to be build, containerized and pushed into a container registry before the deployment.

In this project, I want to:

  • Build the Angular Application using Angular CLI
  • Create a new image based on nginx that embeds the result of the angular build
  • Push the image into the GitLab container registry of the project.

The project

For this example, I have created an new GitLab project named “ci-project” and initialised an Angular application using angular-cli into the new repository. My Angular application has the same name (ci-project) as the GitLab project.

Add a Dockerfile to the project

The first step is to add a Dockerfile to define how to build the container.

I use an nginx alpine image as base to serve the static content of the Angular application.

In the root folder of the project, add a Docker file with this content:

# Angular Build Stage
FROM node:current-alpine AS builder
WORKDIR /
COPY . /app
RUN npm install -g @angular/cli
RUN cd /app && npm install 
RUN cd /app && ng build --configuration=production

# Effective Stage
FROM nginx:alpine
COPY --from=builder /app/dist/ci-project /usr/share/nginx/html

The build process contains 2 steps:

  • The build stage: use a node.js alpine image to have the npm tools available during the build process. This step, copy the sources to the build container, install Angular CLI, run npm install to add the packages for the application and run the build using ng build in production mode.
  • The second stage: create the final image for the futur deployment. This stage copy the result of the build from the build container (/app/dist/ci-project) into the public nginx directory of the new container (/usr/share/nginx/html)
Dockerfile

Add the GitLab CI/CD configuration

The second step is to define a GitLab CI pipeline, for that create a .gitlab-ci.yml file in the root folder of the repository.

This file contain only one stage for the build:

stages:
- build

build:
  # Use the official docker image.
  image: docker:latest
  stage: build
  services:
    - docker:dind
  before_script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
  script:
    - docker build --pull -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA" .
    - docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"

  # Run this job where a Dockerfile exists
  rules:
    - if: $CI_COMMIT_BRANCH
      exists:
        - Dockerfile

The before script, connects the build container the the docker registry using the predefined variable of GitLab CI.

In the script step, the new image is built using the Dockerfile previously created.
The predefined gitlab variables are used to define the name of the image and the tag.
The docker push command sends the new image into the Gitlab container registry of the project.

The rules configuration defines when the job should be run:

  • if: $CI_COMMIT_BRANCH: this variable is only available on commit event, the job run on commit only (not for tag or merge)
  • exists: Dockerfile: run only if a dockerfile exists in the current branch. The file name is case sensitive.
gitlab-ci file

Build and debug

In the GitLab project, in the menu, go to Build => Pipelines.

The list of pipeline contains all the run for the project. When a pipeline is completed, the job can be passed or failed. To view the logs of the run, click on the Stages icon.

Pipeline runs

If the job is completed successfully, the image is available in the project registry.
In the GitLab Menu go to: Deploy => Container Registry

Registry view

The image is listed in the container registry and the tag generated is available in the details.