Austin, Code, Life...

Tags


Developing Angular Applications with Docker Containers

1st June 2018

With microservice architectures, often times it is benefitial to develop you Angular applications from within Docker. Placing an Nginx proxy in front of your docker container can provide you with clean portless urls and ssl - making integration with services like Auth0 more natural.

In this article, I will show you how to work locally while serving your Angular application from within docker.


Docker

We will leverage both Docker and Docker Compose for this project.

Dockerfile

In order to increase the build times, we will be leveraging a docker cache layer based on the contents of the node package.config. This will prevent the build from having to pull down all of the node_modules files every time. The only time the layer will need to be refreshed is if you add or update an npm package.

Additionally, we will use the environment variable ENABLE_POLLING for Windows development machines that do not support File System Events.

FROM node:10

LABEL Maintainer = Christopher Town 
LABEL Name = Docker Angular App

# #############################################################################
# Cache layer with package.json for node_modules 
#
ADD package.json package-lock.json ./tmp/
RUN cd /tmp && npm i npm@latest -g && npm install && npm i -g nodemon
RUN mkdir -p /home/app/angular-app && cp -a /tmp/node_modules /home/app/angular-app

# #############################################################################
# Application Code
#
COPY . /home/app/angular-app

# #############################################################################
# Expose
#
WORKDIR /home/app/angular-app
EXPOSE 4200

# #############################################################################
# Start dev server with polling for Windows
# 
ENTRYPOINT ["/bin/bash", "-c", "if [ \"$ENABLE_POLLING\" = \"enabled\" ]; \
then npm run start:docker:poll; else npm run start:docker; fi"]

Dockerfile

docker-compose

The docker compose configuration maps the application source in the container to the local development folder via a volume. This will allow ng serve to detect changes and dynamically reload your application.

version: '3'
services:

  docker-angular-app:
    image: docker-angular-app
    build:
      context: .
      dockerfile: Dockerfile
    container_name: docker-angular-app
    environment:
      - ENABLE_POLLING=${ENABLE_POLLING}
      - VIRTUAL_HOST=web.mydomain.com
    ports:
      - "4200:4200"
    volumes:
      - ./src:/home/app/angular-app/src
    working_dir: /home/app/angular-app
    networks:
      - dev-network
    tty: true
    stdin_open: true

networks:
  dev-network:
    driver: bridge
docker-compose.yml

The VIRTUAL_HOST variable is used to support loading your container behind an nginx ssl proxy. Check out the post Clean Development URLs and SSL with Docker and Nginx Proxy for more info.


Node Tasks

In order to support containers and polling, the following tasks are used:

{
  "name": "docker-angular-app",
  "version": "0.0.0",
  "scripts": {
    "start": "ng serve --host 0.0.0.0 --port 4200",
    "start:docker": "ng serve --host 0.0.0.0 --port 4200 --configuration=container",
    "start:docker:poll": "npm run start:docker -- --poll 1000"
  }
}
package.json


Visual Studio Code Tasks

To streamline launching and debugging your application in a container, we'll add some VS Code tasks and debug launchers.

Tasks.json

The compose task will help build and compose the docker container.

{
    "label": "compose",
    "type": "shell",
    "osx": {
        "command": "bash ./scripts/project-tasks.sh compose"
    },
    "presentation": {
        "echo": true,
        "reveal": "always",
        "focus": true,
        "panel": "dedicated"
    },
    "problemMatcher": [],
    "windows": {
        "command": ".\\scripts\\project-tasks.ps1 -Compose"
    }
}
tasks.json

Launch.json

The docker launch debugger will call the compose task to create your container and then launch Chrome with the debugger attached. This will allow you to set breakpoints in you Angular application - even when running in the container.

{
    "name": "Docker Launch",
    "request": "launch",
    "preLaunchTask": "compose",
    "type": "chrome",
    "url": "http://localhost:4200",
    "webRoot": "${workspaceFolder}"
}
launch.json


Helper Scripts

Two helper scripts, project-tasks.sh and project-tasks.ps1, have been added to orchestrate the management of your containers. You can read more about them in the web series, Orchestrating Visual Studio Code.


Source Code

https://github.com/christophla/blog-docker-angular

Software/DevOps Architect based in Austin, Texas living on tacos and code.

View Comments