how to run docker CMD as root after USER was changed - bash

I have a docker image that runs on linux alpine. Sudo is not installed. I would like to build the image with a non-root user but I need to run a start script from CMD as root after the image is build.
I need to open the container in vscode and if the USER is root then all new files created inside the container environment (and mounted in a volume) will be owned by root and therefore needs sudo to modify from the host system.
If I change the USER to anything but root in the Dockerfile, then the start.sh script running in my parent image CMD cannot run.
I have tried a few things like:
Dockerfile RUN is done as root and the start.sh script ends with: su . to change the user back to the non root. This has no effect on vscode ownership. I can then create new files from the terminal with the non root user, but I would rather be able to use vscode create new file (which is still owned by root)
Override the CMD to run with sudo (but sudo not installed. And I do not want to install it)
CMD su root -c /start.sh but I dont know the root password in the docker image, and I do not want to modify the root password
Any help with finding a way to run my start.sh script with root privileges without using sudo would be greatly appreciated.

Related

how to overwrite property files in a docker container?

I have a docker container inside which I have jar file that is of my springBoot application . How can I overwrite the application.property file of my app. Suppose if I want to change datasource url ,how can I do that through commandline?
Run docker ps and note the initials of id of your container.
Run docker exec -it <id> <bash or sh>, you will be inside your running container.
Go to your jar directory. Place your properties file in config/ as application.properties.
Rerun your app, but make sure to do it in background, so you can exit docker.
You can't restart the primary process (PID 1). For that usecase you'll need external volume and restart the container on property file change.
Create a volume: docker volume create vol1, you will get /var/lib/docker/volumes/vol1/
Change group of directory sudo chgrp 1001 /var/lib/docker/volumes/vol1/_data
Add write access to group: sudo chmod g+w /var/lib/docker/volumes/vol1/_data
Check the permissions of the directory: sudo ls -al /var/lib/docker/volumes/vol1/. They should be: drwxrwxr-x
Next time you run your container, mount the folder containing jar file to your volume as: docker run -d --name=webApp1 --mount source=vol1,destination=/path/to/app -p port:port name
You can change the property file in /var/lib/docker/volumes/vol1/_data/ and restart container: docker restart container_name
Disclaimer: Replacing properties file outside jar is not considered a good practice and is highly discouraged. So, these steps are only recommended for testing.

Using setuid inside a docker container

I have a container which needs to do some initialisation on startup that can only be done as root, but following good practice I don't want the container running as root.
I figured I should be able to create a script inside the container, owned by root and with the setuid bit set. The container can then be started with a non-root user, the initialisation done by executing the script, and the the container does what it needs to do.
This does not seem to work. Even though the script is owned by root and the setuid bit set, the initialisation script runs as the non-root user.
Should this work? Is there another (better) way?
I'm running with Docker for Desktop on a mac.
The initialisation I need to do is to update /etc/hosts with a value that can only be determined at run time from inside the container - specifically the IP address associated with host.docker.internal.
I have tried making /etc/hosts writable by the non-root user from within the Dockerfile. That doesn't work either. /etc/hosts is a mounted volume when in the docker file and chmod and chown seem to have no effect on the file in the running container.
Probably to achieve your goal you can specify in the Dockerfile to use the non-root user after the installation script.
For example:
FROM ...
RUN ./install.sh
USER foo
...
This Dockerfile will launch the installer as root and after changing the user to the selected one.
Hope it can be useful for you!

Connecting folder in a Docker container with a folder on local machine - Permission Denied

I'm new to docker and am trying to bind mount a folder in my docker container with a folder on my local machine. Using the code below, I was able to create the container with no issue.
docker run -it -v /Users/bdbot/Documents/mount_demo/:/mount_demo nycdsa/linux-toolkits bash
However, when I tried to create a txt file within the container folder, I got this error:
bash: demo.txt: Permission denied
Seeing that it was an access issue, I ran
sudo chmod 777 ../mount_demo
This allowed me to create the file, however when I checked the folder on my local machine it was not there. So the folders are not syncing.
I've also made sure the docker settings "Shared Drives" had the correct credentials. I'm not familiar enough with Docker to know how to trouble shoot further and have not been able to find anything online. I am using Windows, and everything is up to date.
The answer ended up being a really simple fix. The combination of using unix on a windows machine required that I add an additional slash(/) before the folder path. The below fixed this issue for me:
docker run -it -v //Users/bdbot/Documents/mount_demo/:/mount_demo nycdsa/linux-toolkits bash

How to edit files which are made by Laradock workspace

