mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
fix(backup): keep privileges in PostgreSQL database backups
pg_dump ran with --no-acl --no-owner, so single-database backups lost all GRANTs and a restored Supabase database did not work. The import already skips owners and privileges unless "Keep owners and privileges" is selected, so the backup now keeps them. Closes #12244 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
1e71561239
commit
19afd36084
@@ -144,7 +144,7 @@ class RestoreDatabase extends Command
|
||||
|
||||
// Use pg_restore for custom format dumps
|
||||
$command = sprintf(
|
||||
'PGPASSWORD=%s pg_restore -h %s -p %s -U %s -d %s -v %s',
|
||||
'PGPASSWORD=%s pg_restore --no-owner --no-acl -h %s -p %s -U %s -d %s -v %s',
|
||||
escapeshellarg($password),
|
||||
escapeshellarg($host),
|
||||
escapeshellarg($port),
|
||||
|
||||
@@ -698,7 +698,9 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
||||
// Validate and escape database name to prevent command injection
|
||||
validateShellSafePath($database, 'database name');
|
||||
$escapedDatabase = escapeshellarg($database);
|
||||
$backupCommand .= " {$escapedContainerName} pg_dump --format=custom --no-acl --no-owner --username $escapedUsername $escapedDatabase > {$escapedBackupLocation}";
|
||||
// Keep owners and privileges in the archive: services such as Supabase need them,
|
||||
// and the restore skips them unless "Keep owners and privileges" is selected.
|
||||
$backupCommand .= " {$escapedContainerName} pg_dump --format=custom --username $escapedUsername $escapedDatabase > {$escapedBackupLocation}";
|
||||
}
|
||||
|
||||
$commands[] = $backupCommand;
|
||||
|
||||
@@ -303,6 +303,30 @@ it('backs up a service PostgreSQL database as the user from PGUSER or POSTGRESQL
|
||||
'POSTGRES_USER wins' => ["POSTGRES_USER=app\nPGUSER=pguser", 'app'],
|
||||
]);
|
||||
|
||||
it('keeps owners and privileges in a single PostgreSQL database backup', function () {
|
||||
$service = Service::factory()->create([
|
||||
'server_id' => $this->server->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
'environment_id' => $this->environment->id,
|
||||
]);
|
||||
$database = ServiceDatabase::create([
|
||||
'service_id' => $service->id,
|
||||
'name' => 'supabase-db',
|
||||
'image' => 'supabase/postgres:15.14.1.163',
|
||||
'status' => 'running:healthy',
|
||||
]);
|
||||
$backup = backupRunSafetySchedule($database, $this->team);
|
||||
$commands = backupRunSafetyFakeRemoteCommands(['| grep -E' => "POSTGRES_USER=postgres\nPOSTGRES_DB=postgres"]);
|
||||
|
||||
(new DatabaseBackupJob($backup))->handle();
|
||||
|
||||
expect($commands->first(fn (string $command) => str_contains($command, 'pg_dump')))
|
||||
->toContain('pg_dump --format=custom --username')
|
||||
->not->toContain('--no-acl')
|
||||
->not->toContain('--no-owner');
|
||||
});
|
||||
|
||||
function backupRunSafetyServiceDatabase(Server $server, StandaloneDocker $destination, Environment $environment, string $image): ServiceDatabase
|
||||
{
|
||||
$service = Service::factory()->create([
|
||||
|
||||
Reference in New Issue
Block a user