Lewislbr

Using Docker for development with a frontend application

Using Docker for development has several advantages, the main one being that we can run the application in a static environment, free from our own computer quirks and versions, so we can develop in the exact environment we need. For instance, if we replicate the production environment during development, it gives us confidence that the application will behave the same in that environment. This becomes even more important when working with other developers, as each one can have a different operating system, runtime versions, and so on, so it gives us the ability to run the same application with the same conditions everywhere.

Nowadays, to run a Node.js-based frontend application in development means dealing with the folder node_modules, a folder where all the application's dependencies and the dependencies of the dependencies are stored. This folder is used by the application itself and the IDE to use by extensions.

The common way of building a docker container implies having the node_modules folder in the container but not in the host, so we don't have it for the IDE, breaking the development experience. Some workarounds exist like copying the folder to the host every time, but it's a long process.

A workaround to solve that is to mount the application directory in the container directly, so the host and the contaienr will share the same node_modules folder.

Imagine we have a web folder where our frontend application is located. We can start by creating a simple Dockerfile named Dockerfile.dev to be used during development:

FROM node:14-alpine
RUN apk add --no-cache g++ make python
WORKDIR /usr/src/app
ENV NODE_ENV=development
CMD [ -d "node_modules" ] && npm run start || npm ci -q && npm run start

And in the parent folder, we can create a docker-compose.yaml file to configure it to build a container that will be accessible on port 3000 with the web folder mounted into it:

version: "3.8"

services:
  web-app:
    build:
      context: web
      dockerfile: web/Dockerfile.dev
    image: web-app:dev
    container_name: web-app
    ports:
      - "127.0.0.1:3000:3000"
    volumes:
      - ./web:/usr/src/app

Now by running docker-compose up -d --build we can initialize the application with Docker, and it will install the dependencies if no node_modules folder is found. If the folder exists, it will skip the installation and just start the application, saving quite some time.

Whenever we need to reinstall dependencies, we can just delete node_modules and they will be automatically reinstalled when running the Docker Compose command.



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.