I've newly started to use Laradock to build my Laravel projects but I have a problem in editing the files such as Controllers, Models, etc which are made by the php artisan command in the Laradock workspace. The reason is the user in the workspace is a root and on the other side, I'm trying to edit the file in my editor by a common user. So every time I have to run the command chmod -R 777 /newCreatedFile.php to change the permission. So is there any solution to handle this problem?
By the way my OS is ubuntu 18.04
In the Laradock Getting Started guide, it explains how to get Laradock running as a specified user:
Note: You can add --user=laradock to have files created as your host’s user. Example:
docker-compose exec --user=laradock workspace bash
I believe this should solve your issue, as you will no longer have the Docker user running these commands. Try it out!
Note: The core issue may just be that whatever user Laradock is running as is not creating files with group permissions that allows the host machine's user write capabilities, hence why the --user flag can be used. It may not actually be running as the root user itself.

Running docker as non-root user OR running jenkins on tomcat as root user

I am trying to build a docker image using docker-maven plugin, and plan to execute the mvn command using jenkins. I have jenkins.war deployed on a tomcat instance instead of a standalone app, which runs as a non-root user.
The problem is that docker needs to be run as root user, so maven commands need to be run as root user, and hence jenkins/tomcat needs to run as root user which is not a good practice (although my non-root-user is also sudoer so I guess won't matter much).
So bottom line, I see two solutions : Either run docker as non-root user (and need help on how to do that)
OR
Need to run jenkins as root (And not sure how to achieve that as I changed environment variable /config and still its not switching to root).
Any advice on which solution to choose and how to implement it ?
The problem is that docker needs to be run as root user, so maven commands need to be run as root user,
No, a docker run can be done with a -u (--user) parameter in order to use a non-root user inside the container.
Either run docker as non-root user
Your user (on the host) needs to be part of the docker group. Then you can run the docker service with that user.
As commented, this is not very secure.
See:
"chrisfosterelli/dockerrootplease"
"Understanding how uid and gid work in Docker containers"
That last links ends with the following findings:
If there’s a known uid that the process inside the container is executing as, it could be as simple as restricting access to the host system so that the uid from the container has limited access.
The better solution is to start containers with a known uid using the--user (you can use a username also, but remember that it’s just a friendlier way of providing a uid from the host’s username system), and then limiting access to the uid on the host that you’ve decided the container will run as.
Because of how uids and usernames (and gids and group names) map from a container to the host, specifying the user that a containerized process runs as can make the process appear to be owned by different users inside vs outside the container.
Regarding that last point, you now have user namespace (userns) remapping (since docker 1.10, but I would advice 17.06, because of issue 33844).
I am also stuck on how to setup a docker build server.
Here's where I see ground truth right now...
Docker commands require root privileges
This is because if can run arbitrary docker commands, you have the same powers as root on the host. (You can build a container runnings as root internally, with a filesystem mount to anywhere on the host, thus allowing any root action.)
The "docker" group is a big lie IMHO. It's effectively the same as making the members root.
The only way I can see to wrap docker with any kind of security for non-root use is to build custom bash scripts to launch very specific docker commands, then to carefully audit the security implications of those commands, then add those scripts to the sudoers file (granting passwordless sudo to non-root users).
In the world where we integrate docker into development pipelines (e.g. putting docker commands in Maven builds or allow developers to make arbitrary changes to build definitions for a docker build server), I have idea how you maintain any security.
From a lot of searching and research debugging this issue in the the last week.
I found to run a maven docker container as non root would be to pass the user flag
eg -u 1000
But for this to work correctly the user needs to be in the /passwd directory of the image
to work around this you can add the host (Jenkins) /etc/passwd directory to the docker image and use a non root user.
From your system commmand arguments on the docker run container add the following to mount the correct volumes to the mvn image to allow the host non root user to get mapped inside the maven container.
-v /share:/share -v /etc/passwd:/etc/passwd:ro -v /etc/group:/etc/group:ro -v "$HOME/.m2":/var/maven/.m2:z -w /usr/src/mymaven -e MAVEN_CONFIG=/var/maven/.m2 -e MAVEN_OPTS="-Duser.home=/var/maven"
I know this might not be the most informative answer but it should work to run a mvn container as non root specifically to run otj-embedded-pg for integration tests that pass fine locally but fail on a Jenkins server.
See this link OTJ_EMBEDDED_RUN_IN_CI_SERVER
As most of the posters on that thread suggest creating a new image there is no need to do that and you can run the latest maven docker image with the commands listed above and it works as it should
Hope this helps somebody that might get stuck on this issue and save them a few hours work.

Resources