Jenkinsfile with writeFile inside docker container? - docker

If I have a Jenkinsfile with
docker.image('foo').inside {
writeFile file: bar, text: baz
}
the file gets written to the Jenkins agent's workspace, not inside the container, right? Is there a sane way to write a file inside a container?
The closest thing I was able to find on the web is https://issues.jenkins-ci.org/browse/JENKINS-33510. I suppose I could use a sh step with a here-doc, but that sounds pretty ugly.

There is a workspace in the container and you can write files inside the container with writeFiles.
But it's also shared with the workspace of the host node because it's mounted as a volume.
inside will:
Automatically grab a slave and a workspace (no extra node block is
required).
Pull the requested image to the Docker server (if not already cached).
Start a container running that image.
Mount the Jenkins workspace as a “volume” inside the container, using
the same file path.
You can see more detail what happens in inside here: https://go.cloudbees.com/docs/cloudbees-documentation/cje-user-guide/chapter-docker-workflow.html

Related

Build from parent directory with Jenkins

We are adapting monorepo to our project and we organized the code to three folders in which one of them is a shared_code between the two other projects.
When changes done in one of the project or the shared code a build triggered according the changes and a docker image is build and pushed to a docker registry.
project1
-Dockerfile
-Jenkinsfile
project2
-Dockerfile
-Jenkinsfile
shared_code
Jenkinfile
Since we using docker with a shared code, so the build should be done from parent directory as docker doesn't expect files from parent directory to be included.
Something like this should be done:
docker build -t project1:tag -f project1/Dockerfile .
This all still fine, but when using Jenkins I defined Jenkinsfile inside project1, so when I build project1 from Jenkins I fall to the issue that says docker doesn't access parent directory, and at the same time I don't wanna to take the Jenkinsfile to the parent folder in order to keep a certain organization.
Is there a way I could configure the directory that Jenkins takes for the build in the Jenkinsfile?
I came back to answer my quetion if someone is facing the same challenge.
This is what helped me to build the image from Jenkins:
stage("Build image") {
// Build the docker image with a tag
steps {
script {
dockerImage = docker.build("project1:${env.BUILD_ID}", "-f ./project1/Dockerfile .")
}
}
}

Mount repo into docker image when running yaml-pipeline in Azure DevOps

I am running a docker image in Azure Devops yaml-pipeline using a container step. However, I have problems mounting the content of the repo so that this is accessible from inside the docker image.
The Azure Devops pipeline.yml file is as follows:
container:
image: 'image-name'
endpoint: 'foo'
options: '-v $(Build.SourcesDirectory):/testing'
steps:
- script: echo Hello, world!
displayName: 'Run a one-line script inside docker image'
This fails with the error message:
Error response from daemon: create $(Build.SourcesDirectory): "$(Build.SourcesDirectory)" includes
invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended
to pass a host directory, use absolute path
I also tried replacing $(..)$ with $[..] (see here but this results in the same error. Also with ${{..}} the pipeline will not even start (error: "A template expression is not allowed in this context" in the UI)
If I remove options the script runs, but the repo is not mounted.
For non-yaml pipelines, the question was addressed here.
Any ideas how to accomplish this? Or do I need to create a new docker image where the repo files have been add:ed?
Any ideas how to accomplish this? Or do I need to create a new docker
image where the repo files have been add:ed?
When specifying the Container using Yaml Schema directly, the Azure DevOps Service will call an extra Initialize containers task automatically before checkout source repo task and your real tasks.
container:
image: 'image-name'
steps:
- script: echo Hello, world!
displayName: 'Run a one-line script inside docker image'
During the Initialize containers task, the predefined variables like Agent.BuildDirectory, Build.Repository.LocalPath and Build.SourcesDirectory are not expanded (non-defined variables).
So you can't use the Build.SourcesDirectory in this way cause the value of this variable is expanded after the Initialize containers task.
1.About why the link you shared above can work: It's in a docker task/step so it can recognize the $(Build.SourcesDirectory) variable. (The real build tasks run after the build variables are defined)
2.If you're using specific Micorosft-hosted agent, you can try hard-coding the path. You can check this similar issue.
Usually for windows-hosted agent: $(Build.SourcesDirectory)=> D:\a\1\s
For Ubuntu-hosted agent: $(Build.SourcesDirectory)=> /home/vsts/work/1/s.

How to specify custom path for remote node on Jenkins?

I've a Jenkins server. It runs on D:\Jenkins.
In my jenkins file, I've the following:
pipeline {
agent {
node{
label 'windows-node'
customWorkspace "${JENKINS_HOME}\\${env.BRANCH_NAME}"
}
}
//...
}
This was working fine and tries to use the D:\jenkins\feature\testbranch (by example).
I now setup a new node, and it has only one disk, C:\
The remote node has the Remote root directory configured as C:/ws. So I was expecting that my output folder would be C:/ws/feature/testbranch.
But it seems it tries to access the D:\jenkins\feature\testbranch on the remote node. How to use the node specific root folder in an Jenkins file?
So that variable appears to be specific to the master. You probably need a environment variable which will point to a location that is consistent across your slaves (like WKSPC_LOC), set it in your windows environment and use something like customWorkspace "${WKSPC_LOC}\${env.BRANCH_NAME}", note that you still need to set this up in every slave. In general for CI, having different things being treated same creates problems. So a slave should be the same (consistent). As of now I don't think there is way to have different workspace locations for master and slave. In linux you could have used sym links, but I can't think of a solution for windows, except what I mentioned before, but I still doubt it will work.

Creating Docker image and running as service in Jenkins

I have a JSP website. I am building DevOps pipeline. I am looking for help to integrate Jenkins with the Docker.
I already have docker file which does task of Deploying war file to the tomcat server.
(Command1)
Through the command line I can run the docker file and create an image.
I can run created image as a service and able to browse the website.
(Command2)
I want to do these two steps in Jenkins. I need your help to integrate these two commands in Jenkins, so that I need not to run these two commands manually one after other.
I think that you can use the "Docker Pipeline Plugin" for that.
For the first command, you can have a stage that runs:
myImage = docker.build("my-image:my-tag")
If you need you can have another stage where you can run some tests inside the image with:
myImage.inside {
sh './run-test.sh'
}
Finally, you can push the image to the repository to your repository with:
docker.withRegistry('https://your-registry.com', 'credentials_id') { //use a second parameter if you repository requires authentication
myImage.push('new_tag') //You can push it with a new tag
}
Please note that if you wanna use the docker.* methods in a declarative pipeline you must do it inside a script step or in a function.
(More info in the plugin's user guide)
For the second command, you only have to update the running image in the server. For doing that you have a lot of options (docker service update if you're using Docker Swarm, for example) and I think that part is outside of the scope of this post.

Jenkins build an image for Docker?

I'm a beginner with Jenkins CI integration with Docker.
My virtual machine tcp://192.168.99.100:2376
I created an image "personluz" with my SVN source code and the configuration like this image
image config
But the result is:
error
FATAL: Cannot run program "docker": error=2, No such file or directory
Could anyone have some idea? Thanks
First, the tag highlighted in the first picture is not the one for the personluz image (it is one of a dangling image)
The tag for personluz is b7782bf4cf30.
Second, a Cannot run program "docker": error=2 means that, in the context of the Jenkins slave executing the job, docker is not found in the Jenkins user $PATH. Make sure it is properly installed for that Jenkins user.

Resources