2

I'm trying to perform docker save -o on all images in a docker-compose.yaml file in one command.

what I've managed to do is:

cat docker-compose.yaml | grep image and this will give:

 image: hub.myproject.com/dev/frontend:prod_v_1_2
 image: hub.myproject.com/dev/backend:prod_v_1_2
 image: hub.myproject.com/dev/abd:v_2_3
 image: hub.myproject.com/dev/xyz:v_4_6

I need to perform the following command for each image:

docker save -o frontend_prod_v_1_2.tar hub.myproject.com/dev/frontend:prod_v_1_2

What I have managed to achieve is :

cat docker-compose.yml | grep image | cut -d ':' -f 2,3 which gives:

 hub.myproject.com/dev/frontend:prod_v_1_2
 hub.myproject.com/dev/backend:prod_v_1_2
 hub.myproject.com/dev/abd:v_2_3
 hub.myproject.com/dev/xyz:v_4_6

I can furthur do:

cat docker-compose.yml | grep image | cut -d ':' -f 2,3 | cut -d '/' -f3 | cut -d ':' -f1,2

which gives:

 frontend:prod_v_1_2
 backend:prod_v_1_2
 abd:v_2_3
 xyz:v_4_6

Then I'm not sure what to do. I have tried to use xargs to pass as a variable but I don't know how to change xargs from frontend:prod_v_1_2 to frontend_prod_v_1_2.tar on the fly in the command line. Also, I still need the full image name and tag at the end.

I'm looking for something like:

cat docker-compose.yml | grep image | cut -d ':' -f 2,3 | xargs -I {} docker save -o ``{} | cut -d '/' -f3 | cut -d ':' -f1,2 | xargs -I {} {}.tar`` {}

any bash magicians can offer a hint?

1 Answer 1

1

Your pipeline approach could convoluted as you add more and more commands. Just use the prowess of your native shell, in this case bash for operations like this. Pipe the output of grep image docker-compose.yml into a while..read loop and perform substitutions with it.

In a proper shell script this could be done as

#!/usr/bin/env bash
# '<(..)' is a bash construct i.e process substitution to run the command and make 
# its output appear as if it were from a file
# https://mywiki.wooledge.org/ProcessSubstitution

while IFS=: read -r _ image; do
    # Strip off the part up the last '/'
    iname="${image##*/}"
    # Remove ':' from the image name and append '.tar' to the string and 
    # replace spaces in the image name
    docker save -o "${iname//:/_}.tar" "${image// }"
done < <(grep image docker-compose.yml)

On the command line, instead of xargs I would use awk directly to run the docker save operation

awk '/image/ { 
       n = split($NF, arr, "/"); 
       iname = arr[n]".tar"; 
       sub(":", "_", iname); fname = $2;  
       cmd = "docker save -o " iname " " fname; 
       system(cmd);
    }' docker-compose.yml
2
  • 1
    awk is so powerful! May 18, 2020 at 10:12
  • a follow up question: what is the meaning of _ in read -r _ image? I've searched a lot but couldn't find any information about using underscore with read .. May 18, 2020 at 16:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .