Design by: Vivian Bierhuizen

How to set up an Angular CLI project with Docker Compose

Onno de Jong
5 min readApr 15, 2019

--

Introduction

In this post I would like to give a quick introduction about how to get your Angular project running in Docker. When developing our application locally, the expectation is that the container will reload our new application just like you are used to when developing locally.

This solution will work on existing angular projects as well as on new projects.

We will start of with creating a Dockerfile and use the Docker Compose tool to run our service.

What are we going to do

This post will guide you all the way from creating an Angular project with the CLI to a Docker setup, including reload on file changes.

In order to do so, we need the following prerequisites as displayed bellow.

  • Node 8+
  • Angular CLI
  • Docker V18+
  • Preferably a Linux OS, but Mac will do as well. I won’t encourage Windows.

Installing Node on your machine

This post won’t cover how to install Node, but here is a link to the official download page.

https://nodejs.org/en/download/

Installing the Angular CLI

The first step is to install the Angular CLI on your local machine. The Angular CLI is the command line interface that provides multiple useful tools including creating new projects, components and services.

npm install -g @angular/cli 

Create a new project

Create a new project.

ng new angulardockerproject

navigate to the project folder.

cd angulardockerproject

The Dockerfile

To run a Docker container we need an image. This image is defined in a Docker file.

In the Docker file we can use the following instructions:

FROM,WORKDIR ,COPY, RUN, ENV, EXPOSE, CMD

Docker then, will read these instructions to build a Docker container, but we’ll get to that later.

Lets create one in the project folder.

touch Dockerfile

Within this Dockerfile, we will define the Docker image. In order to do this we need to add a starting point, which is another image. To define a starting point we use the FROM instruction, followed by the image we would like to use.

To use an empty image we could use “FROM scratch”, but we will use the Node:8 image because that is exactly what we need for our Angular environment.

# This defines our starting point
FROM node:8

Amazing, we’ve defined our starting point. Let’s define an instruction to create a working directory for our app. First we need to create a directory with the RUN instruction, after that we will make that our working directory using the WORKDIR instruction.

RUN mkdir /usr/src/app 

WORKDIR /usr/src/app

Now we have defined our directory, we are ready to install the Angular CLI, lets do that right away. The node image provides us with NPM, which means we can install NPM packages with the RUN command.

RUN npm install -g @angular/cli 

The next thing we need to do is to copy our Angular application to our Docker instance. We can do that using the COPY instruction. The copy instruction uses two paths as parameters similar to the CP command.

COPY . . 

That’s it, that is the Dockerfile for now. It is the bare minimum but it should be enough for our example.

Lets test our Dockerfile by building it.

docker build -t testimage .

To see our image(s) we can use the following command.

docker images

For now, we will remove our image again. Because we are going to build our image with Docker compose. Removing the image is simple, check your IMAGE ID that you can see in the Docker image output.

Image id’s look like this: d304814c7120

docker image rm <your image id>

The docker-compose file

A Docker file is enough to build, but we want to be able to start multiple containers with one file. For example, if we also want to add our Node Express back-end application and our database which all contain their own Dockerfile, we could manage them within a single configuration.

This is where we can use the docker-compose tool.

Docker compose is a tool which reads a docker-compose YAML file to start your application services.

Lets create one outside our Angular project folder.

cd ../
touch docker-compose.yml

A Docker compose file starts of with the version of the configuration file that we are going to use.

version: '3.5'

Below the version we start defining our services. Our service will be called angular-service.

Here we also need to define the container name we generate with the CONTAINER_NAME instruction and the build location of our Dockerfile with the BUILD instruction.

Next we map our volumes from our local directory to the directory that we make in our environment with the VOLUMES instruction.

Then we specify on which port we want to run our application and what port we have exposed in our Dockerfile with the PORTS instruction.

version: '3.5' # We use version 3.5 syntax
services: # Here we define our service(s)
angular-service: # The name of the service
container_name: angularcontainer # Container name
build: ./angulardockerproject # Location of our Dockerfile
volumes: # Volume binding
- './angulardockerproject:/usr/src/app'
ports:
- '4200:4200' # Port mapping
command: >
bash -c "npm install && ng serve --host 0.0.0.0 --port 4200"

The COMMAND instruction is a way to instruct Docker to run npm install and ng serve. This is one way to do it, I will use this example for now but there are other ways to install the node packages and run the application.

The following command opens bash in the running container:

docker exec -i -t container_name /bin/bash

In this container you could also install the node packages and serve the application.

Run docker compose

Run the docker-compose.yml file by the following command. We use the build parameter to build the image we defined in our Dockerfile if it not exists already. I like to use the -d parameter to run docker in the background.

docker-compose up --build -d

How to monitor what is happening

To see which Docker containers are running, we can run.

docker ps

To see all of the images that are built.

docker images

To stop a container, we can use.

docker container stop angularcontainer

Conclusion

In this document we learned how to create a Dockerfile to define our image(s). How to use docker compose to run our container and we learned how to monitor our running containers.

--

--