Reputation: 3857
Jenkins with docker-pipeline is downloading my git repository, and installing it.
pipeline {
agent {
docker {
image 'node:6-alpine'
args '-p 8989:8989'
}
}
stages {
stage("install") {
steps {
sh 'npm install -production'
}
}
}
}
But then it's cleaning up and deleting the image:
$ docker stop --time=1 4b3220d100fae5d903db600992e91fb1ac391f1226b2aee01c6a92c3f0ff009c $ docker rm -f 4b3220d100fae5d903db600992e91fb1ac391f1226b2aee01c6a92c3f0ff009c
All of the many deployment examples online are for publishing to a registry.
how do I just stop it being cleaned up?
How do I name & save and the image locally ?
Upvotes: 2
Views: 3508
Reputation: 42254
You may want to use dockerfile
agent instead of the docker
one. It uses a Dockerfile that is part of your project to build the local docker image. All image layers will be cached, so the next time you run the build, it won't spend time on re-building the image. It is also useful to put commands like npm install -production
inside the Dockerfile, so those dependencies are downloaded and installed only one time.
Take a look at the following example.
Dockerfile:
FROM node:6-alpine
RUN npm install -production
Jenkinsfile:
pipeline {
agent {
dockerfile {
filename "Dockerfile"
args '-p 8989:8989'
additionalBuildArgs "-t my-custom-node:latest"
}
}
stages {
stage("Test") {
steps {
sh "npm --version" // this command gets executed inside the container
}
}
}
}
The output:
Running on Jenkins in /home/wololock/.jenkins/workspace/pipeline-dockerfile
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Declarative: Agent Setup)
[Pipeline] isUnix
[Pipeline] readFile
[Pipeline] sh
+ docker build -t a3f11e979e510758f10ac738e7e4e5c1160db2eb -f Dockerfile .
Sending build context to Docker daemon 2.048 kB
Step 1/2 : FROM node:6-alpine
Trying to pull repository docker.io/library/node ...
sha256:17258206fc9256633c7100006b1cfdf25b129b6a40b8e5d37c175026482c84e3: Pulling from docker.io/library/node
bdf0201b3a05: Pulling fs layer
e9fa13fdf0f5: Pulling fs layer
ccc877228d8f: Pulling fs layer
ccc877228d8f: Verifying Checksum
ccc877228d8f: Download complete
bdf0201b3a05: Verifying Checksum
bdf0201b3a05: Download complete
bdf0201b3a05: Pull complete
e9fa13fdf0f5: Verifying Checksum
e9fa13fdf0f5: Download complete
e9fa13fdf0f5: Pull complete
ccc877228d8f: Pull complete
Digest: sha256:17258206fc9256633c7100006b1cfdf25b129b6a40b8e5d37c175026482c84e3
Status: Downloaded newer image for docker.io/node:6-alpine
---> dfc29bfa7d41
Step 2/2 : RUN npm install -production
---> Running in e058ab280807
[91mnpm[0m[91m WARN[0m[91m enoent[0m[91m ENOENT: no such file or directory, open '/package.json'
[0m[91mnpm [0m[91mWARN[0m[91m !invalid#1 No description
[0m[91mnpm[0m[91m [0m[91mWARN[0m[91m !invalid#1 No repository field.
[0m[91mnpm [0m[91mWARN[0m[91m !invalid#1 No README data
[0m[91mnpm [0m[91mWARN[0m[91m !invalid#1 No license field.
[0m ---> d685094800d9
Removing intermediate container e058ab280807
Successfully built d685094800d9
[Pipeline] dockerFingerprintFrom
[Pipeline] }
[Pipeline] // stage
[Pipeline] sh
+ docker inspect -f . a3f11e979e510758f10ac738e7e4e5c1160db2eb
.
[Pipeline] withDockerContainer
Jenkins does not seem to be running inside a container
$ docker run -t -d -u 1000:1000 -w /home/wololock/.jenkins/workspace/pipeline-dockerfile -v /home/wololock/.jenkins/workspace/pipeline-dockerfile:/home/wololock/.jenkins/workspace/pipeline-dockerfile:rw,z -v /home/wololock/.jenkins/workspace/pipeline-dockerfile@tmp:/home/wololock/.jenkins/workspace/pipeline-dockerfile@tmp:rw,z -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** a3f11e979e510758f10ac738e7e4e5c1160db2eb cat
$ docker top 84ca2e4a30487f114de81dbd60e53219a8cfa3959fb5b05d2c908f872bfe790c -eo pid,comm
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] sh
+ npm --version
3.10.10
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
$ docker stop --time=1 84ca2e4a30487f114de81dbd60e53219a8cfa3959fb5b05d2c908f872bfe790c
$ docker rm -f 84ca2e4a30487f114de81dbd60e53219a8cfa3959fb5b05d2c908f872bfe790c
[Pipeline] // withDockerContainer
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
In this example I used additionalBuildArgs
option to add additional tag. Now, when I do docker images
on my host, I can see this image as:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-custom-node latest d685094800d9 About a minute ago 56.1 MB
docker.io/node 6-alpine dfc29bfa7d41 6 months ago 56.1 MB
This is the good first step to start with. If at some point you will find building the docker image too consuming, you can consider building this image in the separate pipeline and push it to some private repository. But because docker caches all layers, I wouldn't think about remote docker repository at this stage. Use local Dockerfile, experiment with your build environment and then see if publishing the docker image would be any improvement for you.
And btw, Jenkins Pipeline terminates the docker container when it terminates the Jenkins job. Your current workspace is mounted and the container workspace is set to the current Jenkine job one, so any file(s) that get created inside your workspace inside the container will be persisted.
To read more about Jenkins Pipeline agents, go here - https://jenkins.io/doc/book/pipeline/syntax/#agent
Upvotes: 2