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.