dockside 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +27 -0
- data/LICENSE.txt +21 -0
- data/README.md +479 -0
- data/lib/dockside/autostart.rb +33 -0
- data/lib/dockside/commands.rb +60 -0
- data/lib/dockside/compose.rb +68 -0
- data/lib/dockside/dependency.rb +216 -0
- data/lib/dockside/docker.rb +61 -0
- data/lib/dockside/errors.rb +42 -0
- data/lib/dockside/override.rb +51 -0
- data/lib/dockside/project.rb +133 -0
- data/lib/dockside/provisioner.rb +81 -0
- data/lib/dockside/railtie.rb +16 -0
- data/lib/dockside/readiness.rb +120 -0
- data/lib/dockside/registry.rb +55 -0
- data/lib/dockside/runner.rb +55 -0
- data/lib/dockside/settings.rb +38 -0
- data/lib/dockside/version.rb +3 -0
- data/lib/dockside.rb +101 -0
- data/lib/generators/dockside/install_generator.rb +15 -0
- data/lib/generators/dockside/templates/dockside.yml.tt +25 -0
- data/lib/tasks/dockside.rake +38 -0
- metadata +97 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
require "net/http"
|
|
2
|
+
require "socket"
|
|
3
|
+
|
|
4
|
+
module Dockside
|
|
5
|
+
# Probes that tell whether a started container really answers.
|
|
6
|
+
module Readiness
|
|
7
|
+
def self.probe_for(dependency, spec)
|
|
8
|
+
case spec
|
|
9
|
+
when "auto" then dependency.port ? Tcp.new(dependency.port) : None.new
|
|
10
|
+
when "none" then None.new
|
|
11
|
+
when Hash then probe_from_hash(dependency, spec)
|
|
12
|
+
else raise ConfigError, "#{dependency.name}: ready must be auto, none, {http:}, {log:} or {command:}, got #{spec.inspect}"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.probe_from_hash(dependency, spec)
|
|
17
|
+
if spec.key?("http")
|
|
18
|
+
Http.new("#{dependency.url}#{spec["http"]}", status: spec["status"])
|
|
19
|
+
elsif spec.key?("log")
|
|
20
|
+
Log.new(dependency, spec["log"])
|
|
21
|
+
elsif spec.key?("command")
|
|
22
|
+
Command.new(dependency, spec["command"])
|
|
23
|
+
else
|
|
24
|
+
probe_for(dependency, "auto")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Polls the probe until it answers. Raises ReadyTimeout, whose message the caller enriches with logs.
|
|
29
|
+
def self.wait(probe, timeout:)
|
|
30
|
+
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + timeout
|
|
31
|
+
until probe.ready?
|
|
32
|
+
raise ReadyTimeout if Process.clock_gettime(Process::CLOCK_MONOTONIC) > deadline
|
|
33
|
+
|
|
34
|
+
sleep Dockside.poll_interval
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class Tcp
|
|
39
|
+
def initialize(port)
|
|
40
|
+
@port = port
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Docker accepts connections on a published port before the service inside listens and closes
|
|
44
|
+
# them right away, so a connection only counts when it stays open or the service says something.
|
|
45
|
+
def ready?
|
|
46
|
+
Socket.tcp("127.0.0.1", @port, connect_timeout: 1) do |socket|
|
|
47
|
+
return true unless socket.wait_readable(0.2)
|
|
48
|
+
|
|
49
|
+
!socket.read_nonblock(1, exception: false).nil?
|
|
50
|
+
end
|
|
51
|
+
rescue SystemCallError, IOError
|
|
52
|
+
false
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def to_s
|
|
56
|
+
"port #{@port} accepts connections"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class Http
|
|
61
|
+
def initialize(url, status: nil)
|
|
62
|
+
@uri = URI(url)
|
|
63
|
+
@status = status
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def ready?
|
|
67
|
+
response = Net::HTTP.start(@uri.host, @uri.port, open_timeout: 1, read_timeout: 5) do |http|
|
|
68
|
+
http.get(@uri.request_uri)
|
|
69
|
+
end
|
|
70
|
+
@status.nil? || response.code.to_i == @status
|
|
71
|
+
rescue SystemCallError, IOError, Net::OpenTimeout, Net::ReadTimeout
|
|
72
|
+
false
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def to_s
|
|
76
|
+
"#{@uri} answers#{" with status #{@status}" if @status}"
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
class Log
|
|
81
|
+
def initialize(dependency, pattern)
|
|
82
|
+
@dependency = dependency
|
|
83
|
+
@pattern = Regexp.new(pattern)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def ready?
|
|
87
|
+
@dependency.logs(tail: 200).match?(@pattern)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def to_s
|
|
91
|
+
"log matches #{@pattern.source}"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
class Command
|
|
96
|
+
def initialize(dependency, command)
|
|
97
|
+
@dependency = dependency
|
|
98
|
+
@command = command
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def ready?
|
|
102
|
+
@dependency.exec_succeeds?(@command)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def to_s
|
|
106
|
+
"command #{Array(@command).join(" ")} succeeds"
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
class None
|
|
111
|
+
def ready?
|
|
112
|
+
true
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def to_s
|
|
116
|
+
"container is running"
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Dockside
|
|
2
|
+
# All dependencies of the app for one environment, built once from the resolved compose file.
|
|
3
|
+
class Registry
|
|
4
|
+
include Enumerable
|
|
5
|
+
|
|
6
|
+
def initialize(project)
|
|
7
|
+
@project = project
|
|
8
|
+
@dependencies = build
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def names
|
|
12
|
+
@dependencies.keys
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def fetch(name)
|
|
16
|
+
@dependencies.fetch(name.to_sym) do
|
|
17
|
+
raise UnknownDependency, "Unknown dependency #{name}. Known: #{names.join(", ")}."
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
alias_method :[], :fetch
|
|
21
|
+
|
|
22
|
+
def each(&block)
|
|
23
|
+
@dependencies.each_value(&block)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def autostart
|
|
27
|
+
select(&:autostart?)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def build
|
|
33
|
+
resolved = @project.resolve!
|
|
34
|
+
@project.service_names.to_h do |service|
|
|
35
|
+
dependency = Dependency.new(
|
|
36
|
+
name: service,
|
|
37
|
+
project: @project,
|
|
38
|
+
settings: @project.settings(service),
|
|
39
|
+
config: resolved.fetch(service),
|
|
40
|
+
shared: shared?(service)
|
|
41
|
+
)
|
|
42
|
+
[service.to_sym, dependency]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def shared?(service)
|
|
47
|
+
port = @project.host_port(service, @project.env)
|
|
48
|
+
return false if port.nil? || port != @project.host_port(service, @project.other_env)
|
|
49
|
+
|
|
50
|
+
Dockside.log "warning: #{service} uses port #{port} in development and test, " \
|
|
51
|
+
"so both environments share one container and its data"
|
|
52
|
+
true
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require "open3"
|
|
2
|
+
|
|
3
|
+
module Dockside
|
|
4
|
+
# Runs commands given as argv arrays, never as shell strings.
|
|
5
|
+
class Runner
|
|
6
|
+
Result = Struct.new(:argv, :stdout, :stderr, :exit_status) do
|
|
7
|
+
def success?
|
|
8
|
+
exit_status.zero?
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Returns a Result. With stream: true the output is also printed while the command runs.
|
|
13
|
+
def run(argv, env: {}, stdin: nil, chdir: nil, stream: false)
|
|
14
|
+
if stream
|
|
15
|
+
stream_run(argv, env: env, chdir: chdir)
|
|
16
|
+
else
|
|
17
|
+
capture_run(argv, env: env, stdin: stdin, chdir: chdir)
|
|
18
|
+
end
|
|
19
|
+
rescue Errno::ENOENT
|
|
20
|
+
raise DockerMissing, "#{argv.first} was not found. Install Docker with the Compose plugin " \
|
|
21
|
+
"(https://docs.docker.com/get-docker/) or start with DOCKSIDE_AUTOSTART=0 to skip the containers."
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def run!(argv, **options)
|
|
25
|
+
result = run(argv, **options)
|
|
26
|
+
raise CommandFailed.new(result) unless result.success?
|
|
27
|
+
|
|
28
|
+
result
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def capture_run(argv, env:, stdin:, chdir:)
|
|
34
|
+
options = {}
|
|
35
|
+
options[:chdir] = chdir.to_s if chdir
|
|
36
|
+
options[:stdin_data] = stdin if stdin
|
|
37
|
+
stdout, stderr, status = Open3.capture3(env, *argv, **options)
|
|
38
|
+
Result.new(argv: argv, stdout: stdout, stderr: stderr, exit_status: status.exitstatus)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def stream_run(argv, env:, chdir:)
|
|
42
|
+
options = {}
|
|
43
|
+
options[:chdir] = chdir.to_s if chdir
|
|
44
|
+
output = +""
|
|
45
|
+
Open3.popen2e(env, *argv, **options) do |input, combined, wait|
|
|
46
|
+
input.close
|
|
47
|
+
combined.each_line do |line|
|
|
48
|
+
Dockside.output.print(line)
|
|
49
|
+
output << line
|
|
50
|
+
end
|
|
51
|
+
Result.new(argv: argv, stdout: output, stderr: "", exit_status: wait.value.exitstatus)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Dockside
|
|
2
|
+
# The x-dockside part of a service, merged for one environment.
|
|
3
|
+
Settings = Struct.new(:ready, :timeout, :after_start, :autostart)
|
|
4
|
+
|
|
5
|
+
class Settings
|
|
6
|
+
KEYS = %w[ready timeout after_start autostart].freeze
|
|
7
|
+
DEFAULTS = {"ready" => "auto", "timeout" => 300, "after_start" => [], "autostart" => true}.freeze
|
|
8
|
+
|
|
9
|
+
def self.for(service, definition, env)
|
|
10
|
+
extension = definition["x-dockside"] || {}
|
|
11
|
+
environment_block = extension[env] || {}
|
|
12
|
+
values = DEFAULTS.merge(extension.slice(*KEYS)).merge(environment_block.slice(*KEYS))
|
|
13
|
+
new(**values.transform_keys(&:to_sym)).tap do |settings|
|
|
14
|
+
settings.after_start = Provisioner::Step.parse_all(service, settings.after_start)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.validate(service, extension)
|
|
19
|
+
return if extension.nil?
|
|
20
|
+
|
|
21
|
+
unknown = extension.keys - KEYS - Project::ENVIRONMENTS
|
|
22
|
+
return if unknown.empty?
|
|
23
|
+
|
|
24
|
+
raise ConfigError, "Unknown x-dockside key#{"s" if unknown.size > 1} #{unknown.join(", ")} for service #{service}. " \
|
|
25
|
+
"Allowed: #{(KEYS + Project::ENVIRONMENTS).join(", ")}."
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# The compose keys of the environment block, the part compose has to merge.
|
|
29
|
+
def self.compose_overrides(definition, env)
|
|
30
|
+
block = definition.dig("x-dockside", env) || {}
|
|
31
|
+
block.except(*KEYS)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def autostart?
|
|
35
|
+
autostart != false
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/dockside.rb
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require "pathname"
|
|
3
|
+
require "yaml"
|
|
4
|
+
require "zeitwerk"
|
|
5
|
+
|
|
6
|
+
loader = Zeitwerk::Loader.for_gem
|
|
7
|
+
loader.ignore("#{__dir__}/generators")
|
|
8
|
+
loader.ignore("#{__dir__}/tasks")
|
|
9
|
+
loader.ignore("#{__dir__}/dockside/railtie.rb")
|
|
10
|
+
loader.ignore("#{__dir__}/dockside/errors.rb")
|
|
11
|
+
loader.setup
|
|
12
|
+
|
|
13
|
+
require "dockside/errors"
|
|
14
|
+
|
|
15
|
+
# Starts the Docker containers an app needs, described in config/dockside.yml.
|
|
16
|
+
module Dockside
|
|
17
|
+
class << self
|
|
18
|
+
attr_writer :root, :env, :app_name, :runner, :output
|
|
19
|
+
attr_accessor :poll_interval
|
|
20
|
+
|
|
21
|
+
def root
|
|
22
|
+
@root ||= Pathname.new((defined?(Rails) && Rails.root) ? Rails.root : Dir.pwd)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def env
|
|
26
|
+
@env ||= (defined?(Rails) && Rails.env.present?) ? Rails.env.to_s : ENV.fetch("RAILS_ENV", "development")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def app_name
|
|
30
|
+
@app_name ||= default_app_name
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def runner
|
|
34
|
+
@runner ||= Runner.new
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def output
|
|
38
|
+
@output || $stdout
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def project
|
|
42
|
+
@project ||= Project.new(root: root, env: env, app_name: app_name, runner: runner)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def registry
|
|
46
|
+
@registry ||= Registry.new(project)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def reset!
|
|
50
|
+
@root = @env = @app_name = @runner = @project = @registry = nil
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def names
|
|
54
|
+
registry.names
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def fetch(name)
|
|
58
|
+
registry.fetch(name)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def ensure_running!(*names)
|
|
62
|
+
dependencies = names.empty? ? registry.autostart : names.map { |name| fetch(name) }
|
|
63
|
+
dependencies.each(&:ensure_running!)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def down
|
|
67
|
+
registry.each(&:remove_shared_container)
|
|
68
|
+
project.compose.down
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def log(message)
|
|
72
|
+
output.puts("dockside: #{message}")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def respond_to_missing?(name, include_private = false)
|
|
76
|
+
registry.names.include?(name) || super
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def method_missing(name, *args)
|
|
80
|
+
if args.empty? && registry.names.include?(name)
|
|
81
|
+
fetch(name)
|
|
82
|
+
else
|
|
83
|
+
super
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
def default_app_name
|
|
90
|
+
if defined?(Rails) && Rails.application
|
|
91
|
+
Rails.application.class.module_parent_name.underscore.dasherize
|
|
92
|
+
else
|
|
93
|
+
root.basename.to_s.downcase.tr("_ ", "--")
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
Dockside.poll_interval = 1
|
|
100
|
+
|
|
101
|
+
require "dockside/railtie" if defined?(Rails::Railtie)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require "rails/generators"
|
|
2
|
+
|
|
3
|
+
module Dockside
|
|
4
|
+
module Generators
|
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
|
7
|
+
|
|
8
|
+
desc "Creates config/dockside.yml with a commented example"
|
|
9
|
+
|
|
10
|
+
def create_compose_file
|
|
11
|
+
template "dockside.yml.tt", "config/dockside.yml"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# The containers this app needs in development and test. dockside starts them with `rails server` and
|
|
2
|
+
# before the first test. This is a normal compose file; only the `x-dockside` block belongs to the gem.
|
|
3
|
+
#
|
|
4
|
+
# See https://github.com/renuo/dockside for every option.
|
|
5
|
+
services:
|
|
6
|
+
# minio:
|
|
7
|
+
# image: minio/minio
|
|
8
|
+
# command: server /data
|
|
9
|
+
# environment:
|
|
10
|
+
# MINIO_ROOT_USER: minio
|
|
11
|
+
# MINIO_ROOT_PASSWORD: minio-secret
|
|
12
|
+
# ports: ["9000:9000"]
|
|
13
|
+
# volumes:
|
|
14
|
+
# - ./tmp/dockside/${RAILS_ENV}/minio:/data
|
|
15
|
+
# x-dockside:
|
|
16
|
+
# ready: { http: "/minio/health/live" } # auto (port answers), none, {http:}, {log:} or {command:}
|
|
17
|
+
# timeout: 60 # seconds to wait until ready, default 300
|
|
18
|
+
# after_start: # runs once, after the container is ready
|
|
19
|
+
# - exec: mc alias set local http://localhost:9000 $MINIO_ROOT_USER $MINIO_ROOT_PASSWORD
|
|
20
|
+
# - exec: mc mb --ignore-existing local/uploads
|
|
21
|
+
# test: # what differs in the test environment
|
|
22
|
+
# ports: ["9010:9000"]
|
|
23
|
+
# volumes: []
|
|
24
|
+
# Remove the {} below when you add your first service.
|
|
25
|
+
{}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
namespace :dockside do
|
|
2
|
+
names = ->(args) { [args[:names], *args.extras].compact.map(&:strip) }
|
|
3
|
+
|
|
4
|
+
desc "Start the containers (BUILD=1 rebuilds, PULL=1 pulls). Names separated by commas."
|
|
5
|
+
task :up, [:names] => :environment do |_task, args|
|
|
6
|
+
Dockside::Commands.up(names.call(args), build: ENV["BUILD"] == "1", pull: ENV["PULL"] == "1")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
desc "Stop the containers, keep the data"
|
|
10
|
+
task :stop, [:names] => :environment do |_task, args|
|
|
11
|
+
Dockside::Commands.stop(names.call(args))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
desc "Remove the containers, keep the data"
|
|
15
|
+
task down: :environment do
|
|
16
|
+
Dockside::Commands.down
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
desc "Remove the containers and the data, start again"
|
|
20
|
+
task :reset, [:names] => :environment do |_task, args|
|
|
21
|
+
Dockside::Commands.reset(names.call(args))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
desc "Show every container, its state and URL"
|
|
25
|
+
task status: :environment do
|
|
26
|
+
Dockside::Commands.status
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
desc "Show the container log (TAIL=200, FOLLOW=1)"
|
|
30
|
+
task :logs, [:name] => :environment do |_task, args|
|
|
31
|
+
Dockside::Commands.logs(args.fetch(:name), tail: ENV.fetch("TAIL", 100).to_i, follow: ENV["FOLLOW"] == "1")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
desc "Show the compose file the gem really uses"
|
|
35
|
+
task config: :environment do
|
|
36
|
+
Dockside::Commands.config
|
|
37
|
+
end
|
|
38
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: dockside
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Alessandro Rodi
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: railties
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.1'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '7.1'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: zeitwerk
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '2.6'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '2.6'
|
|
40
|
+
description: Describe the containers your app needs in a compose file. dockside starts
|
|
41
|
+
them before the server and the test suite, waits until they are ready, sets them
|
|
42
|
+
up the first time and keeps development and test apart.
|
|
43
|
+
email:
|
|
44
|
+
- alessandro.rodi@renuo.ch
|
|
45
|
+
executables: []
|
|
46
|
+
extensions: []
|
|
47
|
+
extra_rdoc_files: []
|
|
48
|
+
files:
|
|
49
|
+
- CHANGELOG.md
|
|
50
|
+
- LICENSE.txt
|
|
51
|
+
- README.md
|
|
52
|
+
- lib/dockside.rb
|
|
53
|
+
- lib/dockside/autostart.rb
|
|
54
|
+
- lib/dockside/commands.rb
|
|
55
|
+
- lib/dockside/compose.rb
|
|
56
|
+
- lib/dockside/dependency.rb
|
|
57
|
+
- lib/dockside/docker.rb
|
|
58
|
+
- lib/dockside/errors.rb
|
|
59
|
+
- lib/dockside/override.rb
|
|
60
|
+
- lib/dockside/project.rb
|
|
61
|
+
- lib/dockside/provisioner.rb
|
|
62
|
+
- lib/dockside/railtie.rb
|
|
63
|
+
- lib/dockside/readiness.rb
|
|
64
|
+
- lib/dockside/registry.rb
|
|
65
|
+
- lib/dockside/runner.rb
|
|
66
|
+
- lib/dockside/settings.rb
|
|
67
|
+
- lib/dockside/version.rb
|
|
68
|
+
- lib/generators/dockside/install_generator.rb
|
|
69
|
+
- lib/generators/dockside/templates/dockside.yml.tt
|
|
70
|
+
- lib/tasks/dockside.rake
|
|
71
|
+
homepage: https://github.com/coorasse/dockside
|
|
72
|
+
licenses:
|
|
73
|
+
- MIT
|
|
74
|
+
metadata:
|
|
75
|
+
homepage_uri: https://github.com/coorasse/dockside
|
|
76
|
+
source_code_uri: https://github.com/coorasse/dockside
|
|
77
|
+
changelog_uri: https://github.com/coorasse/dockside/blob/main/CHANGELOG.md
|
|
78
|
+
funding_uri: https://github.com/sponsors/coorasse
|
|
79
|
+
rubygems_mfa_required: 'true'
|
|
80
|
+
rdoc_options: []
|
|
81
|
+
require_paths:
|
|
82
|
+
- lib
|
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
|
+
requirements:
|
|
85
|
+
- - ">="
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '3.2'
|
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
|
+
requirements:
|
|
90
|
+
- - ">="
|
|
91
|
+
- !ruby/object:Gem::Version
|
|
92
|
+
version: '0'
|
|
93
|
+
requirements: []
|
|
94
|
+
rubygems_version: 4.0.8
|
|
95
|
+
specification_version: 4
|
|
96
|
+
summary: Starts the Docker containers your Rails app needs, when your app starts.
|
|
97
|
+
test_files: []
|