diff --git a/packages/server/src/utils/backups/web-server.ts b/packages/server/src/utils/backups/web-server.ts index ef2249d0..2dea3d81 100644 --- a/packages/server/src/utils/backups/web-server.ts +++ b/packages/server/src/utils/backups/web-server.ts @@ -25,21 +25,23 @@ export const runWebServerBackup = async (backup: BackupSchedule) => { // First get the container ID const { stdout: containerId } = await execAsync( - "docker ps --filter 'name=dokploy-postgres' -q", + `docker ps --filter "name=dokploy-postgres" --filter "status=running" -q | head -n 1`, ); if (!containerId) { throw new Error("PostgreSQL container not found"); } - // Then run pg_dump with the container ID - const postgresCommand = `docker exec ${containerId.trim()} pg_dump -v -Fc -U dokploy -d dokploy > '${tempDir}/database.sql'`; + const postgresContainerId = containerId.trim(); + + const postgresCommand = `docker exec ${postgresContainerId} pg_dump -v -Fc -U dokploy -d dokploy > '${tempDir}/database.sql'`; await execAsync(postgresCommand); await execAsync(`cp -r ${BASE_PATH}/* ${tempDir}/filesystem/`); await execAsync( - `cd ${tempDir} && zip -r ${backupFileName} database.sql filesystem/ > /dev/null 2>&1`, + // Zip all .sql files since we created more than one + `cd ${tempDir} && zip -r ${backupFileName} *.sql filesystem/ > /dev/null 2>&1`, ); const uploadCommand = `rclone copyto ${rcloneFlags.join(" ")} "${tempDir}/${backupFileName}" "${s3Path}"`; diff --git a/packages/server/src/utils/restore/web-server.ts b/packages/server/src/utils/restore/web-server.ts index 46aa9239..8397dcf2 100644 --- a/packages/server/src/utils/restore/web-server.ts +++ b/packages/server/src/utils/restore/web-server.ts @@ -83,44 +83,54 @@ export const restoreWebServerBackup = async ( throw new Error("Database file not found after extraction"); } + const { stdout: postgresContainer } = await execAsync( + `docker ps --filter "name=dokploy-postgres" --filter "status=running" -q | head -n 1`, + ); + + if (!postgresContainer) { + throw new Error("Dokploy Postgres container not found"); + } + + const postgresContainerId = postgresContainer.trim(); + // Drop and recreate database emit("Disconnecting all users from database..."); await execAsync( - `docker exec $(docker ps --filter "name=dokploy-postgres" -q) psql -U dokploy postgres -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'dokploy' AND pid <> pg_backend_pid();"`, + `docker exec ${postgresContainerId} psql -U dokploy postgres -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'dokploy' AND pid <> pg_backend_pid();"`, ); emit("Dropping existing database..."); await execAsync( - `docker exec $(docker ps --filter "name=dokploy-postgres" -q) psql -U dokploy postgres -c "DROP DATABASE IF EXISTS dokploy;"`, + `docker exec ${postgresContainerId} psql -U dokploy postgres -c "DROP DATABASE IF EXISTS dokploy;"`, ); emit("Creating fresh database..."); await execAsync( - `docker exec $(docker ps --filter "name=dokploy-postgres" -q) psql -U dokploy postgres -c "CREATE DATABASE dokploy;"`, + `docker exec ${postgresContainerId} psql -U dokploy postgres -c "CREATE DATABASE dokploy;"`, ); // Copy the backup file into the container emit("Copying backup file into container..."); await execAsync( - `docker cp ${tempDir}/database.sql $(docker ps --filter "name=dokploy-postgres" -q):/tmp/database.sql`, + `docker cp ${tempDir}/database.sql ${postgresContainerId}:/tmp/database.sql`, ); // Verify file in container emit("Verifying file in container..."); await execAsync( - `docker exec $(docker ps --filter "name=dokploy-postgres" -q) ls -l /tmp/database.sql`, + `docker exec ${postgresContainerId} ls -l /tmp/database.sql`, ); // Restore from the copied file emit("Running database restore..."); await execAsync( - `docker exec $(docker ps --filter "name=dokploy-postgres" -q) pg_restore -v -U dokploy -d dokploy /tmp/database.sql`, + `docker exec ${postgresContainerId} pg_restore -v -U dokploy -d dokploy /tmp/database.sql`, ); // Cleanup the temporary file in the container emit("Cleaning up container temp file..."); await execAsync( - `docker exec $(docker ps --filter "name=dokploy-postgres" -q) rm /tmp/database.sql`, + `docker exec ${postgresContainerId} rm /tmp/database.sql`, ); emit("Restore completed successfully!");