smartechno
smartechno

Reputation: 490

Execute command inside docker image and save it in Jenkinsfile

I am working on Jenkins file which is pulling docker image and execute some command inside this docker image then after I want to save this image and push it into AWS ECR. in here execute commands inside a docker container and push the docker image to ECR part is working and have no clue about how to commit(save) updated docker image.

Excute commands inside

stage('Run inside Docker container') {
  agent {
    docker { image 'test/testimage:619c95b' }
  }
  steps {
    sh 'ls & pwd & ps'
  }
}

Save Docker image

???

Push to AWS ECR

steps {
    script {
      docker.withRegistry('https://xxxxxxxxxxx.dkr.ecr.us-east-2.amazonaws.com/', 'ecr:us-east-2:aws-xx-automation') {
        image.push("${env.tag}")
      }
    }
  }

Upvotes: 0

Views: 1879

Answers (2)

David Maze
David Maze

Reputation: 159781

You can build this into a straightforward Dockerfile:

FROM test/testimage:619c95b  # docker { image ... }
RUN ls && pwd && ps          # sh "..."

You can test and run the resulting image on your developer system. (I have not had good luck locally testing complex Jenkins pipelines.)

Now your Jenkins pipeline code can build and push that image:

steps {
  script {
    image = docker.build("${env.tag}")
    docker.withRegistry('https://xxxxxxxxxxx.dkr.ecr.us-east-2.amazonaws.com/', 'ecr:us-east-2:aws-xx-automation') {
      image.push()
    }
  }
}

The approach you describe (probably) isn't technically possible. If you look at the Jenkins logs, you'll see a very long docker run command, that (among other things) has a -v option to mount the build workdir into the image on the same path. That means any changes you make within the build workdir aren't able to be committed into an image, they only live within that Jenkins-managed directory.

Upvotes: 1

Alejandro Galera
Alejandro Galera

Reputation: 3691

First of all, I'm not pretty sure that the way you purpose is the best practice. Independently of that, I'll answer you problem in your way.

Commands are executed in a docker container = instance of a docker image, not a docker image. So, stage should be named as 'Run inside Docker container from image foo'

After creating a docker container from your image 'test/testimage:619c95b' named mycontainer, for example, you could save your image with

docker commit <mycontainer> <mynew docker image tag>

With this step, image is saved with your container current snapshot.

Finally, set/export env.tag with <mynew docker image tag> and do

docker.withRegistry('https://xxxxxxxxxxx.dkr.ecr.us-east-2.amazonaws.com/',
  'ecr:us-east-2:aws-xx-automation') {
        image.push("${env.tag}")

Upvotes: 1

Related Questions