GoogleContainerTools / jib

🏗 Build container images for your Java applications.
Apache License 2.0
13.68k stars 1.44k forks source link

Unnecessary overwrites of directories, resulting changes to owners and permissions #1270

Open chanseokoh opened 5 years ago

chanseokoh commented 5 years ago

The way we took to fix #727 and #523 was to add TAR archive entries to enumerate all parent directories of any given file and explicitly set permissions for those parent directories: PR #891. The consequence is that owner:group is always reset to root:root and the permission mode 755 for all the directories involved.

So, let's say I have a base Tomcat image where the owner:group and the permission of /usr are 12345:54321 and 750:

$ docker run --rm -it --entrypoint ls francium25/base-tomcat -ld /usr
drwxr-x---    1 12345    54321         4096 Sep 12 20:50 /usr

Now, if Jib builds an image where /usr is one of the parent directories of my <appRoot>,

          <from><image>francium25/base-tomcat</image></from>
          <container>
            <appRoot>/usr/local/tomcat/webapps/ROOT</appRoot>
          </container>

the owner and the permission are reset (to the values we chose).

$ docker run --rm -it --entrypoint ls my-image -ld /usr
drwxr-xr-x    1 root     root          4096 Jan  1  1970 /usr

It will be ideal to not touch the owners and permissions of existing directories.

Also note that <appRoot> and its parent directories will always be root:root and 755.

chanseokoh commented 5 years ago

But I understand the way we reset the permissions, which resolves #727 and #523. So I'd say this issue is a low priority that we may not fix until there is a real need.

unautre commented 4 years ago

Hello, I think I just encountered this problem: I am building a docker image for a war on a custom wildfly image ; the app is put in the /opt/jboss/wildfly/standalone/deployments/ folder, and thus chown/chmoding all parent folders to root:root/755... The final image is not able to start as non-root because of that.

Is there any change this bug might end up corrected, despite being low priority ? Or is there any workaround ?

loosebazooka commented 4 years ago

If you control you base image, maybe you can control this using some sort of symlink? Are you using a standard jboss image?

unautre commented 4 years ago

Maybe I misunderstood your comment, how would symlinks help with permissions ?

I am not using a standard jboss image, but close (we rebuilt it with minor tweaks).

A possible workaround would be pushing the exploded war somewhere else (appRoot configuration), and copy it at container start time using a custom entrypoint ; then I would be able to control permissions better.

Edit: oh wait, did you mean putting the appRoot somewhere else, and symlinking wildfly deployment to it ? That's a great idea ! I'll try that tomorrow.

Thanks @loosebazooka !

loosebazooka commented 4 years ago

