Add support for volumes
This commit is contained in:
@@ -96,6 +96,15 @@ If the referenced secret ENVs are missing, the configuration will be halted with
|
|||||||
Note: Marking an ENV as secret currently only redacts its value in the output for MRSK. The ENV is still injected in the clear into the container at runtime.
|
Note: Marking an ENV as secret currently only redacts its value in the output for MRSK. The ENV is still injected in the clear into the container at runtime.
|
||||||
|
|
||||||
|
|
||||||
|
### Adding volumes
|
||||||
|
|
||||||
|
You can add custom volumes into the app containers using `volumes`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
volumes:
|
||||||
|
- "/local/path:/container/path"
|
||||||
|
```
|
||||||
|
|
||||||
### Splitting servers into different roles
|
### Splitting servers into different roles
|
||||||
|
|
||||||
If your application uses separate hosts for running jobs or other roles beyond the default web running, you can specify these hosts and their custom entrypoint command like so:
|
If your application uses separate hosts for running jobs or other roles beyond the default web running, you can specify these hosts and their custom entrypoint command like so:
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|||||||
"--name", config.service_with_version,
|
"--name", config.service_with_version,
|
||||||
*rails_master_key_arg,
|
*rails_master_key_arg,
|
||||||
*role.env_args,
|
*role.env_args,
|
||||||
|
*config.volumes,
|
||||||
*role.label_args,
|
*role.label_args,
|
||||||
config.absolute_image,
|
config.absolute_image,
|
||||||
role.cmd
|
role.cmd
|
||||||
@@ -43,6 +44,7 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|||||||
("-it" if interactive),
|
("-it" if interactive),
|
||||||
*rails_master_key_arg,
|
*rails_master_key_arg,
|
||||||
*config.env_args,
|
*config.env_args,
|
||||||
|
*config.volumes,
|
||||||
config.service_with_version,
|
config.service_with_version,
|
||||||
*command
|
*command
|
||||||
end
|
end
|
||||||
@@ -53,6 +55,7 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|||||||
"--rm",
|
"--rm",
|
||||||
*rails_master_key_arg,
|
*rails_master_key_arg,
|
||||||
*config.env_args,
|
*config.env_args,
|
||||||
|
*config.volumes,
|
||||||
config.absolute_image,
|
config.absolute_image,
|
||||||
*command
|
*command
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ class Mrsk::Configuration
|
|||||||
ensure_required_keys_present if validate
|
ensure_required_keys_present if validate
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def roles
|
def roles
|
||||||
@roles ||= role_names.collect { |role_name| Role.new(role_name, config: self) }
|
@roles ||= role_names.collect { |role_name| Role.new(role_name, config: self) }
|
||||||
end
|
end
|
||||||
@@ -61,7 +60,6 @@ class Mrsk::Configuration
|
|||||||
roles.select(&:running_traefik?).flat_map(&:hosts)
|
roles.select(&:running_traefik?).flat_map(&:hosts)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def version
|
def version
|
||||||
@version
|
@version
|
||||||
end
|
end
|
||||||
@@ -78,7 +76,6 @@ class Mrsk::Configuration
|
|||||||
"#{service}-#{version}"
|
"#{service}-#{version}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def env_args
|
def env_args
|
||||||
if config.env.present?
|
if config.env.present?
|
||||||
argumentize_env_with_secrets(config.env)
|
argumentize_env_with_secrets(config.env)
|
||||||
@@ -87,6 +84,12 @@ class Mrsk::Configuration
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def volumes
|
||||||
|
return unless config.volumes.present?
|
||||||
|
|
||||||
|
config.volumes.map { |volume| "--volume #{volume}" }
|
||||||
|
end
|
||||||
|
|
||||||
def ssh_user
|
def ssh_user
|
||||||
config.ssh_user || "root"
|
config.ssh_user || "root"
|
||||||
end
|
end
|
||||||
@@ -110,11 +113,11 @@ class Mrsk::Configuration
|
|||||||
service_with_version: service_with_version,
|
service_with_version: service_with_version,
|
||||||
env_args: env_args,
|
env_args: env_args,
|
||||||
ssh_options: ssh_options,
|
ssh_options: ssh_options,
|
||||||
builder: config.builder
|
builder: config.builder,
|
||||||
|
volumes: volumes
|
||||||
}.compact
|
}.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
attr_accessor :config
|
attr_accessor :config
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,13 @@ class CommandsAppTest < ActiveSupport::TestCase
|
|||||||
[:docker, :run, "-d", "--restart unless-stopped", "--name", "app-missing", "-e", "RAILS_MASTER_KEY=456", "--label", "service=app", "--label", "role=web", "--label", "traefik.http.routers.app.rule='PathPrefix(`/`)'", "--label", "traefik.http.services.app.loadbalancer.healthcheck.path=/up", "--label", "traefik.http.services.app.loadbalancer.healthcheck.interval=1s", "--label", "traefik.http.middlewares.app.retry.attempts=3", "--label", "traefik.http.middlewares.app.retry.initialinterval=500ms", "dhh/app:missing"], @app.run
|
[:docker, :run, "-d", "--restart unless-stopped", "--name", "app-missing", "-e", "RAILS_MASTER_KEY=456", "--label", "service=app", "--label", "role=web", "--label", "traefik.http.routers.app.rule='PathPrefix(`/`)'", "--label", "traefik.http.services.app.loadbalancer.healthcheck.path=/up", "--label", "traefik.http.services.app.loadbalancer.healthcheck.interval=1s", "--label", "traefik.http.middlewares.app.retry.attempts=3", "--label", "traefik.http.middlewares.app.retry.initialinterval=500ms", "dhh/app:missing"], @app.run
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "run with volumes" do
|
||||||
|
@config[:volumes] = ["/local/path:/container/path" ]
|
||||||
|
|
||||||
|
assert_equal \
|
||||||
|
[:docker, :run, "-d", "--restart unless-stopped", "--name", "app-missing", "-e", "RAILS_MASTER_KEY=456", "--volume /local/path:/container/path", "--label", "service=app", "--label", "role=web", "--label", "traefik.http.routers.app.rule='PathPrefix(`/`)'", "--label", "traefik.http.services.app.loadbalancer.healthcheck.path=/up", "--label", "traefik.http.services.app.loadbalancer.healthcheck.interval=1s", "--label", "traefik.http.middlewares.app.retry.attempts=3", "--label", "traefik.http.middlewares.app.retry.initialinterval=500ms", "dhh/app:missing"], @app.run
|
||||||
|
end
|
||||||
|
|
||||||
test "run with" do
|
test "run with" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
[ :docker, :run, "--rm", "-e", "RAILS_MASTER_KEY=456", "dhh/app:missing", "bin/rails", "db:setup" ],
|
[ :docker, :run, "--rm", "-e", "RAILS_MASTER_KEY=456", "dhh/app:missing", "bin/rails", "db:setup" ],
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
service: "app", image: "dhh/app",
|
service: "app", image: "dhh/app",
|
||||||
registry: { "username" => "dhh", "password" => "secret" },
|
registry: { "username" => "dhh", "password" => "secret" },
|
||||||
env: { "REDIS_URL" => "redis://x/y" },
|
env: { "REDIS_URL" => "redis://x/y" },
|
||||||
servers: [ "1.1.1.1", "1.1.1.2" ]
|
servers: [ "1.1.1.1", "1.1.1.2" ],
|
||||||
|
volumes: ["/local/path:/container/path"]
|
||||||
}
|
}
|
||||||
|
|
||||||
@config = Mrsk::Configuration.new(@deploy)
|
@config = Mrsk::Configuration.new(@deploy)
|
||||||
@@ -84,15 +85,14 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
assert_equal "app-missing", @config.service_with_version
|
assert_equal "app-missing", @config.service_with_version
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
test "env args" do
|
test "env args" do
|
||||||
assert_equal [ "-e", "REDIS_URL=redis://x/y" ], @config.env_args
|
assert_equal [ "-e", "REDIS_URL=redis://x/y" ], @config.env_args
|
||||||
end
|
end
|
||||||
|
|
||||||
test "env args with clear and secrets" do
|
test "env args with clear and secrets" do
|
||||||
ENV["PASSWORD"] = "secret123"
|
ENV["PASSWORD"] = "secret123"
|
||||||
config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!({
|
config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!({
|
||||||
env: { "clear" => { "PORT" => "3000" }, "secret" => [ "PASSWORD" ] }
|
env: { "clear" => { "PORT" => "3000" }, "secret" => [ "PASSWORD" ] }
|
||||||
}) })
|
}) })
|
||||||
|
|
||||||
assert_equal [ "-e", "PASSWORD=secret123", "-e", "PORT=3000" ], config.env_args
|
assert_equal [ "-e", "PASSWORD=secret123", "-e", "PORT=3000" ], config.env_args
|
||||||
@@ -103,8 +103,8 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
test "env args with only secrets" do
|
test "env args with only secrets" do
|
||||||
ENV["PASSWORD"] = "secret123"
|
ENV["PASSWORD"] = "secret123"
|
||||||
config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!({
|
config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!({
|
||||||
env: { "secret" => [ "PASSWORD" ] }
|
env: { "secret" => [ "PASSWORD" ] }
|
||||||
}) })
|
}) })
|
||||||
|
|
||||||
assert_equal [ "-e", "PASSWORD=secret123" ], config.env_args
|
assert_equal [ "-e", "PASSWORD=secret123" ], config.env_args
|
||||||
@@ -114,8 +114,8 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "env args with missing secret" do
|
test "env args with missing secret" do
|
||||||
config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!({
|
config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!({
|
||||||
env: { "secret" => [ "PASSWORD" ] }
|
env: { "secret" => [ "PASSWORD" ] }
|
||||||
}) })
|
}) })
|
||||||
|
|
||||||
assert_raises(KeyError) do
|
assert_raises(KeyError) do
|
||||||
@@ -134,6 +134,9 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
assert_equal "456", @config.master_key
|
assert_equal "456", @config.master_key
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "volumes" do
|
||||||
|
assert_equal ["--volume /local/path:/container/path"], @config.volumes
|
||||||
|
end
|
||||||
|
|
||||||
test "erb evaluation of yml config" do
|
test "erb evaluation of yml config" do
|
||||||
config = Mrsk::Configuration.create_from Pathname.new(File.expand_path("fixtures/deploy.erb.yml", __dir__))
|
config = Mrsk::Configuration.create_from Pathname.new(File.expand_path("fixtures/deploy.erb.yml", __dir__))
|
||||||
@@ -159,6 +162,6 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "to_h" do
|
test "to_h" do
|
||||||
assert_equal({ :roles=>["web"], :hosts=>["1.1.1.1", "1.1.1.2"], :primary_host=>"1.1.1.1", :version=>"missing", :repository=>"dhh/app", :absolute_image=>"dhh/app:missing", :service_with_version=>"app-missing", :env_args=>["-e", "REDIS_URL=redis://x/y"], :ssh_options=>{:user=>"root", :auth_methods=>["publickey"]} }, @config.to_h)
|
assert_equal({ :roles=>["web"], :hosts=>["1.1.1.1", "1.1.1.2"], :primary_host=>"1.1.1.1", :version=>"missing", :repository=>"dhh/app", :absolute_image=>"dhh/app:missing", :service_with_version=>"app-missing", :env_args=>["-e", "REDIS_URL=redis://x/y"], :ssh_options=>{:user=>"root", :auth_methods=>["publickey"]}, :volumes=>["--volume /local/path:/container/path"] }, @config.to_h)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user