Mounting a Docker image with Nginx – Best Practices for Deployment

Until this chapter, we have been using the web server included in the Angular package to run our application locally. Although very competent, it focuses purely on the developer’s experience and does not have the performance and scalability capabilities required by the production environment.

For this purpose, we use production-grade web servers. One of the most popular is Nginx (pronounced Engine X).

To configure it, we need to create a file in the root of our project called nginx.default.conf and add the following to it:
server {
  listen 80;
  sendfile on;
  default_type application/octet-stream;
  gzip on;
  gzip_http_version 1.1;
  gzip_disable      “MSIE [1-6]\.”;
  gzip_min_length   1100;
  gzip_vary         on;
  gzip_proxied      expired no-cache no-store private auth;
  gzip_types        text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
  gzip_comp_level   9;
  root /usr/share/nginx/html;
  location / {
    try_files $uri $uri/ /index.html =404;
  }
}

In this configuration file, the first three properties (listen, sendfile, and default_type) aim to configure the exposed port and prepare the server to send our project’s package files.

The properties starting with gzip configure the delivery of files with the native web compression data gzip, further reducing the files delivered to our user’s browser.

The last part of the file determines the first page to be served. As we are in a Single-Page Application (SPA), the first file to be delivered is index.html.

With this configuration, we can run Nginx, but instead of installing it natively on our local machine, we will use Docker to run it.

Docker is a tool widely used in today’s modern systems and aims to compartmentalize an application’s environment. In other words, by configuring a file, we can create an environment for our application where it can be run both on our local machine and on a cloud provider with the same dependencies and versions.

Let’s exemplify its use by first creating a file called .dockerignore in our project’s root and adding the following to it:
node_modules

Using the .gitignore file as an example, we are ensuring that the node_modules folder will not be copied to the image . Keep in mind that the image and the service that will be run from it (called a container in the Docker ecosystem) is as if it were a new machine and we will only copy what our application needs to run.

The next step is to create the dockerfile file and add the following code to it:
FROM node:18-alpine as build
COPY package.json package-lock.json ./
RUN npm ci && mkdir /gym-app && mv ./node_modules ./gym-app/
WORKDIR /gym-app
COPY .
RUN npm run build
FROM nginx:1.25-alpine
COPY nginx.default.conf /etc/nginx/conf.d/default.conf
RUN rm -rf /usr/share/nginx/html/*
COPY –from=build /gym-app/dist/gym-diary /usr/share/nginx/html
CMD [“nginx”, “-g”, “daemon off;”]

In this file, we are using the multi-stage build technique to create our image. First, we build the application and then use the result of this build to create the final image. This way, our image becomes smaller and more optimized.

The first stage, which we call build here, is based on the node:18-alpine image, which is a minimal image with the Alpine Linux distribution and version 18 of Node.js included.

Then, the package.json and package-lock.json files are copied and the npm ci command is run to install the package.

Then, with the COPY . . command, all project code is copied (except the node_module folder).

At the end of this stage, our application bundle is generated using the npm run build command.

The next stage, which will be production, is based on the nginx:1.25-alpine image because to run the web server, we only need a Linux distribution such as Nginx installed.

The next task is to copy the configuration file for the Nginx installation, delete the example file that comes with the tool, and copy the files generated in the previous stage to this one.

The line [“nginx”, “-g”, “daemon off;”] runs Nginx and makes it ready to deliver our application.

To mount the image, right-click on the dockerfile file in VSCode and select the Build Image option.

To run the Docker container locally, use the following command:
docker run -p 8080:80 gymdiary

By accessing the http://localhost:8080 URL, we have our application running in production mode. Another way to put our project on the web is by using Azure Static Web Apps. We will work on this in the next section.

No Responses

Leave a Reply

Your email address will not be published. Required fields are marked *



Terms of Use | About yeagerback | Privacy Policy | Cookies | Accessibility Help | Contact yeagerback