Skip to content

Instantly share code, notes, and snippets.

@fxdave
Last active November 23, 2022 15:58
Show Gist options
  • Select an option

  • Save fxdave/a005fc4c10aa853378ee05a66242fb0d to your computer and use it in GitHub Desktop.

Select an option

Save fxdave/a005fc4c10aa853378ee05a66242fb0d to your computer and use it in GitHub Desktop.

In theory, we use dev containers, because, we don't have the same environment locally. If one would develop NodeJs, they shouln't have to install node on their main machine that they use as a daily driver. They only need the image, that has these tools. And the best way to define images is using docker.

Dockerfile is for building an image. Containerd is for starting a process inside one of these images. An isolated process is called as "container". (you can use linux utilities for this, docker is optional) However, docker makes it easy to mount the image and make the image as root of the container.

Imagine that you have a "node:latest" image. You want to use npm for like checking the version. You run this: docker-compose run node npm --version It's clear that you don't need npm install to do this.

So reason 1: unnecessary steps required for running a simple command.

Unfortunately docker is very slow. Docker chaches every line in Dockerfile as a new layer. This results in huge images. It's because if you change one line, it will start from the unchanged lines and builds the rest again. Saves the image again. And the whole process is time consuming. On the other hand containers are very fast, as they are just simple processes. (it's as really fast as linux distros use this to isolate apps from each other.) And if you mount a volume, that will be your native filesystem performance. That's what developers want I think.

So reason 2: slow build time and the need for rebuilding

If you want only one command and the project is up and running for a newly hired colleuge. You have to use shell scripts. Makefile is a popular option for combining simple shell scripts into one file. You need usually manny things to do: install dependencies, init db, run migrations, run seeds, generate new secrets, generate language files, etc... If you include these to every project startup that would be very time consuming, and it could for example remove the users in this example at every run. So I think it's useful to separate the install and the run.

"install:" would do every stuff like: cp .env.sample .env docker-compose run backend npm run migrate && npm run swagger

"run:" is just a "docker-compose up -d" that would just init the containers, so you can continue from where you were yesterday instantly. Or if you stopped the docker daemon to have better fps in CS:GO, you can start it back instantly, without rebuilding it.

If you add a dependency or you checkout a branch. It's useful to have an "update:" script. That reinstalls the dependencies, migrates, without wiping the db. and so on...

You don't want to install more than once, so if you place install script into the Dockerfile, you cannot just docker-compose up --build everytime.

I think it should be up to you to decide whether you rebuild the image with or without the npm install.

So reason 3: you have to have a Makefile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment