Run Maven in Docker container via current user - maven

I want to run Maven to build a project in a Docker container. First, I came up with:
docker run -it --rm
-v $HOME/.m2:/root/.m2:rw
-v $PWD:$PWD:rw
-w $PWD
maven:alpine
mvn "$#"
This builds fine, but the problem here is that all files are now written and owned by the root user. I want them to be owned by the current user, myself.
So I tried this:
docker run -it --rm
--user $(id -u):$(id -g)
-v $HOME/.m2:/root/.m2:rw
-v $PWD:$PWD:rw
-w $PWD
maven:alpine
mvn "$#"
This did not work as expected. I believe I know why: now with --user $(id -u):$(id -g), we are indeed executing as myself, but now the mapping of -v $HOME/.m2:/root/.m2:rw becomes incorrect, there is no /root in place anymore.
So let's try this:
docker run -it --rm
--user $(id -u):$(id -g)
-v $HOME:$HOME:rw
-v $PWD:$PWD:rw
-w $PWD
maven:alpine
mvn "$#"
Now I am getting the following warning:
Can not write to /root/.m2/copy_reference_file.log. Wrong volume permissions? Carrying on ...
Also, Maven seems to be able to build (although I am having problems with accessing the Docker daemon during integration tests, but that might be better suited for another question), but I don't see any artifacts appearing in ~/.m2/repository on the host? They are also not in /root/.m2/repository (which does not exist, as expected) on the host. Where are they? What am I doing wrong?

Here is described how to run maven as non-root-user:
Maven needs the user home to download artifacts to, and if the user does not exist in the image an extra user.home Java property needs to be set.
Something in that direction should work:
docker run -it --rm \
--user $(id -u):$(id -g) \
-v ~/.m2:/var/maven/.m2:rw \
-e MAVEN_CONFIG=/var/maven/.m2 \
-v $PWD:$PWD:rw \
-w $PWD \
maven:alpine \
mvn -Duser.home=/var/maven "$#"

Related

Bcrypt docker passwd using --admin-passwd

What is wrong with the following command? It is intended to create a portainer container with admin passwd 'portainer':
docker run --rm -d --name "portainer" -p "127.0.0.1:9001:9000" -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer --admin-password='$2a$10$0PW6gPY0TSeYzry2RSakl.7VUVmzdmD6mQPcemiG6i2vfJGGGePYu'
It leads to a Portainer container that will deny access for 'admin', saying that passwd 'portainer' is invalid. Details:
I put it into a .bat file. The thing runs on docker CE in Windows 10.
The longish crypt string within single quotes is a bcrypt equivalent of 'portainer', the designated admin password. I created and checked it here: https://www.javainuse.com/onlineBcrypt
Prior to running the command I stopped and removed an old portainer container, and even said docker volume rm portainer_data.
Doubling the "$" to "$$" did not solve the issue.
The command is deeply inspired by the official portainer docs: https://documentation.portainer.io/v2.0/deploy/initial/
For now I have a simple workaround: Simply drop that --admin-passwd parameter. Given that I grant a volume to portainer, I can just define a passwd at first start. However, I'd still prefer the script-only solution. Any ideas?
Here it is the solution you need:
docker run --detach \
--name=portainer-ce \
-p 8000:8000 \
-p 9000:9000 \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /volume1/docker/portainer-ce:/data \
portainer/portainer-ce \
--admin-password="$(htpasswd -nb -B admin adminpwPC | cut -d ':' -f 2)"

Docker build fails when executed within Makefile

