0

Please follow this reasoning and tell me where I am wrong.

  • I want to develop a web app with Typescript. This is the folder structure:
src
- index.ts
package.json
tsconfig.json
  • I want to compile and run the app inside a container so that is not environment-dependent.

  • I run docker build --name my_image with the following Dockerfile in order to create an image:

FROM node:16
WORKDIR /app
COPY package.json /app
RUN npm install
CMD ["npx", "dev"]
  • This will create a node_modules folder inside the container.

  • Now I create a container like so:

docker create -v $(pwd)/src/:/app/src my_image --name my_container
  • I created a volume so that when I change files in my host /src I will change also the same files in the container.

  • I start the container like so:

docker start -i my_container
  • Now everything is working. The problem, though, are the linters.

  • When I open a file with my text editor from the host machine in /src the linter are not working because there is no node_modules installed on the host.

If I npm install also on the host machine I will have 2 different node_modules installation and there might be some compilation that differ between the host and the container.

Is there a way to point the host node_modules to the container node_modules?

If I create a docker volume for node_modules like so

docker create -v $(pwd)/node_modules:/app/node_modules ...

I will delete all the compilation done in the container.

What am I doing wrong?

Thank you.

47ndr
  • 583
  • 5
  • 23
  • everything you run inside docker only exists inside that container. I'm not clear why you think it would update your local machine. If you use a volume then the docker container reads the files from your machine. Beyond that, I'm not clear what your trying to achieve. Why don't you just run `npm install` locally then copy the whole lot into docker? – Liam Jan 04 '22 at 12:10
  • 2
    Some node modules depend on the operation system and for this reason I would not share the node_modules folder. Simply develop on your local system and deploy the result as a docker image. – Christoph Lütjen Jan 04 '22 at 12:10
  • *so that is not environment-dependent* it's still environment dependant. If you have a linux container it'll be linux, if it's a windows container it'll be windows. There is nothing magic happening here. – Liam Jan 04 '22 at 12:12
  • @Liam because the compilation made on the local might be different between machines. If you are working within a team I cannot make `npm install` on different machines and than copy to the container. – 47ndr Jan 04 '22 at 12:13
  • 1
    Well that's what CI/CD is for. I think you're very confused as to what's actually going on here – Liam Jan 04 '22 at 12:14
  • @ChristophLütjen If I develop on my local machine, my compilation will be different than my colleague compilation. The compilation must be done inside a container. – 47ndr Jan 04 '22 at 12:15
  • @Liam please tell me more about it. How can I solve it? – 47ndr Jan 04 '22 at 12:17
  • "my compilation will be different" - not really. You define all settings/scripts in package.json / tsconfig.json / ... that works well even with large teams. For production builds you use CI as Liam already commented. This will run npm install, run tests, do a production build and copies the result in a docker image. Done. Using containers for development can make sense if people switch a lot between different languages and you want to ensure they don't have to install the language specific tooling for each ecosystem. But in most cases this is simply not a real life problem. – Christoph Lütjen Jan 04 '22 at 12:26
  • @ChristophLütjen So in general you are telling me not to compile the code inside the container. But let say I am compiling on Node:14 and my colleague is compiling on Node:16 and for some reason one it is not compatible with the other. How would you solve it? Isn't it better to compile both inside a container that has the same Node version? So you will be sure the compiled code will be the same. – 47ndr Jan 04 '22 at 12:30
  • Simply restrict the node version in package.json https://stackoverflow.com/questions/29349684/how-can-i-specify-the-required-node-js-version-in-package-json - more relevant than the node version is what language level is allowed and this is defined in package.json too and does not depend on your node version. – Christoph Lütjen Jan 04 '22 at 12:35
  • "not to compile the code inside the container" you can do the compile part in a container and that makes sense if you have a lot of dependencies that you cannot define in your package.json - then you would npm install on the local machine for the editor and do the same inside your container for the build / dev server. It's just more complicated and does not solve a real pain in most cases. – Christoph Lütjen Jan 04 '22 at 12:46
  • I understand your point. I actually managed to make the compilation work inside the container. However my only problems are the linters of the text editor. It would be nice if there was a way to point file inside the container so that the linter will point to the compiled code inside the container. – 47ndr Jan 04 '22 at 12:52
  • 1
    "that the linter will point to the compiled code inside the container" - Linters do not work on the compiled files but on the source files. – Christoph Lütjen Jan 04 '22 at 12:54
  • 1
    Does this answer your question? [Sharing the \`node\_modules\` folder between the container and the host](https://stackoverflow.com/questions/57628844/sharing-the-node-modules-folder-between-the-container-and-the-host) – Christoph Lütjen Jan 04 '22 at 12:56

1 Answers1

0

For those who might have a similar problem, this is what I have done and it is working.

First I build an image:

docker build --name my_image .

Then I copy the node_modules folder from a temporary container to my local folder:

docker create --name tmp_container my_image
docker cp tmp_container:/app/node_modules ./node_modules
docker rm tmp_container

Then I create the final container with a volume:

docker create -v $(pwd)/node_modules:/app/node_modules --name my_container my_image

And now I have a exactly what it has built and compiled in the container but also in my local folder.

This can be of course extended to any folder with build artifacts. For example in my case I needed also another folder in order to make the linters work in my text editor. I just copy the folder exactly like I did with node_modules.

47ndr
  • 583
  • 5
  • 23