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
I have been developing React apps in Docker for a few years now, and so far nothing was able to stop me from…
What is this good for?
A Node.js app can be:
- an Express backend (eg. a REST API)
It is up to you what you make in this environment. I usually do React frontends.
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 with Bash functions. 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
Make your terminal work for you
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:
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.
Docker-compose can fetch the environment variables from a local
.env file. The purpose of this is to avoid repetition in the
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.
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
/code everywhere, I didn't know which project's folder I'm about to open.
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.
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.
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 :)