Docker container can't write on host - docker

First of all, I couldn't find the answer here on SO (this is the closest post).
I have EC2 running Ubuntu. First I installed Jenkins, and then Docker.
It's not "DonD".
My project has a Jenkinsfile, on that I'm running some docker commands.
It's supposed to use a docker container like gradle, share a volume and build the project.
The final .war will be on the host file system.
The problem is: the gradle inside the container can't write on host's folder.
Here's my Jenkinsfile (one of countless tries):
#!/usr/bin/groovy
node {
checkout scm
stage 'Gradle'
sh 'sudo docker run --rm -v "$PWD":/api -w /api gradle gradle clean build --stacktrace'
}
Stacktrace important line:
Caused by: org.gradle.api.UncheckedIOException: Failed to create parent directory '/api/.gradle' when creating directory '/api/.gradle/4.3/fileHashes'

Solved!
I logged into container using the -v argument:
$ docker exec -it -v "$PWD":/api -w /api gradle bash
Then I tried to check the current user:
$ whoami
# gradle
So, the solution is to run the container as root:
sh 'docker -u root run --rm -v "$PWD":/api -w /api gradle gradle clean build'
This is the root of the container. Jenkins doesn't need root access.

Related

Cannot copy file from jenkins container to host through jenkins pipeline

working on zsh (mac1), I have used this docker run command:
- docker run --name container2 --link container1:alias -v /Users/omerboucris/Desktop/Devops_Final_Project/jenkins-data:/var/jenkins_home -p 8090:8080 -d jenkins/jenkins:lts
I have upload the Jenkins job and Im trying to docker cp some local file which created in /workspace/job1/file.txt to my vm host path:
/Users/omerboucris/Desktop/Devops_Final_Project/jenkins-data
why I have no access to my vm ? the jenkins runs on root only.. If I print 'pwd' on my job: /var/jenkins_home/workspace/MonitorJob
so how I can use the docker cp ?
this command not helpful:
docker cp d6dac560c25b:/var/jenkins_home/workspace/FinalProject_Devops/OurLandPage.jsp <HOME>/Desktop
even If Im trying to cd my Desktop I cant
thanks!

Running docker within docker missing file - docker run -v /var/jenkins_home/job:/build ./script.sh

I have Jenkins running in docker container. In Jenkins container we also run docker commands from pipelines. The problem with it is that when we run this from pipeline:
docker run -v /var/jenkins_home/job:/build ./script.sh
It does not mount the content of /var/jenkins_home/job
So I tested it with:
docker run -v /tmp:/build ./script.sh
And it mounted /tmp of the host machine not of Jenkins docker.
What causes this behaviour and how can I mount the path of Jenkins docker not host machine? OR is there anyway to make docker interpret /var/jenkins_home/job to host folder automatically?

testing tkinter-based function on jenkins in a docker container on AWS

