Create a small and secured Angular Docker image based on nginx

When we are building a docker Image, the first idea is using the default official image.

FROM node
FROM golang
FROM nginx
FROM openjdk

Angular is often associated with Node.js server (at least for development).
There is an official Docker image for Node.js.

$ docker image list | grep node | grep latest
node latest 1f72742acfa2 4 days ago 677MB

Ouch 677 MB just for an empty image … this is crazy 😾

There is lightweight Alpine Docker image for Node.js.

Check the Alpine linux page for more informations.

FROM node:alpine

This is 10x smaller but too large for a production image with nothing

$ docker image list | grep node | grep alpine
node alpine b5f94997f35f 4 days ago 68.4MB

Use Multi-stage builds

Thanks to docker multi-stage builds, we can build our application in a docker alpine image an produce a small image with only a binary in a scratch image.

OK, it’s time to build a smaller image with multi-stage build based on nginx

Before that we gonna see docker nginx image, only 16.8MB image. Perfect for our static website.

# STEP 1 build static website
FROM node:alpine as builder
RUN apk update && apk add --no-cache make git
# Create app directory
# Install app dependencies
COPY package.json package-lock.json Makefile /app/
RUN cd /app && npm set progress=false && npm install
# Copy project files into the docker image
COPY . /app
RUN cd /app && npm run build

# STEP 2 build a small nginx image with static website
FROM nginx:alpine
## Remove default nginx website
RUN rm -rf /usr/share/nginx/html/*
## From 'builder' copy website to default nginx public folder
COPY --from=builder /app/dist /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]

Oh cool only 28.2MB with everything i need for my angular app.

$ docker image list
site latest bbab7aea4567 2hours ago 28.2MB

Let’s build a more secure docker image

Just some reminders :

  • Run only one process in a container.
  • Never run a process as root in a container.
  • Never store data in a container, do it in a volume
  • Never store credentials in a container, do it in a volume
  • Keep your image up to date
  • Verify third-party container repositories
  • Use tool like docker-security-scanning
  • May the force be with you 🙏

If you want to run docker as non root

If you have any advice about security, please let me know :)