Recently I have the case where I have to use a base Docker image from a remote or local repository. I love to keep the configuration close and to not have a couple of configuration files with the same content so I decided to write a simple program which will do the config switch and then will return it back (if needed)
Here is an example of usage:
When I build the images locally I want to use:
FROM anaconda-environment:latest
When I want to build from our CI/CD server I would like to use the remote ECR
CONFIG->remote-images:FROM XXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com/anaconda-environment:latest
Then in the Docker file, I put those lines
# CONFIG->local-images:FROM anaconda-environment:latest # CONFIG->remote-images:FROMXXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com/anaconda-environment:latest FROM anaconda-environment:latest ENV ACCEPT_INTEL_PYTHON_EULA=yes .... and so on...
And here is how the config is changed to point to the remote-images
ruby switch-config.rb Dockerfile remote-images
and this is how it is changed back to local images.
ruby switch.rb Dockerfile local-images
So far I haven’t found any drawback on this approach. For sure there is some drawbacks please let me know if you hit it.
And here is the code…
#!/usr/bin/env ruby # ruby switch.rb Dockerfile remote-images # # # CONFIG->local-images:FROM anaconda-environment:latest # # CONFIG->remote-images:FROM XXXXXXXXXXX.dkr.ecr.us-east-1.amazonaws.com/anaconda-environment:latest # FROM anaconda-environment:latest file = ARGV[0] || "Dockerfile" desired_environment = ARGV[1] || "local" lines = File.read(file).split("\n") tag = /\s*?#\s+CONFIG->([\w\-]+?):(.*)\Z/ new_lines = [] key_found = true options = {} found_config_lines = false lines.each do |line| if line =~ tag environment_key = $1 option = $2 options[environment_key] = option found_config_lines = true end if found_config_lines && options.values.include?(line) key_found = options.key?(desired_environment) new_lines << options[desired_environment] found_config_lines = false options = {} else new_lines << line end end if key_found File.write(file, new_lines.join("\n")) else puts "Something is wrong - key not found! The syntax for defining options is:" puts "# CONFIG->KEY:The content of this option" end