Deploy a frontend application with nginx and Docker

Once we have a bundled frontend application ready to publish, we can put it in the Internet in many ways. A highly versatile one is to use nginx and Docker.

Configure nginx

We can start by creating an nginx.conf configuration file for nginx that will define how our application is served:

server_tokens off;

server {
    listen 80;
    listen [::]:80;

    root /bin/www;
    index index.html;

    add_header Referrer-Policy "strict-origin-when-cross-origin";
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
    add_header X-Content-Type-Options "nosniff";
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";

In this file, we specify the port and path where our files will be served, what file acts as the entrypoint, and declare some HTTP headers. Ideally, we would configure it for HTTPS and HTTP/2, but that is another topic.

Configure Docker

We can then Dockerize the application for production with the following Dockerfile:

FROM node:14-alpine as builder
RUN apk add --no-cache g++ make python
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci
COPY . ./
ENV NODE_ENV=production
RUN npm run build

FROM nginx:stable-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /usr/src/app/dist /bin/www
CMD [ "nginx", "-g", "daemon off;" ]

Here we create a builder step that will take care of building the application for production, and then we create another step to copy the result of that build process (basically a dist or similar folder) and have it served by nginx. This will result in a small Docker image with only the essential code.

From here, we can upload the image to some cloud provider or virtual machine and run a container to make the application available online.

If you're using dark mode, do you like the code blocks's theme? I have it available for VS Code, feel free to check it.