Skip to content

Instantly share code, notes, and snippets.

@aviv926
Last active October 1, 2024 12:54
Show Gist options
  • Save aviv926/124996185390d9230cdc44211c8cb549 to your computer and use it in GitHub Desktop.
Save aviv926/124996185390d9230cdc44211c8cb549 to your computer and use it in GitHub Desktop.
Full disclosure: This script was created with an AI assistant, and it worked for me.
# Variables
$containerName = "immich_postgres"
$backupFile = "immich_dump.sql.gz"
$backupPath = "/tmp/$backupFile" # Path inside the Docker container
$backupFolder = "$Env:USERPROFILE\Desktop\Immich DB backups" # Folder on Windows desktop to store backups
# Ensure the backup folder exists; if not, create it
if (-not (Test-Path -Path $backupFolder)) {
Write-Host "Creating backup folder at $backupFolder..." -ForegroundColor Cyan
New-Item -ItemType Directory -Path $backupFolder
}
# Function to get the next available filename if one already exists
function Get-AvailableFilename {
param (
[string]$filePath
)
$counter = 1
$fileDir = [System.IO.Path]::GetDirectoryName($filePath)
$fileName = [System.IO.Path]::GetFileNameWithoutExtension($filePath)
$fileExt = [System.IO.Path]::GetExtension($filePath)
while (Test-Path -Path $filePath) {
$filePath = "$fileDir\$fileName ($counter)$fileExt"
$counter++
}
return $filePath
}
# Set the desktop path to store the backup in the Immich DB backups folder
$desktopPathBase = "$backupFolder\$backupFile"
# Check if the file exists and get an available filename if necessary
$desktopPath = Get-AvailableFilename -filePath $desktopPathBase
# Step 1: Create the backup inside the Docker container
Write-Host "Step 1: Creating the backup file inside the Docker container..." -ForegroundColor Cyan
docker exec -t $containerName bash -c "mkdir -p /tmp && pg_dumpall --clean --if-exists --username=postgres | gzip > $backupPath"
Write-Host "Backup created inside the Docker container at $backupPath" -ForegroundColor Green
# Step 2: Wait until the backup file is created
Write-Host "Step 2: Waiting for the backup file to be fully created..." -ForegroundColor Cyan
do {
Start-Sleep -Seconds 2
$fileExists = docker exec $containerName bash -c "if [ -f $backupPath ]; then echo 'exists'; else echo 'not exists'; fi"
} while ($fileExists -ne "exists")
Write-Host "Backup file found! Proceeding to copy it to the backup folder..." -ForegroundColor Green
# Step 3: Copy the backup file from the Docker container to the Immich DB backups folder
Write-Host "Step 3: Copying the backup file to $desktopPath..." -ForegroundColor Cyan
docker cp "${containerName}:${backupPath}" "$desktopPath"
Write-Host "Backup successfully copied to $desktopPath" -ForegroundColor Green
# Step 4: Remove the backup file from the Docker container
Write-Host "Step 4: Deleting the backup file from the Docker container..." -ForegroundColor Cyan
docker exec -t $containerName rm $backupPath
Write-Host "Backup file deleted from the Docker container." -ForegroundColor Green
# Final Message
Write-Host "Backup process completed successfully! The file is located in $backupFolder." -ForegroundColor Yellow
# Variables
$containerName = "immich_postgres"
$backupFolder = "$Env:USERPROFILE\Desktop\Immich DB backups" # Backup folder on desktop
$backupFile = "immich_dump.sql.gz" # Specify the backup file to restore
$localBackupPath = "$backupFolder\$backupFile" # Path to the backup on Windows
$containerBackupPath = "/tmp/$backupFile" # Path inside the Docker container
# Step 1: Check if the backup file exists on the desktop
if (-not (Test-Path -Path $localBackupPath)) {
Write-Host "Error: Backup file $backupFile does not exist in $backupFolder!" -ForegroundColor Red
exit
}
Write-Host "Step 1: Found backup file $backupFile in $backupFolder" -ForegroundColor Green
# Step 2: Copy the backup file to the Docker container
Write-Host "Step 2: Copying the backup file to the Docker container..." -ForegroundColor Cyan
docker cp "$localBackupPath" "${containerName}:${containerBackupPath}"
Write-Host "Backup file copied to $containerBackupPath inside the Docker container." -ForegroundColor Green
# Step 3: Check if the gzip file exists inside the container
Write-Host "Step 3: Checking if the backup file was successfully copied inside the Docker container..." -ForegroundColor Cyan
$gzipExists = docker exec $containerName bash -c "[ -f $containerBackupPath ] && echo 'exists' || echo 'not exists'"
if ($gzipExists -ne "exists") {
Write-Host "Error: Backup file $containerBackupPath does not exist inside the container!" -ForegroundColor Red
exit
}
Write-Host "Backup file exists inside the container, proceeding to extract..." -ForegroundColor Green
# Step 4: Extract the gzip file inside the Docker container
Write-Host "Step 4: Extracting the backup file inside the Docker container..." -ForegroundColor Cyan
docker exec -t $containerName bash -c "gunzip -f $containerBackupPath"
$extractedBackupFile = "/tmp/immich_dump.sql" # Path to the extracted SQL file inside the container
# Step 6: Restore the backup using psql
Write-Host "Step 6: Restoring the database from $extractedBackupFile..." -ForegroundColor Cyan
docker exec -t $containerName bash -c "psql --username=postgres < $extractedBackupFile"
Write-Host "Database restored successfully." -ForegroundColor Green
# Step 7: Clean up by removing the extracted file
Write-Host "Step 7: Removing the extracted SQL file from the Docker container..." -ForegroundColor Cyan
docker exec -t $containerName rm $extractedBackupFile
Write-Host "Cleanup completed. Restore process finished successfully!" -ForegroundColor Yellow
@aviv926
Copy link
Author

aviv926 commented Sep 19, 2024

Important

This script was created with an AI assistant, and it worked for me.

Background

The method shown in the Immich documents for backing up on Windows does not work well and it does not properly back up city names in languages ​​other than English.

Cities in Hebrew and Arabic languages ​​would appear as ┘ו╪»┘ך┘ז╪⌐ ╪¿┘ז┘ך ┘ך╪º╪│and caused problems after restoring from a backup.

A solution to this problem is to backup directly from the Docker container and then copy the file to Windows.

The script will create a folder named Immich DB backups on the desktop where a file named immich_dump.sql.gz will be stored

Important

The script does not overwrite a backup file with an existing name, it creates a numbered name.

Always check your backup when finished.

Running the backup script

  1. Save the script as .ps1 (e.g., backup_script.ps1).
  2. Right click and click on Edit.
  3. Run the script from the windows PowerShell ISE .

Restore from backup

docker compose down -v # CAUTION! Deletes all Immich data to start from scratch
## Uncomment the next line and replace DB_DATA_LOCATION with your Postgres path to permanently reset the Postgres database
# rm -rf DB_DATA_LOCATION # CAUTION! Deletes all Immich data to start from scratch
docker compose pull # Update to latest version of Immich (if desired)
docker compose create # Create Docker containers for Immich apps without running them
docker start immich_postgres # Start Postgres server
sleep 10 # Wait for Postgres server to start up

Then run the restore_backup.ps1 script

  1. Right click and click on Edit.
  2. Run the script from the windows PowerShell ISE .

Caution

if you have changed the original backup location or the original file name, you must return it to the original location and name in order for the restore process to succeed

The location and name of the original backup should be:
C:\Users\yourusername\Desktop\Immich DB backups\immich_dump.sql.gz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment