Add custom labels

This commit is contained in:
David Heinemeier Hansson
2023-01-12 17:15:29 +01:00
parent 1f06b1ff94
commit 7e9b73f86a
4 changed files with 62 additions and 12 deletions

View File

@@ -93,6 +93,33 @@ servers:
Traefik will only be installed and run on the servers in the `web` role (and on all servers if no roles are defined). Traefik will only be installed and run on the servers in the `web` role (and on all servers if no roles are defined).
### Adding custom container labels
You can specialize the default Traefik rules by setting custom labels on the containers that are being started:
```
labels:
traefik.http.routers.hey.rule: 'Host(`app.hey.com`)'
```
This allows you to run multiple applications on the same server sharing the same Traefik instance and port.
The labels can even be applied on a per-role basis:
```yaml
servers:
web:
- 192.168.0.1
- 192.168.0.2
job:
hosts:
- 192.168.0.3
- 192.168.0.4
cmd: bin/jobs
labels:
my-custom-label: "50"
```
## Commands ## Commands
### Remote execution ### Remote execution

View File

@@ -3,7 +3,7 @@ require "active_support/core_ext/string/inquiry"
require "erb" require "erb"
class Mrsk::Configuration class Mrsk::Configuration
delegate :service, :image, :servers, :env, :registry, to: :config, allow_nil: true delegate :service, :image, :servers, :env, :labels, :registry, to: :config, allow_nil: true
class << self class << self
def load_file(file) def load_file(file)

View File

@@ -11,6 +11,14 @@ class Mrsk::Configuration::Role
@hosts ||= extract_hosts_from_config @hosts ||= extract_hosts_from_config
end end
def labels
if name.web?
default_labels.merge(traefik_labels).merge(custom_labels)
else
default_labels.merge(custom_labels)
end
end
def label_args def label_args
argumentize "--label", labels argumentize "--label", labels
end end
@@ -31,14 +39,6 @@ class Mrsk::Configuration::Role
end end
end end
def labels
if name.web?
default_labels.merge(traefik_labels)
else
default_labels
end
end
def default_labels def default_labels
{ "service" => config.service, "role" => name } { "service" => config.service, "role" => name }
end end
@@ -53,6 +53,13 @@ class Mrsk::Configuration::Role
} }
end end
def custom_labels
Hash.new.tap do |labels|
labels.merge!(config.labels) if config.labels.present?
labels.merge!(specializations["labels"]) if specializations["labels"].present?
end
end
def specializations def specializations
if config.servers.is_a?(Array) || config.servers[name].is_a?(Array) if config.servers.is_a?(Array) || config.servers[name].is_a?(Array)
{ } { }

View File

@@ -30,6 +30,11 @@ class ConfigurationRoleTest < ActiveSupport::TestCase
assert_equal [ "1.1.1.3", "1.1.1.4" ], @config_with_roles.role(:workers).hosts assert_equal [ "1.1.1.3", "1.1.1.4" ], @config_with_roles.role(:workers).hosts
end end
test "cmd" do
assert_nil @config.role(:web).cmd
assert_equal "bin/jobs", @config_with_roles.role(:workers).cmd
end
test "label args" do test "label args" do
assert_equal [ "--label", "service=app", "--label", "role=workers" ], @config_with_roles.role(:workers).label_args assert_equal [ "--label", "service=app", "--label", "role=workers" ], @config_with_roles.role(:workers).label_args
end end
@@ -38,8 +43,19 @@ class ConfigurationRoleTest < ActiveSupport::TestCase
assert_equal [ "--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"], @config.role(:web).label_args assert_equal [ "--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"], @config.role(:web).label_args
end end
test "cmd" do test "custom labels" do
assert_nil @config.role(:web).cmd @deploy[:labels] = { "my.custom.label" => "50" }
assert_equal "bin/jobs", @config_with_roles.role(:workers).cmd assert_equal "50", @config.role(:web).labels["my.custom.label"]
end
test "custom labels via role specialization" do
@deploy_with_roles[:labels] = { "my.custom.label" => "50" }
@deploy_with_roles[:servers]["workers"]["labels"] = { "my.custom.label" => "70" }
assert_equal "70", @config_with_roles.role(:workers).labels["my.custom.label"]
end
test "overwriting default traefik label" do
@deploy[:labels] = { "traefik.http.routers.app.rule" => "'Host(`example.com`) || (Host(`example.org`) && Path(`/traefik`))'" }
assert_equal "'Host(`example.com`) || (Host(`example.org`) && Path(`/traefik`))'", @config.role(:web).labels["traefik.http.routers.app.rule"]
end end
end end