I have a python code that passes all the test on my local machine. The code uses tkinter and provides a GUI. However, none of the test functions actually open the GUI. (They call tk.Tk() though).
I created a docker container locally and could use X11 forwarding to pass the tests on the "local" container as well.
Now, I'm trying to run the tests on Jenkins that I have set up on an EC2 instance. Jenkins is supposed to create a docker container using the Dockerfile that is on my repository. And then call "docker run -e ... -v ..." (similar to what I had in my local computer) to check the tests. I understand my ec2 instance does not have a gui and therefore x11 forwarding is not as simple as it was on my computer. There should be a way for tests using a gui to be checked through Jenkins setup on AWS. Any help is appreciated.
EDIT
Here is the build script that I have on AWS, it creates the docker container using the Dockerfile:
IMAGE_NAME="test-image"
CONTAINER_NAME="deidentifier_clinical"
echo "Check current working directory"
pwd
echo "Build docker image and run container"
docker build -t $IMAGE_NAME .
echo $DISPLAY
docker run -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY $IMAGE_NAME bash -c "cd /$CONTAINER_NAME;make test"
echo "Copy coverage.xml into Jenkins container"
rm -rf reports; mkdir reports
docker cp $CONTAINER_NAME:/deidentifier_clinical/htmlcov/* reports/.
echo "Cleanup"
docker stop $CONTAINER_NAME
docker rm $CONTAINER_NAME
docker rmi $IMAGE_NAME
This fails on the docker run line. This same script runs with no problem on my local computer after setting up the X11-forwarding.

Run docker-compose from Docker container

I have Jenkins running inside a Docker container with docker.sock mounted. Can I call docker-compose from this container to run a service on host machine? I tried executing installation script from within a container, but it keeps saying
"no such file or directory".
docker exec jenkins curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
docker exec jenkins chmod +x /usr/local/bin/docker-compose
It is achievable but tricky to get it right.
You need to mount with a docker volume the path the docker-compose.yml file is in on your docker host, to the exact same location in the container.
So if the docker-compose.yml file location is /home/leonid/workspace/project1/docker-compose.yml on the docker host, you need to add the volume -v /home/leonid/workspace/project1/:/home/leonid/workspace/project1/ for the jenkins container.
Then, in your Jenkins job:
cd /home/leonid/workspace/project1/
docker-compose up -d
Why is that?
Keep in mind that docker-compose gives instructions to the docker engine. The docker engine runs on the docker host (and not in the Jenkins container). So any path given by docker-compose to the docker engine must exist on the docker host.
Create your own dockerfile that is based on image you use for build (probably docker:latest)
Then, in RUN line put downloading the docker-compose and setting it as executable.
Spin up jenkins agent to build from your image instead default one.
you need to install docker-compose on that build container, not on jenkins master.
For builds in gitlab-ci I had a special build container that based on docker image with compose installed additionally. I think this is your case - you are using jenkins to spin a container based on docker:latest which by default does not have docker-compose. You need to either create own image that is from docker:latest, install compose or use some image from docekrhub that is done like this.
Also, you could try to install compose as part of your build. Just download it to some local dir and use it from there.
The "Install as a container" section in the docs worked for me: https://docs.docker.com/compose/install/
sudo curl -L --fail https://github.com/docker/compose/releases/download/1.25.0/run.sh -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

How to copy SSH from JENKINS host into a DOCKER container?

I can't copy the file from the host into the container using the Dockerfile, because i'm simply not allowed to, as mentioned in Docker Documentation:
The path must be inside the context of the build; you cannot
COPY ../something /something, because the first step of a docker build
is to send the context directory (and subdirectories) to the docker
daemon.
I'm also unable to do so from inside jenkins job, because the job commands run inside the shell of the docker container, there is not way to talk to the parent(which is the jenkins host).
This jenkins plugin could have been a life saver, but as mentioned in the first section: distribution of this plugin has been suspended due to unresolved security vulnerabilities.
This is how I copy files from host to docker image using Dockerfile
I have a folder called tomcat
Inside that, I have a tar file and Dockerfile
Commands to do the whole process just for understanding
$ pwd
/home/user/Documents/dockerfiles/tomcat/
$ ls
apache-tomcat-7.0.84.tar.gz Dockerfile
Sample Docker file:
FROM ubuntu_docker
COPY apache-tomcat-7.0.84.tar.gz /home/test/
...
Docker commands:
$ docker build -it testserver .
$ docker run -itd --name test1 testserver
$ docker exec -it bash
Now you are inside docker container
# ls
apache-tomcat-7.0.84.tar.gz
As you can see I am able to copy apache-tomcat-7.0.84.tar.gz from host to Docker container.
Notice the Docker Documentation first line which you have shared
The path must be inside the context of the build;
So as long as the path is reachable during build you can copy.
Another way of doing this would be using volume
docker run -itd -v $(pwd)/somefolder:/home/test --name test1 testserver
Notice -v parameter
You are telling Docker to mount Current_Directory/somefolder to Docker's path at /home/test
Once the container is up and running you can simply copy any file to $(pwd)/somefolder and it will get copied
inside container at /home/test

Resources