Yeah either symlinking the directory , or a war file (didn't realize exploded war)?

unautre commented 4 years ago

Hello @loosebazooka ,

(didn't realize exploded war)?

Yes. I don't know if it's a bug or not, but if I try to configure packaged, JIB gives the following:

Execution default-cli of goal com.google.cloud.tools:jib-maven-plugin:1.8.0:dockerBuild failed: packaged containerizing mode for WAR is not yet supported

chanseokoh commented 4 years ago

Execution default-cli of goal com.google.cloud.tools:jib-maven-plugin:1.8.0:dockerBuild failed: packaged containerizing mode for WAR is not yet supported

Don't set <containerizingMode>packaged for a WAR project. Jib already takes a packaged .war file, unzips it, and places the exploded contents into <appRoot>.

And double-check if your issue is really from the ownership problem or the permissions problem. We've seen a lot of people mistakenly jumped into their conclusion without knowing that root:root with 755 is already globally readable/accessable and the actual cause of the issue was a different one. See https://github.com/GoogleContainerTools/jib/issues/1257#issuecomment-570309755

If 755 doesn't work for you, it probably means that your application is trying to mutate <appRoot> or any of the parent directories leading to it at runtime. That's a red flag, and you should avoid that. Look into the linked issue above to get a better idea.

unautre commented 4 years ago

Hello @chanseokoh,

Execution default-cli of goal com.google.cloud.tools:jib-maven-plugin:1.8.0:dockerBuild failed: packaged containerizing mode for WAR is not yet supported

Don't set <containerizingMode>packaged for a WAR project. Jib already takes a packaged .war file, unzips it, and places the exploded contents into <appRoot>.

So, that means that WAR can only be in exploded mode ?

And double-check if your issue is really from the ownership problem or the permissions problem. We've seen a lot of people mistakenly jumped into their conclusion without knowing that root:root with 755 is already globally readable/accessable and the actual cause of the issue was a different one. See #1257 (comment)

Good idea, I will check that ASAP.

If 755 doesn't work for you, it probably means that your application is trying to mutate <appRoot> or any of the parent directories leading to it at runtime. That's a red flag, and you should avoid that. Look into the linked issue above to get a better idea.

My application is effectively mutating the parent of the <appRoot> by adding cousins folders. How is that a red flag ?

chanseokoh commented 4 years ago

My application is effectively mutating the parent of the by adding cousins folders. How is that a red flag ?

What are the cousins folders and what is the purpose of creating them? Are they for temporary files? It depends on why you are creating them, but maybe you'd want to mount volumes for the cousins folders if you have to write.

chanseokoh commented 4 years ago

So, that means that WAR can only be in exploded mode ?

Forgot to answer this. Yes, <containerizingMode>packaged is not yet supported for WAR projects.

chanseokoh commented 4 years ago

FTR: #1257 is resolved using a Jib extension. This issue is documented as one of the known limitations of the extension, where there is a workaround.

chanseokoh commented 4 years ago

FTR: #2782 is a duplicate of this, but it's worth checking the discussions there.

Also we should check out #1650 when starting on this work.

cablespaghetti commented 3 years ago

Just came across this problem with the jetty:9-jre11-slim image on Docker Hub. I'm using that rather than Distroless for multi-arch (ARM64) support, and for some reason the default entrypoint shell script tries to create a directory in /var/lib/jetty on startup. Here's the properties I add to get everything working:

        <jib.from.image>jetty:9-jre11-slim</jib.from.image>
        <jib.container.appRoot>/var/lib/jetty/webapps/ROOT</jib.container.appRoot>
        <jib.container.entrypoint>/usr/local/openjdk-11/bin/java,-jar</jib.container.entrypoint>
        <jib.container.args>/usr/local/jetty/start.jar</jib.container.args>
        <jib.container.user>nobody</jib.container.user>

Hope it's useful to somebody. :)

Marty commented 3 years ago

I just ran into this myself. I have to copy some files into an image that are then modified. As a result the modified outputs are saved to new files with a suffix appended to their respective original filenames.

The directory gets all the neccessary permissions to be writable by the user in the base image, but copying files to this location changes the entire directory path to root ownership.

I also tried to explicitly set the permissions via <extraDirectories><permissions> but these don't work for directories apparently. Now I worked around this by using a custom entrypoint and copying all the files around.

chanseokoh commented 3 years ago

@Marty another option is to use the Onwership extension (https://github.com/GoogleContainerTools/jib/issues/1270#issuecomment-642927961), which will allow you to change onwership of those directories.

sgandon commented 2 years ago

Hello, For security reason we have created a folder (/opt/talend) attached to a non root user and we would like to place our application code here without jib tempering the ownership of the folders created in a previous layer. There is a mention of a workaround using the Ownership extension but this is not clear to me how this work. What is amazing is the the ownrship of the /opt/talend is changed to root while all the classes and resources are set with the right user ownership !!! base image

drwxr-xr-x         0:0     483 kB  ├── opt
drwxrwxr-x 61000:61000     483 kB  │   └── talend
drwxr-xr-x 61000:61000        0 B  │       ├── app

image built by jib on top of above base image

drwxr-xr-x         0:0      39 MB  ├── opt
drwxr-xr-x         0:0      39 MB  │   └── talend
drwxr-xr-x         0:0      38 MB  │       ├── app
drwxr-xr-x         0:0     167 kB  │       │   ├── classes
drwxr-xr-x     61000:0        0 B  │       │   │   ├── conf
drwxr-xr-x     61000:0        0 B  │       │   │   ├── mock
yazimpact commented 11 months ago

Any updates on this issue, facing same thing, even with https://github.com/GoogleContainerTools/jib-extensions/tree/master/first-party/jib-ownership-extension-gradle

chanseokoh commented 11 months ago

@yazimpact if the ownership extension doesn't seem to work for you, check out the known limitations and the workaround.

FTR: #1257 is resolved using a Jib extension. This issue is documented as one of the known limitations of the extension, where there is a workaround.