Skip to content

Instantly share code, notes, and snippets.

@9re
Created December 13, 2018 16:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 9re/186566532864be30d0fa53e7e6143420 to your computer and use it in GitHub Desktop.
Save 9re/186566532864be30d0fa53e7e6143420 to your computer and use it in GitHub Desktop.
Rake command to sync files in host to container
require 'docker'
require 'listen'
APP_NAME = 'hoge'
def retrieve_file(app_root, file)
dir = File.dirname(file)
container_dir = dir.to_s.sub(Regexp.new(app_root + '/'), '')
container_file = file.to_s.sub(Regexp.new(app_root + '/'), '')
return container_dir, container_file
end
def exec(container, args)
std_out, std_err, _ = container.exec(args)
puts std_out if std_out
puts std_err if std_err
end
def get_app_container
Docker::Container.all.find {|container| Regexp.new(APP_NAME).match?(container.info['Image'])}
end
namespace :docker do
desc 'sync files from host'
task sync: :environment do
ignore_patterns = %w(Gemfile.lock)
app_root = Rails.root.to_s
app_root_in_container = '/var/www/brabrabra'
app_container = get_app_container
if app_container.nil?
puts "Error: docker container not found: #{APP_NAME}"
return
end
listener = Listen.to('.') do |modified, added, removed|
([*modified, *added]).each do |file|
container_dir, container_file = retrieve_file(app_root, file)
if ignore_patterns.include?(container_file)
puts "ignore file: #{container_file}"
next
end
dir, errors, _ = app_container.exec(['ls', container_dir])
if dir.length.zero? and errors.length > 0
app_container.exec(['mkdir', '-p', container_dir])
end
`docker cp #{file} #{app_container.id}:#{app_root_in_container}/#{container_file}`
puts "updated: #{container_file}"
if container_file.eql?('Gemfile')
exec(app_container, %w(bundle install))
end
end
removed.each do |file|
_, container_file = retrieve_file(app_root, file)
exec(app_container, ['rm', '-v', container_file])
end
end
listener.start
sleep
end
desc 'execute a command in container'
task :exec, ['command'] => :environment do |task, args|
exec(get_app_container, args[:command].split(' '))
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment