Open hirosat opened 1 year ago
The directory structure of the container at build time is created with uid1001
, but the actual user is cnb(uid1002
), which seems to cause problems when writing a file such as .eslintcache
after startup.
$ docker exec -it 9c925c0c6253 bash
cnb@9c925c0c6253:/workspace$ id
uid=1002(cnb) gid=1000(cnb) groups=1000(cnb)
cnb@9c925c0c6253:/workspace$ ls -al
total 732
drwxrwxrwx 6 1001 cnb 4096 Jan 1 1980 .
drwxr-xr-x 1 root root 4096 Oct 24 15:51 ..
-rw-r--r-- 1 1001 cnb 27 Jan 1 1980 .env
drwxr-xr-x 7 1001 cnb 4096 Jan 1 1980 .git
-rw-r--r-- 1 1001 cnb 2230 Jan 1 1980 .gitignore
-rw-r--r-- 1 1001 cnb 3359 Jan 1 1980 README.md
drwxr-xr-x 3 1001 cnb 4096 Jan 1 1980 build
lrwxrwxrwx 1 1001 cnb 69 Jan 1 1980 node_modules -> /tmp/4d6b8328f31f0ade280f708051b532cf52e67649547d1c558ce7df2ecb94a806
-rw-r--r-- 1 1001 cnb 698792 Jan 1 1980 package-lock.json
-rw-r--r-- 1 1001 cnb 821 Jan 1 1980 package.json
drwxr-xr-x 2 1001 cnb 4096 Jan 1 1980 public
drwxr-xr-x 2 1001 cnb 4096 Jan 1 1980 src
-rw-r--r-- 1 1001 cnb 130 Jan 1 1980 start.sh
9c925c0c6253:/workspace$ ls -al /workspace/node_modules/.cache/.eslintcache
-rw-r--r-- 1 1001 cnb 1089 Jan 1 1980 /workspace/node_modules/.cache/.eslintcache
@hirosat Thanks for the for the perfect steps to reproduce :)
For bionic
, the build und the run user were the same (uid 1000). This changed with jammy
and the build (uid 1001) and the run user (uid 1002) are different. Unfortunately, no writable .cache
folder exists, so when eslint
tries to create it, it fails due to permission.
workaround: You could run the container with the build user, e.g. docker run -u 1001 -p 3000:3000 test-jammy:latest
possible solution: It sounds to me as if a .cache
folder should already exist and it should be writable for the group cnb
. I will look into this.
@c0d1ngm0nk3y Thank you for your reply! Your explanation was very helpful. However, if the expected run user is cnb (uid 1002), is it possible to change the directory's owner to the last step of the builder process, like the following?:
$ chown -R 1002 /workspace
Or it would be more appropriate if the build user could also be configured with id1002.
@hirosat Having the whole workspace writable for the run user would somehow be against the original idea of using different users for build and run in the first place.
Although, the same problem should occur when using a r/o root file system. The question is WHY eslint
needs to run at runtime and not only at buildtime. Is it not "only" a linter?
Another question, you can help me with. How/when did you decide to change from bionic
to jammy
. Because I think the usage of bionic
is quite hidden and we could/should help there.
@c0d1ngm0nk3y
Having the whole workspace writable for the run user would somehow be against the original idea of using different users for build and run in the first place.
I think the actual problem is that the runuser is not an expected user ID
.
I suggested chown
than chmod
because where it is writable is not a current issue.
Although, the same problem should occur when using a r/o root file system. The question is WHY eslint needs to run at runtime and not only at buildtime. Is it not "only" a linter?
Usecases for react:
For development, it is likely to use npm start
on the local environment
to start the Webpack Dev Server and enable real-time debugging. The eslint is used in this case, and a cache is written to re-test based on changes in the source code.
For production, it is likely to use npm build
to render static files and copy these files to a web server, such as apache or nginx.
Why: To share a prototype frontend code with others, it is preferable to be able to build by using a development way, rather than preparing such a web server. Essentially, eslint is unnecessary in such cases, but it is a pain to consider a workaround for it. BTW, I'm not sure "only" a linter is need writeble.
Another question, you can help me with. How/when did you decide to change from bionic to jammy. Because I think the usage of bionic is quite hidden and we could/should help there.
I was decided by using pack builder suggest
.
Previously bionic(paketobuildpacks/builder:base) was suggested and a few months ago it was changed to jammy.
Thanks for the explanation.
Having the whole workspace writable for the run user would somehow be against the original idea of using different users for build and run in the first place.
I think the actual problem is that the runuser is not an
expected user ID
. I suggestedchown
thanchmod
because where it is writable is not a current issue.
Actually i do think that the run user has the expected user id and the node_modules
do not have the permissions to be changed by the run user (only by build user).
The permissions of these symlinks in between might be confusing.
cnb@6242c05f0a37:/workspace$ id
uid=1002(cnb) gid=1000(cnb) groups=1000(cnb)
cnb@6242c05f0a37:/workspace$ ls -la node_modules
lrwxrwxrwx 1 1001 cnb 69 Jan 1 1980 node_modules -> /tmp/4d6b8328f31f0ade280f708051b532cf52e67649547d1c558ce7df2ecb94a806
cnb@6242c05f0a37:/workspace$ ls -la /tmp/4d6b8328f31f0ade280f708051b532cf52e67649547d1c558ce7df2ecb94a806
lrwxrwxrwx 1 cnb cnb 65 Oct 31 08:31 /tmp/4d6b8328f31f0ade280f708051b532cf52e67649547d1c558ce7df2ecb94a806 -> /layers/paketo-buildpacks_npm-install/launch-modules/node_modules
cnb@6242c05f0a37:/workspace$ ls -la /layers/paketo-buildpacks_npm-install/launch-modules
total 52
drwxr-xr-x 5 1001 cnb 4096 Jan 1 1980 .
drwxr-xr-x 3 1001 cnb 4096 Jan 1 1980 ..
drwxr-xr-x 2 1001 cnb 4096 Jan 1 1980 env.launch
drwxr-xr-x 2 1001 cnb 4096 Jan 1 1980 exec.d
drwxr-xr-x 854 1001 cnb 36864 Jan 1 1980 node_modules
Although, the same problem should occur when using a r/o root file system. The question is WHY eslint needs to run at runtime and not only at buildtime. Is it not "only" a linter?
Usecases for react: For development, it is likely to use
npm start
on thelocal environment
to start the Webpack Dev Server and enable real-time debugging. The eslint is used in this case, and a cache is written to re-test based on changes in the source code. For production, it is likely to usenpm build
to render static files and copy these files to a web server, such as apache or nginx.Why: To share a prototype frontend code with others, it is preferable to be able to build by using a development way, rather than preparing such a web server. Essentially, eslint is unnecessary in such cases, but it is a pain to consider a workaround for it. BTW, I'm not sure "only" a linter is need writeble.
Thanks for the explanation. Yes, I agree that this seems not to be specific to eslint
. I was just wondering why a linter comes up in this.
Another question, you can help me with. How/when did you decide to change from bionic to jammy. Because I think the usage of bionic is quite hidden and we could/should help there.
I was decided by using
pack builder suggest
. Previously bionic(paketobuildpacks/builder:base) was suggested and a few months ago it was changed to jammy.
Thanks.
Maybe I misunderstood. So you are intentionally making node_modules read-only and intentionally mounting them as a different user? In general, I thought that node_modules is an area that can be managed by the user(cnb), so what is the reason for making it read-only like that?
Got it.
The idea of splitting the run and build user is originated here.
@paketo-buildpacks/nodejs-maintainers Having a group writable node_module
folder doesn't sound right to me. Why should the run user want/need to change it. It is an image after all. WDYT?
But the node_nodules/.cache
folder is a bit different and seems to be standard to be used. Any concerns in making is group writable?
I guess this use case will just not work with a readonly root filesystem, but I don't see a chance.
Now I understood the background. Thank you for your kindly explanation.
Yes. I would be happy if you could make the group writable for all configurations under the node_nodules/.cache
directory, at least in this case.
Thank you in advance.
@c0d1ngm0nk3y Would you fix it to close this ticket?
@c0d1ngm0nk3y Any updates?
@hirosat Sorry for the VERY late reply :( I created a draft pr for the fix, I just wanna check the approach with the maintainers first before I clean the pr up.
But basically, the build
would always create the .cache
folder as symlink to tmp
, so it would work for a different user as well as when a read-only
file-system is used.
Fixed with the next release of npm-install
/nodejs
buildpack
Expected Behavior
We can run the container without permission trouble in case using React APP (npm start for development). As a successful example, I will show the case of using bionic based builder.
Current Behavior
Failed to run the container with permission trouble when using Jammy based builder.
I guess #278 may be related.
Possible Solution
I will probably go back to bionic based builder for a while for React development. However, bionic is not good for a security perspective. So I hope this issue will be fixed.
Steps to Reproduce
Motivations
I think it's a very basic scenario when we develop React App. If we can't do it, we need to go back dockerfile.