fabric8io / docker-maven-plugin

Maven plugin for running and creating Docker images
https://dmp.fabric8.io
Apache License 2.0
1.88k stars 642 forks source link

user command not work in order #913

Open fairjm opened 6 years ago

fairjm commented 6 years ago

Description

I use <user> before <runCmds>,but <runCmds> still run earlier than <user>.

Info

<build>
    <from>jetty</from>
    <assembly>
        <descriptorRef>rootWar</descriptorRef>
        <targetDir>/var/lib/jetty/webapps</targetDir>
    </assembly>
    <env>
        <JAVA_OPTIONS>-Xmx1g</JAVA_OPTIONS>
    </env>
    <user>root</user>
    <runCmds>
        <runCmd>mkdir -p /root/xxx</runCmd>
        <runCmd>touch /root/xxx/yyy</runCmd>
        <runCmd>echo zzz > /root/xxx/yyy</runCmd>
    </runCmds>
</build>

build output:

[INFO] DOCKER> [project:0.0.1-SNAPSHOT]: Created docker-build.tar in 3 seconds
[INFO] DOCKER> Step 1/7 : FROM jetty
[INFO] DOCKER> ---> 2938aa22262c
[INFO] DOCKER> Step 2/7 : ENV JAVA_OPTIONS -Xmx1g
[INFO] DOCKER> ---> Using cache
[INFO] DOCKER> ---> d047a2ce0867
[INFO] DOCKER> Step 3/7 : COPY maven /var/lib/jetty/webapps/
[INFO] DOCKER> ---> 272466f0b477
[INFO] DOCKER> Removing intermediate container 82de144a0b48
[INFO] DOCKER> Step 4/7 : RUN mkdir -p /root/xxx
[INFO] DOCKER> ---> Running in 14165585160c
[INFO] DOCKER> [91mmkdir: cannot create directory /root: Permission denied

because parent image use jetty as user so I can't create the file that is required by app in /root.
using Dockerfile is ok.
Is it on purpose?

amanzag commented 6 years ago

Apparently, commands don't run in the same order as you set them in the POM, but rather in a fixed order. The fixed order is actually this:

    addOptimisation();
    addEnv(b);
    addLabels(b);
    addPorts(b);

    addCopy(b);
    addWorkdir(b);
    addRun(b);
    addVolumes(b);

    addHealthCheck(b);

    addCmd(b);
    addEntryPoint(b);

    addUser(b);

I've created a pull request tu put USER in some place where it can be useful (before RUN)

963

rhuss commented 6 years ago

It's not possible determine the order of configuration XML elements due to the way how Maven injects the configuration.

If you really require more flexibility, a Dockerfile might be the better solution to you.

Unfortunately its not easily possible to change the generation right now, because of backwards compatibility because very often you still need the original user for executing the commands before switching to the final user.

A similar (but different) discussion happens in #632. Probably the best solution is to extend <runCmds> like in

<runCmds>
  <user>root</user>
  <run>....</run>
  <run>....</run>
<runCmds>

so that you can explicitely specify with which user you want to run the cmds. This is probably the best possible solution, for anything more complicated a real Dockerfile should be used (and referenced to with dockerFile)

chrisinmtown commented 5 years ago

It would be helpful if the D-M-P would make it easy to create an image that runs its service as an unprivileged user, for example as discussed here: https://medium.com/@mccode/processes-in-containers-should-not-run-as-root-2feae3f0df3b I like to put everything in the pom.xml file. I think the steps are (1) specify a runCmd to create the user; (2) specify that user in the assembly element; (3) specify user in the build element. But today the emitted order in the generated dockerfile is wrong, the instructions from the assembly attempt to do a chown before that user has been created by the runcmds (which have not run yet). Here's my attempt that does not work:

<build>
        <from>openjdk:8-jre-slim</from>
        <tags>
                <tag>${project.version}-b${build.number}</tag>
        </tags>
        <runCmds>
                <run>useradd myuser</run>
        </runCmds>
        <assembly>
                <user>myuser</user>    <!-- chown FAILS DUE TO MISSING USER -->
                <descriptorRef>artifact</descriptorRef>
        </assembly>
        <user>myuser</user>
        <cmd>
                <shell><![CDATA[cd /maven; java -Xms128m -Xmx1024m -Djava.security.egd=file:/dev/./urandom -jar ${project.artifactId}-${project.version}.${project.packaging}]]></shell>
        </cmd>
</build>

Yes I can switch to an external Dockerfile, then I get what I need:

FROM ${docker.base}
RUN groupadd mygroup && useradd -r -g mygroup myuser
COPY maven/ /maven
RUN chown -R cdsuser:cdsgroup /maven
USER myuser
CMD cd /maven; java -Xms128m -Xmx1024m -Djava.security.egd=file:/dev/./urandom -jar ${project.artifactId}-${project.version}.${project.packaging}

But this is a trivial Dockerfile and it seems like all the pieces are already in D-M-P, they just don't quite fit together properly. Thanks for listening.

rhuss commented 5 years ago

I agree that in your use case it might make sense to have command first before extracting and adding the assembly. But as mentioned above, change the internal order breaks other use cases.

For your use case, what's about using a numeric uid for the assembly, and then add your user (with this numeric uid) in a run command? That should work, too.

Alternatively, you can use a special base image which you have prepared outside that build which performs the preparation steps for you.

rhuss commented 5 years ago

If anyone wants to work on the suggestion in https://github.com/fabric8io/docker-maven-plugin/issues/913#issuecomment-378725546, I'm happy to help here (but won't implement in on my own). Otherwise, I tend to close this issue.

JensGroenborgAndersen commented 6 months ago

I have written a fix for this that allows user changes in the runCmds. The tests and documentation are updated, and i believe everything is done according to the contributing document. Can't push my branch though.

rohanKanojia commented 6 months ago

@JensGroenborgAndersen : Umm, to which git remote are you pushing your branch? You should fork the repository and push it to your fork then create pull request to merge it in master.

JensGroenborgAndersen commented 6 months ago

Ahh ok. The contributing doc, didn't say anything about it, so i though i might need some access rights.

rohanKanojia commented 6 months ago

@JensGroenborgAndersen : I see. maybe we need to improve CONTRIBUTING.md as well :-)