Deploy multi environments with Angular, nginx and Docker

Angular and Docker for beginners

Container ship. Source: Unknown

Prerequisites

  • Installed Docker and Docker compose
  • Already have a Angular application
  • Slight experience about Docker, Angular and Nodejs

Angular environments

As we known that Angular(CLI) provides default 2 environments:

  • Development with environment.ts
  • Production with environment.prod.ts
Here we use Angular CLI application, so all environment files will be in src/environments/

So follow by Angular deployment, if you didn’t hear before you can read this article:

We will run ng build --env=<your-env> --prod --build-optimizer to build (AOT is default with — prod) a Angular application and deploy it.

You may further reduce bundle sizes by adding the build-optimizer flag.

So we can build any Angular application with arg env , example like below:

  • ng build --prod --env=prod --build-optimizer
  • ng build --prod --env=sandbox --build-optimizer
  • ng build --prod (if not provides — env it means use environment.ts file)

Let’s start

Assume our application have 2 stages for deployment is sandbox and prod , our environment will like below:

With environment.sandbox.ts also like above but just change the host property to another value like: https://sb-api.xxx.xxx/api etc..

We will use nginx to deploy Angular application.

Docker and Docker Compose

Firstly, because Angular is SPA so we just need the nginx only and then just serve the static site, that all. But we also need to build Angular application with NodeJS. It’s bad if we use an image that contains both nginx and nodejs. It’s will big docker image.

But fortunately Docker support multi-stage builds so we can use nodejs image build first and then use nginx to serve the site.

And one more thing is build-time variables which will detect we building on what environment. No worries, you can understand when you read the Dockerfile.

  1. Dockerfile

2. package.json

3. nginx.conf

4. Use docker-compose.yml to build and mange services.

Finally, run docker-compose up --build -d to build and start these services.

The result will be like below:

Building sandbox.web
Step 1/14 : FROM node:alpine as builder
---> 166e2eca249b
Step 2/14 : ARG env=prod
---> Using cache
---> 990ada0b85cd
Step 3/14 : RUN apk update && apk add --no-cache make git
---> Using cache
---> f02f8e0a2fc5
Step 4/14 : WORKDIR /app
---> Using cache
---> 133b0ba0ffe6
Step 5/14 : COPY package.json package-lock.json /app/
---> Using cache
---> d853be32dc3e
Step 6/14 : RUN cd /app && npm install
---> Using cache
---> 4cce259d36ef
Step 7/14 : COPY . /app
---> Using cache
---> a81b3b9f742c
Step 8/14 : RUN cd /app && npm run build:$env
---> Using cache
---> 12c9f710a16f
Step 9/14 : FROM nginx:alpine
---> 920e5c5c8bed
Step 10/14 : RUN rm -rf /usr/share/nginx/html/*
---> Using cache
---> c1a1aaceebd8
Step 11/14 : COPY nginx.conf /etc/nginx/nginx.conf
---> Using cache
---> a99d4fa4ff25
Step 12/14 : COPY --from=builder /app/dist /usr/share/nginx/html
---> Using cache
---> 077232e62422
Step 13/14 : EXPOSE 80
---> Using cache
---> 0b7a2c0fae0e
Step 14/14 : CMD ["nginx", "-g", "daemon off;"]
---> Using cache
---> 3b7d2d72a304
Successfully built 3b7d2d72a304
Successfully tagged clientnew_sandbox.web:latest
Building app.web
Step 1/14 : FROM node:alpine as builderStep 1/14 : FROM node:alpine as builder
---> 166e2eca249b
Step 2/14 : ARG env=prod
---> Using cache
---> 990ada0b85cd
Step 3/14 : RUN apk update && apk add --no-cache make git
---> Using cache
---> c5d665d648ee
Step 4/14 : WORKDIR /app
---> Using cache
---> bafb1fe6f021
Step 5/14 : COPY package.json package-lock.json /app/
---> Using cache
---> 7067697ec902
Step 6/14 : RUN cd /app && npm install
---> Using cache
---> 05d5e0b9d753
Step 7/14 : COPY . /app
---> Using cache
---> 78bc469ba13e
Step 8/14 : RUN cd /app && npm run build:$env
---> Using cache
---> e22a74e7377f
Step 9/14 : FROM nginx:alpine
---> 920e5c5c8bed
Step 10/14 : RUN rm -rf /usr/share/nginx/html/*
---> Using cache
---> c1a1aaceebd8
Step 11/14 : COPY nginx.conf /etc/nginx/nginx.conf
---> Using cache
---> a99d4fa4ff25
Step 12/14 : COPY --from=builder /app/dist /usr/share/nginx/html
---> Using cache
---> 0c5821e7ab94
Step 13/14 : EXPOSE 80
---> Using cache
---> 198df99d13e8
Step 14/14 : CMD ["nginx", "-g", "daemon off;"]
---> Using cache
---> 1eb22527bd39
Successfully built 1eb22527bd39
Successfully tagged clientnew_app.web:latest
clientnew_sandbox.web_1 is up-to-date
clientnew_app.web_1 is up-to-date

Any questions you can comment below, thanks for reading. 🤗