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