Config the number of containers to keep
By default we keep 5 containers around for rollback. The containers don't take much space, but the images for them can. Make the number of containers to retain configurable, either in the config with the `retain_containers` setting on the command line with the `--retain` option.
This commit is contained in:
@@ -18,12 +18,16 @@ class Kamal::Cli::Prune < Kamal::Cli::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "containers", "Prune all stopped containers, except the last 5"
|
desc "containers", "Prune all stopped containers, except the last n (default 5)"
|
||||||
|
option :retain, type: :numeric, default: nil, desc: "Number of containers to retain"
|
||||||
def containers
|
def containers
|
||||||
|
retain = options.fetch(:retain, KAMAL.config.retain_containers)
|
||||||
|
raise "retain must be at least 1" if retain < 1
|
||||||
|
|
||||||
mutating do
|
mutating do
|
||||||
on(KAMAL.hosts) do
|
on(KAMAL.hosts) do
|
||||||
execute *KAMAL.auditor.record("Pruned containers"), verbosity: :debug
|
execute *KAMAL.auditor.record("Pruned containers"), verbosity: :debug
|
||||||
execute *KAMAL.prune.app_containers
|
execute *KAMAL.prune.app_containers(retain: retain)
|
||||||
execute *KAMAL.prune.healthcheck_containers
|
execute *KAMAL.prune.healthcheck_containers
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ class Kamal::Commands::Prune < Kamal::Commands::Base
|
|||||||
"while read image tag; do docker rmi $tag; done"
|
"while read image tag; do docker rmi $tag; done"
|
||||||
end
|
end
|
||||||
|
|
||||||
def app_containers(keep_last: 5)
|
def app_containers(retain:)
|
||||||
pipe \
|
pipe \
|
||||||
docker(:ps, "-q", "-a", *service_filter, *stopped_containers_filters),
|
docker(:ps, "-q", "-a", *service_filter, *stopped_containers_filters),
|
||||||
"tail -n +#{keep_last + 1}",
|
"tail -n +#{retain + 1}",
|
||||||
"while read container_id; do docker rm $container_id; done"
|
"while read container_id; do docker rm $container_id; done"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -127,6 +127,10 @@ class Kamal::Configuration
|
|||||||
raw_config.require_destination
|
raw_config.require_destination
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def retain_containers
|
||||||
|
raw_config.retain_containers || 5
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def volume_args
|
def volume_args
|
||||||
if raw_config.volumes.present?
|
if raw_config.volumes.present?
|
||||||
@@ -218,7 +222,7 @@ class Kamal::Configuration
|
|||||||
|
|
||||||
|
|
||||||
def valid?
|
def valid?
|
||||||
ensure_destination_if_required && ensure_required_keys_present && ensure_valid_kamal_version
|
ensure_destination_if_required && ensure_required_keys_present && ensure_valid_kamal_version && ensure_retain_containers_valid
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_h
|
def to_h
|
||||||
@@ -291,6 +295,12 @@ class Kamal::Configuration
|
|||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ensure_retain_containers_valid
|
||||||
|
raise ArgumentError, "Must retain at least 1 container" if retain_containers < 1
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def role_names
|
def role_names
|
||||||
raw_config.servers.is_a?(Array) ? [ "web" ] : raw_config.servers.keys.sort
|
raw_config.servers.is_a?(Array) ? [ "web" ] : raw_config.servers.keys.sort
|
||||||
|
|||||||
@@ -20,6 +20,15 @@ class CliPruneTest < CliTestCase
|
|||||||
assert_match /docker ps -q -a --filter label=service=app --filter status=created --filter status=exited --filter status=dead | tail -n +6 | while read container_id; do docker rm $container_id; done on 1.1.1.\d/, output
|
assert_match /docker ps -q -a --filter label=service=app --filter status=created --filter status=exited --filter status=dead | tail -n +6 | while read container_id; do docker rm $container_id; done on 1.1.1.\d/, output
|
||||||
assert_match /docker container prune --force --filter label=service=healthcheck-app on 1.1.1.\d/, output
|
assert_match /docker container prune --force --filter label=service=healthcheck-app on 1.1.1.\d/, output
|
||||||
end
|
end
|
||||||
|
|
||||||
|
run_command("containers", "--retain", "10").tap do |output|
|
||||||
|
assert_match /docker ps -q -a --filter label=service=app --filter status=created --filter status=exited --filter status=dead | tail -n +11 | while read container_id; do docker rm $container_id; done on 1.1.1.\d/, output
|
||||||
|
assert_match /docker container prune --force --filter label=service=healthcheck-app on 1.1.1.\d/, output
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_raises(RuntimeError, "retain must be at least 1") do
|
||||||
|
run_command("containers", "--retain", "0")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|||||||
@@ -23,7 +23,11 @@ class CommandsPruneTest < ActiveSupport::TestCase
|
|||||||
test "app containers" do
|
test "app containers" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker ps -q -a --filter label=service=app --filter status=created --filter status=exited --filter status=dead | tail -n +6 | while read container_id; do docker rm $container_id; done",
|
"docker ps -q -a --filter label=service=app --filter status=created --filter status=exited --filter status=dead | tail -n +6 | while read container_id; do docker rm $container_id; done",
|
||||||
new_command.app_containers.join(" ")
|
new_command.app_containers(retain: 5).join(" ")
|
||||||
|
|
||||||
|
assert_equal \
|
||||||
|
"docker ps -q -a --filter label=service=app --filter status=created --filter status=exited --filter status=dead | tail -n +4 | while read container_id; do docker rm $container_id; done",
|
||||||
|
new_command.app_containers(retain: 3).join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "healthcheck containers" do
|
test "healthcheck containers" do
|
||||||
|
|||||||
@@ -309,4 +309,12 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
assert_match /bar isn't defined/, error.message
|
assert_match /bar isn't defined/, error.message
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "retain_containers" do
|
||||||
|
assert_equal 5, @config.retain_containers
|
||||||
|
config = Kamal::Configuration.new(@deploy_with_roles.merge(retain_containers: 2))
|
||||||
|
assert_equal 2, config.retain_containers
|
||||||
|
|
||||||
|
assert_raises(ArgumentError) { Kamal::Configuration.new(@deploy_with_roles.merge(retain_containers: 0)) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user