Running an Angular Application in a Docker Container

Published on

Recently I’ve started using Docker and have become a huge fan. I’ve mainly used it with the development of my side projects and have come to love the benefits of using it.

When it comes to Docker there are quite a few benefits of but some of the primary reasons to choose Docker is that Docker provides portability, predictability, and scalability for your applications. When containerized, an application can be ported to any system regardless of OS as long as it runs Docker and you can expect the application to run in the same consistent manner on all machines/servers. This gives great flexibility and predictability to you applications. Also, if an application requires multiple instances running, spinning up another instance of a Docker image is quick and simple.

For development, using Docker containers can also minimize the differences between dev environments between team members to allow teams to develop against the same versions of applications.

 

Initial Setup

In this post we’ll quickly cover setting up an Angular application and running it in a Docker container with Nginx as our web server. First we need to create an Angular application to use for this demo. Open a terminal and create a new Angular application with the Angular CLI.

ng new angular-docker-example && cd angular-docker-example

From within the root of our Angular application we will need to create two additional files. One will be our Dockerfile used to build our Docker image and the other will be the Nginx configuration that we will provide to our docker container for running Nginx.

touch Dockerfile nginx.conf

 

Configuring NGINX

Our nginx.conf file contains a very basic configuration for serving static files from the root of the nginx default html folder (/usr/share/nginx/html). For more understanding of nginx configuration, you can refer to the official documentation and adjust the nginx.conf as needed.

events{
  
}

http {
    include /etc/nginx/mime.types;
    server {
        listen   80;
        server_name  localhost;
        
        location / {
            alias /usr/share/nginx/html/;
            try_files $uri $uri/ /index.html =404;
        }
    }
}

 

Configuring Docker

Our Dockerfile will have two stages. One stage for building our Angular application which will use the latest node image as the base for a build stage. The second stage will be our nginx environment which will serve our built Angular application.

In Angular you can have multiple environments. When we build our application we want to be able to handle building our image for different environments. We will handle this in our Dockerfile as well….

And our Dockerfile

# Build Stage
FROM node:latest AS build-env
WORKDIR /source
ARG ANGULAR_ENVIRONMENT
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN ng build -c "$ANGULAR_ENVIRONMENT"

# Run Stage
FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf
COPY --from=build-env /source/dist/* /usr/share/nginx/html

EXPOSE 80

 

Build Stage Steps

  • FROM - Here we are setting our base image to use for a build stage. Since we’re building an Angular application we’re using the latest node image.
  • WORKDIR - Set our working directory as /source.
  • ARG - Here we are defining a build argument, ANGULAR_ENVIRONMENT. This allows us to pass in an argument from the docker cli’s build command. In our case we’re passing in an angular environment arg to allow us to build our Angular application for different environments; development, staging, production, etc.
  • COPY - Copy over our package.json and package-lock.json over our working directory.
  • RUN We install the node modules dependencies with npm install to our working directory.
  • COPY - We copy over the rest of our source to the working directory.
  • RUN Now we are running our command to build our Angular application. The Angular CLI has an option for passing a configuration (environment) to build for with the -c option. In our case we’re using our ANGULAR_ENVIRONMENT build arg to tell the command which environment file to use for our build.

Run Stage Steps

  • FROM For our run stage we’re using the latest Nginx image as our base run stage.
  • COPY We copy over our nginx.conf file.
  • COPY We copy over our built Angular application from our build stage to our run stage.
  • EXPOSE We expose port 80 which our nginx server is listening on in our container.

 

Building & Running

We can now build and run our docker image…

export ANGULAR_ENVIRONMENT=development

docker build \
    --build-arg ANGULAR_ENVIRONMENT="$ANGULAR_ENVIRONMENT" \
    -t latest/angular-docker-example \
    -f Dockerfile \
    .

With the first line we are simply setting an environment variable by defining the angular environment we want to build for. In this case we are building for “development”.

The next line we are using docker to build our images, passing in the ANGULAR_ENVIRONEMNT environment variable as our ANGULAR_ENVIRONMENT build arg. We also tagging (-t) our build with a name, and specifying the Docker file name to use for the build with -f. Lastly, we specify the path which in our case will be the current root of the project (.).

We can now run our newly created Docker image with…

docker run \
    --name angular-docker-example \
    -p 8080:80 \
    -d \
    latest/angular-docker-example

We bind our local port 8080 to the docker containers 80 port which our Nginx server is listening on, we give our running image an alias name of “angular-docker-example”, detach from the process, and finally tell the docker command what image to use by specifying the tag we gave our image when we built it, “latest/angular-docker-example”.

So now we can open a web browser and navigate to http://localhost:8080 to view our application running in Docker.

 

Complete github repo can be found here

comments powered by Disqus