From c2a07c3f1c69ca1538232ecae2ee711fd9f74b86 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 27 Apr 2026 01:47:50 -0400 Subject: [PATCH] fix: preserve all domains when renaming an app The `post-app-rename-setup` trigger redirected `sed` output to the new app's VHOST file inside a loop over global vhosts, so each iteration clobbered the previous one and only the last global subdomain was rewritten. When no global vhost was set, the loop never ran and the new app's VHOST file was never written, leaving the renamed app with no domains. Copy the old app's VHOST file once as a baseline, then apply `sed -i` in place for each global vhost so substitutions accumulate. Guard against a missing global VHOST file and skip blank lines. --- plugins/domains/post-app-rename-setup | 17 ++++++-- tests/unit/domains.bats | 56 +++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/plugins/domains/post-app-rename-setup b/plugins/domains/post-app-rename-setup index 3ec256a9c..c754fe2f1 100755 --- a/plugins/domains/post-app-rename-setup +++ b/plugins/domains/post-app-rename-setup @@ -7,11 +7,20 @@ trigger-domains-post-app-rename-setup() { declare trigger="post-app-rename-setup" declare OLD_APP="$1" NEW_APP="$2" - if [[ -f "$DOKKU_ROOT/$OLD_APP/VHOST" ]]; then - while read -r VHOST || [[ -n "$VHOST" ]]; do - sed -e "s/$OLD_APP.$VHOST/$NEW_APP.$VHOST/g" "$DOKKU_ROOT/$OLD_APP/VHOST" >"$DOKKU_ROOT/$NEW_APP/VHOST" - done <"$DOKKU_ROOT/VHOST" + if [[ ! -f "$DOKKU_ROOT/$OLD_APP/VHOST" ]]; then + return fi + + cp -f "$DOKKU_ROOT/$OLD_APP/VHOST" "$DOKKU_ROOT/$NEW_APP/VHOST" + + if [[ ! -f "$DOKKU_ROOT/VHOST" ]]; then + return + fi + + while read -r VHOST || [[ -n "$VHOST" ]]; do + [[ -z "$VHOST" ]] && continue + sed -i -e "s/${OLD_APP}\.${VHOST}/${NEW_APP}.${VHOST}/g" "$DOKKU_ROOT/$NEW_APP/VHOST" + done <"$DOKKU_ROOT/VHOST" } trigger-domains-post-app-rename-setup "$@" diff --git a/tests/unit/domains.bats b/tests/unit/domains.bats index 33a88fa08..577239b01 100644 --- a/tests/unit/domains.bats +++ b/tests/unit/domains.bats @@ -393,6 +393,62 @@ teardown() { assert_success } +@test "(domains) app rename preserves all subdomains across multiple global vhosts" { + run /bin/bash -c "dokku domains:set-global ${DOKKU_DOMAIN} dokku.test" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku domains:set $TEST_APP $TEST_APP.${DOKKU_DOMAIN} $TEST_APP.dokku.test custom.example.com" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku apps:rename $TEST_APP other-name" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku domains:report other-name --domains-app-vhosts" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "other-name.${DOKKU_DOMAIN} other-name.dokku.test custom.example.com" + + run /bin/bash -c "dokku apps:rename other-name $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success +} + +@test "(domains) app rename preserves custom domains when no global vhost is set" { + run /bin/bash -c "dokku domains:clear-global" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku domains:set $TEST_APP custom.example.com other.example.org" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku apps:rename $TEST_APP other-name" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku domains:report other-name --domains-app-vhosts" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "custom.example.com other.example.org" + + run /bin/bash -c "dokku apps:rename other-name $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success +} + @test "(domains) verify warning on ipv4/ipv6 domain name" { touch /etc/nginx/sites-enabled/default rm "$DOKKU_ROOT/VHOST"