So, I have a Docker build command that I have tested which works great
docker build \
-t app \
--no-cache --network host \
--build argssh_private_key="$(cat ~/.ssh/id_rsa)"\
--build-arg python_version="3.6.8" -f Dockerfile .
To ease the pain of the team learning Docker I encapsulated a few of the commands - build, start, stop - within a Makefile. However, within the Makefile I need to change the command slightly by modifying
$(cat ~/.ssh/id_rsa)
to
$(shell cat ~/.ssh/id_rsa)
When I execute the following:
make build
I receive the following message:
Step 13/20 : RUN git clone --depth 1 "${git_user}#${git_host}:${git_repo}" app
---> Running in d2eb41a71315
Cloning into 'app'...
Warning: Permanently added the ECDSA host key for IP address [ip_address] to the list of known hosts.
Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights and the repository exists.
However, I do not have the same issue when executing from the command-line. I I think it has something to do with the way the call the "cat" command but, I do not know a way to resolve.
Any ideas ?
Makefile:
APP_NAME=ccs_data_pipeline
DATA?="${HOME}/data"
DOCKER_FILE=Dockerfile
PYTHON_VERSION?=3.6.8
SRC?=$(shell dirname `pwd`)
PRIVATE_KEY?=$(shell echo $(shell cat ~/.ssh/id_rsa))
build: ## Build container for ccs data pipeline
docker build \
-t $(APP_NAME) \
--no-cache --network host \
--build-arg ssh_private_key="$(PRIVATE_KEY)" \
--build-arg python_version="$(PYTHON_VERSION)" \
-f $(DOCKER_FILE) .
start: ## Start the docker container
docker run \
-it -v $(DATA):/data \
--network host \
--rm \
--name="$(APP_NAME)" $(APP_NAME)
stop: ## Stop the docker container
docker stop $(APP_NAME); \
docker rm $(APP_NAME)
Please show your actual makefile, or at least the entire rule that is having the error. The single command you provided, with no context, is not enough to understand what you're doing or what might be wrong.
Note that it is often not correct to replace a shell operation like $(...) with a make shell command $(shell ...). However, sometimes it will work "by accident", where the real differences between those commands don't happen to matter.
In general you should never use $(shell ...) inside a recipe (I have no idea if this command appears in a recipe). Instead, you should escape all the dollar signs that you want to be passed verbatim to the shell when it runs your recipe:
$$(cat ~/.ssh/id_rsa)

Run a Docker Container from a Desktop File Without Terminal GUI?

I have a couple of Docker images I've built for this and that;one for scanner program, another for a browser etc. Once I had them working, I created .desktop files that execute a bash run scripts I've created to run a container with them.
My question is: is there a way to run the .desktop file without the terminal GUI showing up? I've tried a couple of approaches with no success.
For instance, I've tried:
[Desktop Entry]
Name=gscan2pdf
Icon=gscan2pdf.png
Exec=gnome-terminal -e
"/home/hildy/Documents/repos/docker/gscan2pdf/run_gscan.sh"
Type=Application
Terminal=false
As well as:
[Desktop Entry]
Name=gscan2pdf
Icon=gscan2pdf.png
Exec="/home/hildy/Documents/repos/docker/gscan2pdf/run_gscan.sh"
Type=Application
Terminal=true
Both of these execute the scripts just fine of course, I'd just like it better if the application launched without a terminal GUI launching first.
Host System:
CentOS 7 - Gnome 3 Desktop
One example of a run script:
#!/bin/bash
HOST_UID=$(id -u)
HOST_GID=$(id -g)
XSOCK=/tmp/.X11-unix &&
XAUTH=/tmp/.docker.xauth &&
touch $XAUTH &&
xauth nlist :0 | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge - &&
#These are only run the first time a container is run from the image
#docker run -e NEW_USER="${USER}" -e NEW_UID="${HOST_UID}" -e
#NEW_GID="${HOST_GID}" hildy/gscan2pdf:v1
#LAST_CONTAINER=$(docker ps -lq) &&
#docker commit "${LAST_CONTAINER}" hildy/gscan2pdf:v1
docker run \
-ti \
--user $USER \
--privileged \
-v /dev/bus/usb:/dev/bus/usb \
-v $XAUTH:$XAUTH -v $XSOCK:$XSOCK -v /home/$USER:/home/$USER \
-e XAUTHORITY=$XAUTH -e DISPLAY \
--entrypoint "" hildy/gscan2pdf:v1 gscan2pdf &>/dev/null
I have found an answer to my question. The issue was that the command to run the container contained the -i option for an interactive terminal. #sneep was correct in the comments to the question when he said "It should work with Terminal=false." His technique to add a line to the script to create a log file is also a great technique, which I will certainly use in the future and it helped me to diagnose the issue.
I can also confirm that replacing -it with -d for detached mode, as suggested by #Oleg Skylar, works.
Amended Docker command for the run script:
docker run \
-t \
--user $USER \
--privileged \
-v /dev/bus/usb:/dev/bus/usb \
-v $XAUTH:$XAUTH -v $XSOCK:$XSOCK -v /home/$USER:/home/$USER \
-e XAUTHORITY=$XAUTH -e DISPLAY \
--entrypoint "" hildy/gscan2pdf:v1 gscan2pdf &>/dev/null
Amended .desktop file:
[Desktop Entry]
Name=gscan2pdf
Icon=gscan2pdf.png
Exec=/home/hildy/Documents/repos/docker/gscan2pdf/run_gscan.sh
Type=Application
Terminal=false
StartupNotify=true

