Docker Alpine execute command as another user
Asked Answered
I

2

5

I'm having a problem while using an amazoncorretto-alpine image on which I run a Spring boot application. To startup the container I use a specific bash script which (along with other stuff) attempt to run the executable jar for the Spring boot application.

My need is to run the executable jar with a different user , so while the bash script runs with root the "java -jar springBoot.jar" must be executed as "spring" user.

In the docker file a user and a group has been created and given permissions for the springBoot.jar like this:

...
RUN addgroup -S spring && adduser -S -D spring -G spring
RUN chown spring:spring springBoot.jar
...
CMD ["myBash.sh"]

The user and group are present, the permissions on the file are configured correctly and the container starts by executing myBash.sh.

In the bash, that runs with "root" privileges, I'm using this command line to execute the jar with another user:

su - spring -c "java -jar springBoot.jar"

I did some other test by putting the -c "command" before the user but the error is always the same:

"The Account is not available"

This message is printed in the Docker console when starting the container.

Alpine version in the image:

"Alpine Linux v3.15"

Note: if I remove the instruction "su - spring...." above and just run the java -jar springBoot.jar in the bash script all works fine but the application is started with root (as expected).

Anyone have any idea what could be the problem?

Intermigration answered 21/3, 2022 at 12:2 Comment(4)
Is the group sprig a typo in your actual code?Sussex
It was a typo here :) , correct in the code.Intermigration
Does adduser -S create a home directory with login files etc for the account? Does it work if you omit the dash from su -?Pythian
It creates the home directory but not the login files due to the option -D I used. I can even use "spring" user to connect to container.Intermigration
S
4

instead of create the user directly in docker file try to create it inside the script like this

adduser -D spring -g "test" -s /bin/sh -D spring

then switch the user

su -s /bin/bash spring  <<EOF
java -jar java_file.jar
EOF
Severity answered 22/3, 2022 at 11:18 Comment(0)
O
2

You can specify on your Dockerfile a USER. You will find all the documentation in this link above.

https://docs.docker.com/engine/reference/builder/#user

But for your use case i think, you just need to specify in your Dockerfile something like this:

FROM alpine
RUN addgroup -S sprig && adduser -S -D spring -G spring
USER spring
#here you put your commands
#if you want to leave the container as an non-root user which is recommanded you then just
USER 1001
Oldenburg answered 21/3, 2022 at 12:18 Comment(6)
I need root for other things i do in the myBash.sh, so i cannot use your approach or both the jar and the sh will be running under spring.Intermigration
Well you can modify the provilege on running commands, as you wish, so if you want to run the bash as a root, you just change: USER root then go back to USER springOldenburg
the command that starts the spring boot jar is inside the myBash.sh used to start the container, I cannot separate the sh and the jar as you are suggesting.Intermigration
You are not separating anything, you are just telling Docker to run the commands as root and then as spring, you keep same format for your project, maybe we have some miss understanding here, maybeOldenburg
From you comment I'm understanding that you suggest to do 2 CMD in the Docker file so something like : ... USER root RUN "myBash.sh" USER spring CMD java -jar springBoot.jar .... If this is what you mean, i cannot do it because the "java -jar" is inside the myBash.sh and it must remain inside the sh script.Intermigration
CMD ["su", "spring", "-c", "exec sleep 300"]Athanor

© 2022 - 2024 — McMap. All rights reserved.