Quick and dirty Docker development environment for Node.js apps
Dániel Gál
Posted on April 19, 2021
This article is also available on Medium.
Pre-requisites
Files
Usage
Start the environment.
docker-compose up -d
Attach to the container in VSCode.
Enjoy! :)
When done, stop the environment.
docker-compose stop
Why?
I wrote an article on the benefits of using a Dockerized development environment. Check it out here:
9 reasons why you should use Docker as a development environment | by Dániel Gál | Medium
Dániel Gál ・ ・
danielgaldev.Medium
What is this good for?
A Node.js app can be:
- an Express backend (eg. a REST API)
- any JavaScript frontend — React, Angular, Vue
- a CLI app written in JavaScript
- any other type of JavaScript app
It is up to you what you make in this environment. I usually do React frontends.
Tips
When you are attached to the container in VSCode, the IDE's terminal opens a terminal session inside the container. Here you can execute commands directly inside your container without the need to attach to it from another external terminal like PowerShell.
You can reduce the time spent starting and stopping the environment by shortening your Docker commands. If you have multiple concurrent projects, this will save you time and annoyance. I also wrote an article on how to do this, read it here:
Speed up your Docker workflow with Bash functions | by Dániel Gál | Medium
Dániel Gál ・ ・
danielgaldev.Medium
After you opened the dev container once, you can return to it from the "Open recent..." (Ctrl+R) command of VSCode. You don't have to always do the "Attach to running container…" command.
You can extend this bare bones development environment with many different functionalities. I listed my suggestions here.
If you would like to install packages in the container, the best way is to create a Dockerfile, define the install commands inside and change the image
property in the yml to build
with the correct reference to the build context. Here is an example for ffmpeg and the Vercel CLI:
FROM node:14.5.0-alpine
RUN apk add ffmpeg
RUN npm i -g vercel
You could also install Git to get access to the version control tools inside VSCode while you are attached to the container. However, if you want to do version control efficiently inside the container, you will need to set up SSH and configure Git to be able to push your code. It is possible, but I am not a fan because it makes the setup more complex. I do version control on the host system in a separate VSCode window with the IDE's built-in Git tools and the Git Graph extension.
Explained, line-by-line
PROJECT_NAME=my-project
PORT=3000
Docker-compose can fetch the environment variables from a local .env
file. The purpose of this is to avoid repetition in the docker-compose.yml
.
image: node:14.5.0-alpine
I use the Alpine version of the Node image simply because it is small (40 MB compared to the :latest
344 MB). I also use fixed versions to avoid the image upgrading itself and breaking something when I'm in a rush. This way I can upgrade the image when I have the time.
working_dir: /usr/src/${PROJECT_NAME}
You can use any working directory you want inside the container, I just use /usr/src
to avoid name collisions in the root of the filesystem. It also helps me differentiate the projects in VSCode's "Open recent..." menu — back when I used /app
or /code
everywhere, I didn't know which project's folder I'm about to open.
env_file:
- .env
The environment variables defined in .env
will be available inside the container. This is where I put my config options, passwords and secret keys for the app.
ports:
- ${PORT}:${PORT}
There is a high chance I'm building a web app or a REST API, so I map a port of the container to the same port of the host system to be able to access my app or service in the browser.
volumes:
- /usr/src/${PROJECT_NAME}/node_modules
- .:/usr/src/${PROJECT_NAME}
I am mapping the project directory to the container's working directory so that the edits I make in the container propagate to the host system where I do my version control. I don't want the content of node_modules
leaking into my host system however, so I defined that folder as a volume on its own. Otherwise the npm installs would be noticeably slower because the files need to be copied from the container to the host.
entrypoint: tail -F /dev/null
If I would start the container without this entrypoint, it would just exit and I would not be able to attach to it. This command makes the container run indefinitely.
For more advanced devcontainer options visit VSCode's Developing inside a Container article.
Thank you for reading to the end and have a wonderful day :)
Cover photo by Jefferson Santos on Unsplash
Posted on April 19, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.