问题
I am trying to "dockerize" an existing Rails development app. This is my first time experimenting with Docker.
I want to set up Guard to listen for file changes and run relevant specs.
The Guard service appears to be running correctly, and the logs show:
guard_1 | 16:35:12 - INFO - Guard is now watching at '/app'
But when I edit/save spec files Guard is not running any tests.
This is an existing app that I'm moving into Docker. It has a guardfile that works outside of Docker.
I've searched and read a number of posts (e.g. this one), but I'm not sure where to start debugging this. Can anyone point me in the right direction and get Guard listening to file changes.
My docker-compose.yml looks like this:
version: '3'
services:
postgres:
ports:
- "5432:5432"
volumes:
- $HOME/postgres-data:/var/lib/postgresql
image: postgres:9.6.9
redis:
ports:
- "6379:6379"
depends_on:
- postgres
image: redis:5.0-rc
web:
build: .
ports:
- "3000:3000"
command: /bin/sh -c "rails s -b 0.0.0.0 -p 3000"
depends_on:
- postgres
- redis
env_file:
- .env
guard:
build: .
env_file:
- .env
command: bundle exec guard --no-bundler-warning --no-interactions
sidekiq:
build: .
command: bundle exec sidekiq -C config/sidekiq.yml
depends_on:
- postgres
- redis
env_file:
- .env
volumes:
redis:
postgres:
sidekiq:
guard:
Guardfile
guard 'spring', bundler: true do
watch('Gemfile.lock')
watch(%r{^config/})
watch(%r{^spec/(support|factories)/})
watch(%r{^spec/factory.rb})
end
guard :rspec, cmd: "bundle exec rspec" do
require "guard/rspec/dsl"
dsl = Guard::RSpec::Dsl.new(self)
# RSpec files
rspec = dsl.rspec
watch(rspec.spec_files)
# Ruby files
ruby = dsl.ruby
dsl.watch_spec_files_for(ruby.lib_files)
# Rails files
rails = dsl.rails(view_extensions: %w(erb haml slim))
dsl.watch_spec_files_for(rails.app_files)
dsl.watch_spec_files_for(rails.views)
watch(rails.controllers) do |m|
[
rspec.spec.call("routing/#{m[1]}_routing"),
rspec.spec.call("controllers/#{m[1]}_controller"),
rspec.spec.call("acceptance/#{m[1]}")
]
end
# Rails config changes
watch(rails.spec_helper) { rspec.spec_dir }
watch(rails.routes) { "#{rspec.spec_dir}/routing" }
watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
# Capybara features specs
watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
# Turnip features and steps
watch(%r{^spec/acceptance/(.+)\.feature$})
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
end
ignore %r{^spec/support/concerns/}
end
guard 'brakeman', :run_on_start => true do
watch(%r{^app/.+\.(erb|haml|rhtml|rb)$})
watch(%r{^config/.+\.rb$})
watch(%r{^lib/.+\.rb$})
watch('Gemfile')
end
回答1:
I'm assuming you're making changes on your local filesystem and expected guard, inside the container, to trigger.
If so, the missing link is your docker-compose.yml
file.
guard:
build: .
env_file:
- .env
command: bundle exec guard --no-bundler-warning --no-interactions
volumes:
- .:/app
You need to mount the volume of your root (Rails root) directory inside the container so that the changes are reflected. Without this line, your container(s) only sees what was available at build time, and not the changes.
回答2:
I faced the exact same problem and have been wondering about existing solutions that didn't really work. The key solution to your problem (if you are on OSX of course) is to understand the difference between "Docker Toolbox" and "Docker for Mac".
This article gives a lot of insight: https://docs.docker.com/docker-for-mac/docker-toolbox/
TL;DR
If you are on Mac, you need to use Docker for Mac to have the benefits of osxfs. If you do this you will not need docker-sync!
来源:https://stackoverflow.com/questions/54026795/why-is-guard-not-detecting-file-changes-after-dockerizing-rails-app