What is happening when docker-maven plugin tries to build image? - maven

I am running Jenkins in a docker container and Jenkins tries to run my maven build. As part of the build, the docker maven plugin instructs it to build a docker image.
That part of the POM is below.
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.3.8</version>
<configuration>
<imageName>example</imageName>
<baseImage>java:latest</baseImage>
<skipDockerBuild>false</skipDockerBuild>
<cmd>["java", "-jar", "myLogThread-jar-with-dependencies.jar"]</cmd>
<resources>
<resource>
<directory>target/</directory>
<include>config.properties</include>
</resource>
<resource>
<directory>${project.build.directory}</directory>
<include>myLogThread-jar-with-dependencies.jar</include>
</resource>
</resources>
</configuration>
</plugin>
The maven build runs until it attempts to build the image, at which point the following error message is spat out:
[INFO] Building image example
[INFO] I/O exception (java.io.IOException) caught when processing request to {}->unix://localhost:80: Permission denied
I can go into the correct directory and the Dockerfile is there.
I can also run sudo docker build . and it will build the image with no issues.
Why is the maven build failing? What request is being made to localhost:80? How can I correct this so that maven can build my image?
Note: I have mounted the docker socket and binary in this container

As mentioned above by Rajith Delantha, this solved the problem for me:
Add: DOCKER_OPTS=' -G jenkins' directly in /etc/default/docker.
Then restart docker service by sudo service docker restart.

This can be resolved by adding DOCKER_HOST environment variable in Jenkins.
Setup your docker daemon like this:
[/etc/sysconfig/docker]
OPTIONS="-H tcp://127.0.0.1:4243"
Jenkins Jobs (Inject environment variables):
DOCKER_HOST=tcp://127.0.0.1:4243

I had the same problem, but in my local machine.
I've got it after reading this comment in Github thread: https://github.com/docker/compose/issues/1214#issuecomment-256774629
It says:
Solution (from
https://docs.docker.com/engine/installation/linux/debian/, does not
only work with Debian):
Add the docker group if it doesn't already exist.
sudo groupadd docker
Add the connected user "${USER}" to the docker group. Change the user
name to match your preferred user. You may have to logout and log back
in again for this to take effect.
sudo gpasswd -a ${USER} docker
Restart the Docker daemon.
sudo service docker restart

after making sure docker ps works from the same user that runs mvn I still had the same problem.
it looks like a bug due to special characters in the image name. I resolved it by removing the dash sign (-) (or any special characters) from the docker image name.
try set the repository to deferent name and check.
<configuration>
<repository>somename</repository>
</configuration>

I was able to solve the problem by combining elements of both upvoted answers.
Set options to use different port in /etc/default/docker.
DOCKER_OPTS="-H tcp://127.0.0.1:4243"
Restart the Docker daemon.
sudo service docker restart
Then build your package.
export DOCKER_HOST=tcp://127.0.0.1:4243
mvn clean package docker:build

I met the issue at bamboo-agent, but I assume the same holds for jenkins.
Add the user running maven to the docker group. Then restart docker AND the service running maven. Group changes are not loaded while the services are running. So in my case:
sudo groupadd docker # if it does not exist
sudo usermod -a -G docker bamboo-user
sudo systemctl restart docker.service
sudo systemctl restart bamboo-agent.service

I had a similar issue when I didn't have the docker daemon running - restart the Docker toolbox and it looks much happier now

I had the same issue with Jenkins.
Added jenkins to docker group
sudo usermod -aG docker jenkins
Then restrat jenkins.

Related

Install package in Docker image created by Spring Boot Maven plugin

My Spring Boot project contains the Spring Boot Maven Plugin which I use for building a Docker image by running mvn spring-boot:build-image.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>build-image</goal>
</goals>
</execution>
</executions>
</plugin>
When deploying this image to a Docker stack I need to run a healthcheck using the curl command but unfortunately curl is not installed by the default buildpack.
Is it possible to further tweak the image building process so that curl gets installed into the iamge? I couldn't find the necessary information
TLDR;
Install curl into the build image with:
docker run --user="root" --entrypoint launcher my-app:0.0.1-SNAPSHOT "apt-get update && apt-get install curl -y"
Crab container id of the stopped container with docker ps -a:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ff7db32825f my-app:0.0.1-SNAPSHOT "launcher 'apt-get u…" 44 minutes ago Exited (0) 44 minutes ago reverent_swanson
Create a new container image based on the one we installed curl into with:
docker commit 2ff7db32825f my-app-with-curl
Fire up a new container defining the correct ENTRYPOINT to start Spring Boot app:
docker run --rm -p 8080:8080 --user="cnb" --entrypoint /cnb/process/web my-app-with-curl
Now curl should be ready inside your container.
Details of the solution:
The reasoning behind Cloud Native Buildpacks (CNBs) & Paketo.io, which are basically abstracted away by the spring-boot-maven-plugins build-image goal, is to free us from the need to write/maintain our own Dockerfiles. So the inversion of this is: It's easy to configure the build process, but it is not easy to change things like installed packages.
The reason is, that those packages are maintained in a so called stack, that manages the used build-time and run-time images. And if the stack doesn't define a Mixin for your OS-level dependency, then you can't simply add another package. It would also not suffice to create your own simple buildpack (I tried this approach). And creating your own stacks, buildpacks and/or builders would also negate the huge benefits that Cloud Native Buildpacks provide! Amongst other things we would be also forced to keep the images updated ourselves...
But there's another solution. As we don't want to create our own stacks/buildpacks, we can tweak the container image which has been created by CNBs/spring-boot-maven-plugin. Because the official docs show us how to hook into the startup process of the produced containers and run shell scripts for example. Let's assume our mvn spring-boot:build-image command produced a container image called my-app:0.0.1-SNAPSHOT.
Then first we install curl into the image with:
docker run --user="root" --entrypoint launcher my-app:0.0.1-SNAPSHOT "apt-get update && apt-get install curl -y"
We need to use --user="root" here in order that the command apt-get update && apt-get install curl -y will run successfully (otherwise we would run into errors like List directory /var/lib/apt/lists/partial is missing. - Acquire (13: Permission denied)). This will install curl, but we shouldn't use the resulting container in production. Because our Spring Boot app would run using the root user, which would introduce a variety of security problems. Also we've overwritten the ENTRYPOINT of our container, so it wouldn't be able to start our app.
Therefore we simply start this stopped container with a new command, entrypoint & user! Simply crab the container id of the stopped container with docker ps -a:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ff7db32825f my-app:0.0.1-SNAPSHOT "launcher 'apt-get u…" 44 minutes ago Exited (0) 44 minutes ago reverent_swanson
And create a new container image based on the one we installed curl into with:
docker commit 2ff7db32825f my-app-with-curl
Finally fire up a new container based on this new image, defining the correct ENTRYPOINT to start our Spring Boot app and also using the cnb user again (as defined in the Cloud Native Buildpacks):
docker run --rm -p 8080:8080 --user="cnb" --entrypoint /cnb/process/web my-app-with-curl
Off topic but relevant:
There are ongoing discussions if it is desired to install curl in a production container. See this post for example.
I ended up using a mounted volume (/utils for instance) with a static compiled curl (https://github.com/moparisthebest/static-curl) and configured health checker like
/utils/curl http://localhost:8080/actuator/health

Unable to find docker image locally

I was following this post - the reference code is on GitHub. I have cloned the repository on my local.
The project has got a react app inside it. I'm trying to run it on my local following step 7 on the same post:
docker run -p 8080:80 shakyshane/cra-docker
This returns:
Unable to find image 'shakyshane/cra-docker:latest' locally
docker: Error response from daemon: pull access denied for shakyshane/cra-docker, repository does not exist or may require 'docker login'.
See 'docker run --help'.
I tried login to docker again but looks like since it belongs to #shakyShane I cannot access it.
I idiotically tried npm start too but it's not a simple react app running on node - it's in the container and containers are not controlled by npm
Looks like docker pull shakyshane/cra-docker:latest throws this:
Error response from daemon: pull access denied for shakyshane/cra-docker, repository does not exist or may require 'docker login'
So the question is how do I run this docker image on my local mac machine?
Well this is illogical but still sharing so future people like me don't get stuck.
The problem was that I was trying to run a docker image which doesn't exist.
I needed to build the image:
docker build . -t xameeramir/cra-docker
And then run it:
docker run -p 8080:80 xameeramir/cra-docker
In my case, my image had TAG specified with it and I was not using it.
REPOSITORY TAG IMAGE ID CREATED SIZE
testimage testtag 189b7354c60a 13 hours ago 88.3MB
Unable to find image 'testimage:latest' locally for this command docker run testimage
So specifying tag like this - docker run testimage:testtag worked for me
Posting my solution since non of the above worked.
Working on macbook M1 pro.
The issue I had is that the image was built as arm/64. And I was running the command:
docker run --platform=linux/amd64 ...
So I had to build the image for amd/64 platform in order to run it.
Command below:
docker buildx build --platform=linux/amd64 ...
In conclusion your docker image platform and docker run platform needs to be the same from what I experienced.
In my case, the docker image did exist on the system and still I couldn't run the container locally, so I used the exact image ID instead of image name and tag, like this:
docker run myContainer c29150c8588e
I received this error message when I typed the name/character wrong. That is, "name1\name2" instead of "name1/name2" (wrong slash).
In my case, I saw this error when I had logged in to the dockerhub in my docker desktop. The repo I was pulling was local to my enterprise. Once i logged out of dockerhub, the pull worked.
This just happened to me because my local docker vm on macos ran out of disk space.
I just deleted some old images using docker image prune and it started working correctly again.
shakyshane/cra-docker Does not exist in that user's repo https://hub.docker.com/u/shakyshane/
The problem is you are trying to run an imagen that does not exists. If you are executing a Dockerfile, the image was not created until Dockerfile pass with no errors; so when Dockerfile tries to run the image, it can't find it. Be sure you have no errors in the execution of your scripts.
The simplest answer can be the correct one!.. make sure you have permissions to execute the command, use:
sudo docker run -p 8080:80 shakyshane/cra-docker
In my case, I didn't realise there was a difference between docker run and docker start, and I kept using the run command when I should've been using the start command.
FYI, run is for building and creating the docker container, start is to just start a stopped container
Use -d
sudo docker run -d -p 8000:8000 rasa/duckling
learn about -d here
sudo docker run --help
At first, i build image on mac-m1-pro with this command docker build -t hello_k8s_world:0.0.1 ., when is run this image the issue appear.
After read Master Yi's answer, i realize the crux of the matter and rebuild my images like this docker build --platform=arm64 -t hello_k8s_world:0.0.1 .
Finally,it worked.

Jenkins tutorial maven project (with Docker) fails at Build stage

I'm using the current Jenkins Maven Project tutorial using Docker:
https://jenkins.io/doc/tutorials/build-a-java-app-with-maven/
I keep getting this error at the Build stage:
[simple-java-maven-app] Running shell script
sh: can't create
/var/jenkins_home/workspace/simple-java-maven-app#tmp/durable-bae402a9/jenkins-log.txt:
nonexistent directory
sh: can't create
/var/jenkins_home/workspace/simple-java-maven-app#tmp/durable-bae402a9/jenkins-result.txt:
nonexistent directory
I've tried setting least restrictive permissions with chmod -R 777, chown -R nobody and chown -R 1000 on the listed directories, but nothing seems to work.
This is happening with the jenkins image on Docker version 17.12.0-ce, build c97c6d6 on Windows 10 Professional.
As this is happening with the Maven project tutorial on the Jenkins site, I'm wondering how many others have run into this issue.
I had also the same problem on MacOSX.
After few hours of research, I have finally find the solution.
To solve the problem, it's important to understand that Jenkins is inside a container and when the docker agent inside this container talk to your docker engine, it give path to mount volume matching inner the container. But your docker engine is outer. So to allow to work correctly path inner the container must match the same path outer the container in your host.
To allow working correctly, you need to change 2 things.
docker run arguments
Jenkinsfile docker agent arguments
For my own usage, I used this
docker run -d \
--env "JENKINS_HOME=$HOME/Library/Jenkins" \
--restart always \
--name jenkins \
-u root \
-p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $HOME/Library/Jenkins:$HOME/Library/Jenkins \
-v "$HOME":/home \
jenkinsci/blueocean
In the Jenkinsfile
Replace the agent part
agent {
docker {
image 'maven:3-alpine'
args '-v /root/.m2:/root/.m2'
}
by
agent {
docker {
image 'maven:3-alpine'
args '-v <host_home_path>/.m2:/root/.m2'
}
It's quite likely that this issue resulted from a recent change in Docker behaviour, which was no longer being handled correctly by the Docker Pipeline plugin in Jenkins.
Without going into too much detail, the issue was causing Jenkins to no longer be able to identify the container it was running in, which results in the errors (above) that you encountered with these tutorials.
A new version (1.15) of the Docker Pipeline plugin was released yesterday (https://plugins.jenkins.io/docker-workflow).
If you upgrade this plugin on your Jenkins (in Docker) instance (via Manage Jenkins > Manage Plugins), you'll find that these tutorials should start working again (as documented).
The error message means that the directory durable-bae402a9 was not created.
Walk back through the tutorial to find the step that should have created that directory, and make whatever changes are needed to make sure it succeeds.

How to edit a docker image and deploy it

I want to install custom programs on an ubuntu 14.04 image using docker and then upload the result to a repository online. Is there a guide somewhere that can point me to the right direction ?
you create a Dockerfile that starts with ...
FROM ubuntu:14.04
# Other commands here e.g.
# RUN apt-get -y install apache2
CMD bash
THEN create an account on docker hub
https://hub.docker.com/
THEN you can ...
docker build ... etc
to build your image
THEN to test it, create a container with ...
docker run ... etc
THEN finally, when happy with it ...
docker login
docker push ... etc
Once pushed, you can pull from any server with ...
docker login
docker pull
Obviously, you need docker installed on every server you are pulling from

How to run a docker command in Jenkins Build Execute Shell

I'm new to Jenkins and I have been searching around but I couldn't find what I was looking for.
I'd like to know how to run docker command in Jenkins (Build - Execute Shell):
Example: docker run hello-world
I have set Docker Installation for "Install latest from docker.io" in Jenkins Configure System and also have installed several Docker plugins. However, it still didn't work.
Can anyone help me point out what else should I check or set?
John
One of the following plugins should work fine:
CloudBees Docker Custom Build Environment Plugin
CloudBees Docker Pipeline Plugin
I normally run my builds on slave nodes that have docker pre-installed.
I came across another generic solution. Since I'm not expert creating a Jenkins-Plugin out of this, here the manual steps:
Create/change your Jenkins (I use portainer) with environment variables DOCKER_HOST=tcp://192.168.1.50 (when using unix protocol you also have to mount your docker socket) and append :/var/jenkins_home/bin to the actual PATH variable
On your docker host copy the docker command to the jenkins image "docker cp /usr/bin/docker jenkins:/var/jenkins_home/bin/"
Restart the Jenkins container
Now you can use docker command from any script or command line. The changes will persist an image update.

Resources