How to run cucumber/selenium tests in Docker?

I am struggling to run my cucumber tests from a Docker image.
Here is my setup:
I use OSX with XQuartz to run an X11 session
I use an Ubuntu 14 Vagrant image for development where I forward my X11 session
I am trying to run a docker image with Firefox that will use my XQuartz session for display
So far, I managed to start Firefox with the following setup:
# Dockerfile
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y firefox
# Replace 1000 with something appropriate ;)
RUN export uid=1000 gid=1000 && \
mkdir -p /home/developer && \
echo "developer:x:${uid}:${gid}:Developer,,,:/home/dev:/bin/bash" >> /etc/passwd && \
echo "developer:x:${uid}:" >> /etc/group && \
echo "developer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \
chmod 0440 /etc/sudoers.d/developer && \
chown ${uid}:${gid} -R /home/developer
USER developer
ENV HOME /home/developer
CMD /usr/bin/firefox
I can start Firefox with --net=host from my Vagrant machine:
docker build -t firefox .
docker run --net=host -ti --rm -e DISPLAY=$DISPLAY -v $HOME/.Xauthority:/home/developer/.Xauthority -v /tmp/.X11-unix:/tmp/.X11-unix:rw firefox:latest
But this is not ideal because I can't link other containers to my machine in the docker-compose.yml file. Ideally, I would like to run my docker machine without --net=host like this:
docker build -t firefox .
docker run -ti --rm -e DISPLAY=$DISPLAY -v $HOME/.Xauthority:/home/developer/.Xauthority -v /tmp/.X11-unix:/tmp/.X11-unix:rw firefox:latest
But I get the following error:
error: XDG_RUNTIME_DIR not set in the environment.
Error: cannot open display: localhost:10.0
Please help :)
You could simply use elgalu/docker-selenium to avoid dealing with what's already solved for you, and maintained:
docker run --rm -ti --net=host --pid=host --name=grid \
-e SELENIUM_HUB_PORT=4444 -e TZ="US/Pacific" \
-v /dev/shm:/dev/shm --privileged elgalu/selenium
If you need advanced features like a dashboard with video recording for example, or live preview, you can use Zalenium and start it with:
curl -sSL https://raw.githubusercontent.com/dosel/t/i/p | bash -s start -i

Passing parameter in docker build command with fish

Using Docker For Mac, fish shell, macOS 10.11
I am trying to run the following command: docker run -d -it --name=my-app-container -v $(pwd):/app -p 3000:3000 myapp
I get the following error:
$(...) is not supported. In fish, please use '(pwd)'.
fish: docker run -d -it --name=my-app-container -v $(pwd):/app -p 3000:3000 myapp
Been reading through repos and SO answers but cant get this to work. Any ideas? Thank you.
The equivalent of bash $(command) in fish is just (command)
So all you need to do is remove the dollar sign.
docker run -d -it --name=my-app-cont -v (pwd):/app -p 3000:3000 myapp
Following #user2915097 's suggestion, seems like this doesn't throw an error....docker run -d -it --name=my-app-cont -v $PWD:/app -p 3000:3000 myapp. So switching $(pwd) to $PWD gets past this error.

Resources