From 8d280b4aac3f6e0b6ec1de37335a1440043e1933 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 13 Oct 2025 10:01:54 +0200 Subject: [PATCH] fix: prevent container name conflict when updating database port mappings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When port mappings are changed in the UI and the database is restarted, the system now gracefully stops and removes the existing container before recreating it with the new configuration. This prevents the "container name already in use" error that occurred when Docker Compose tried to create a container with the same name but different port configuration. Changes: - Add graceful container stop (10s timeout) before docker compose up - Remove old container to avoid name conflicts - Use --timeout flag (modern Docker CLI) instead of deprecated --time - Apply fix to all database types: MariaDB, MySQL, PostgreSQL, MongoDB, Redis, KeyDB, Dragonfly, and ClickHouse - Update StopDatabase.php for consistency 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- app/Actions/Database/StartClickhouse.php | 2 ++ app/Actions/Database/StartDragonfly.php | 2 ++ app/Actions/Database/StartKeydb.php | 2 ++ app/Actions/Database/StartMariadb.php | 2 ++ app/Actions/Database/StartMongodb.php | 2 ++ app/Actions/Database/StartMysql.php | 2 ++ app/Actions/Database/StartPostgresql.php | 2 ++ app/Actions/Database/StartRedis.php | 2 ++ app/Actions/Database/StopDatabase.php | 2 +- 9 files changed, 17 insertions(+), 1 deletion(-) diff --git a/app/Actions/Database/StartClickhouse.php b/app/Actions/Database/StartClickhouse.php index f218fcabb0..38f6d7bc83 100644 --- a/app/Actions/Database/StartClickhouse.php +++ b/app/Actions/Database/StartClickhouse.php @@ -105,6 +105,8 @@ class StartClickhouse $this->commands[] = "echo '{$readme}' > $this->configuration_dir/README.md"; $this->commands[] = "echo 'Pulling {$database->image} image.'"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull"; + $this->commands[] = "docker stop --timeout=10 $container_name 2>/dev/null || true"; + $this->commands[] = "docker rm -f $container_name 2>/dev/null || true"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; $this->commands[] = "echo 'Database started.'"; diff --git a/app/Actions/Database/StartDragonfly.php b/app/Actions/Database/StartDragonfly.php index 0db73ba07b..300221d249 100644 --- a/app/Actions/Database/StartDragonfly.php +++ b/app/Actions/Database/StartDragonfly.php @@ -192,6 +192,8 @@ class StartDragonfly if ($this->database->enable_ssl) { $this->commands[] = "chown -R 999:999 $this->configuration_dir/ssl/server.key $this->configuration_dir/ssl/server.crt"; } + $this->commands[] = "docker stop --timeout=10 $container_name 2>/dev/null || true"; + $this->commands[] = "docker rm -f $container_name 2>/dev/null || true"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; $this->commands[] = "echo 'Database started.'"; diff --git a/app/Actions/Database/StartKeydb.php b/app/Actions/Database/StartKeydb.php index 2908eb9c11..3a2ceebb36 100644 --- a/app/Actions/Database/StartKeydb.php +++ b/app/Actions/Database/StartKeydb.php @@ -208,6 +208,8 @@ class StartKeydb if ($this->database->enable_ssl) { $this->commands[] = "chown -R 999:999 $this->configuration_dir/ssl/server.key $this->configuration_dir/ssl/server.crt"; } + $this->commands[] = "docker stop --timeout=10 $container_name 2>/dev/null || true"; + $this->commands[] = "docker rm -f $container_name 2>/dev/null || true"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; $this->commands[] = "echo 'Database started.'"; diff --git a/app/Actions/Database/StartMariadb.php b/app/Actions/Database/StartMariadb.php index 11b424ff8f..8a936c8aef 100644 --- a/app/Actions/Database/StartMariadb.php +++ b/app/Actions/Database/StartMariadb.php @@ -209,6 +209,8 @@ class StartMariadb $this->commands[] = "echo '{$readme}' > $this->configuration_dir/README.md"; $this->commands[] = "echo 'Pulling {$database->image} image.'"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull"; + $this->commands[] = "docker stop --timeout=10 $container_name 2>/dev/null || true"; + $this->commands[] = "docker rm -f $container_name 2>/dev/null || true"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; $this->commands[] = "echo 'Database started.'"; if ($this->database->enable_ssl) { diff --git a/app/Actions/Database/StartMongodb.php b/app/Actions/Database/StartMongodb.php index 0bf6ab253f..19699d6849 100644 --- a/app/Actions/Database/StartMongodb.php +++ b/app/Actions/Database/StartMongodb.php @@ -260,6 +260,8 @@ class StartMongodb $this->commands[] = "echo '{$readme}' > $this->configuration_dir/README.md"; $this->commands[] = "echo 'Pulling {$database->image} image.'"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull"; + $this->commands[] = "docker stop --timeout=10 $container_name 2>/dev/null || true"; + $this->commands[] = "docker rm -f $container_name 2>/dev/null || true"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; if ($this->database->enable_ssl) { $this->commands[] = executeInDocker($this->database->uuid, 'chown mongodb:mongodb /etc/mongo/certs/server.pem'); diff --git a/app/Actions/Database/StartMysql.php b/app/Actions/Database/StartMysql.php index bf81d01abe..25546fa9d3 100644 --- a/app/Actions/Database/StartMysql.php +++ b/app/Actions/Database/StartMysql.php @@ -210,6 +210,8 @@ class StartMysql $this->commands[] = "echo '{$readme}' > $this->configuration_dir/README.md"; $this->commands[] = "echo 'Pulling {$database->image} image.'"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull"; + $this->commands[] = "docker stop --timeout=10 $container_name 2>/dev/null || true"; + $this->commands[] = "docker rm -f $container_name 2>/dev/null || true"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; if ($this->database->enable_ssl) { diff --git a/app/Actions/Database/StartPostgresql.php b/app/Actions/Database/StartPostgresql.php index 6cdf32e270..ac011acbe2 100644 --- a/app/Actions/Database/StartPostgresql.php +++ b/app/Actions/Database/StartPostgresql.php @@ -223,6 +223,8 @@ class StartPostgresql $this->commands[] = "echo '{$readme}' > $this->configuration_dir/README.md"; $this->commands[] = "echo 'Pulling {$database->image} image.'"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull"; + $this->commands[] = "docker stop --timeout=10 $container_name 2>/dev/null || true"; + $this->commands[] = "docker rm -f $container_name 2>/dev/null || true"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; if ($this->database->enable_ssl) { $this->commands[] = executeInDocker($this->database->uuid, "chown {$this->database->postgres_user}:{$this->database->postgres_user} /var/lib/postgresql/certs/server.key /var/lib/postgresql/certs/server.crt"); diff --git a/app/Actions/Database/StartRedis.php b/app/Actions/Database/StartRedis.php index c040ec3913..8a7ae42a43 100644 --- a/app/Actions/Database/StartRedis.php +++ b/app/Actions/Database/StartRedis.php @@ -205,6 +205,8 @@ class StartRedis if ($this->database->enable_ssl) { $this->commands[] = "chown -R 999:999 $this->configuration_dir/ssl/server.key $this->configuration_dir/ssl/server.crt"; } + $this->commands[] = "docker stop --timeout=10 $container_name 2>/dev/null || true"; + $this->commands[] = "docker rm -f $container_name 2>/dev/null || true"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; $this->commands[] = "echo 'Database started.'"; diff --git a/app/Actions/Database/StopDatabase.php b/app/Actions/Database/StopDatabase.php index 5c881e7433..63f5b19790 100644 --- a/app/Actions/Database/StopDatabase.php +++ b/app/Actions/Database/StopDatabase.php @@ -49,7 +49,7 @@ class StopDatabase { $server = $database->destination->server; instant_remote_process(command: [ - "docker stop --time=$timeout $containerName", + "docker stop --timeout=$timeout $containerName", "docker rm -f $containerName", ], server: $server, throwError: false); }