Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(docs): Windows backup script #13091

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 24 additions & 14 deletions docs/docs/administration/backup-and-restore.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,21 +47,31 @@ docker compose up -d # Start remainder of Immich apps
</TabItem>
<TabItem value="Windows system (PowerShell)" label="Windows system (PowerShell)">

```powershell title='Backup'
docker exec -t immich_postgres pg_dumpall --clean --if-exists --username=postgres | Set-Content -Encoding utf8 "C:\path\to\backup\dump.sql"
```
### Backup

```powershell title='Restore'
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
# Remove-Item -Recurse -Force 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
gc "C:\path\to\backup\dump.sql" | docker exec -i immich_postgres psql --username=postgres # Restore Backup
docker compose up -d # Start remainder of Immich apps
```
1. [Download](https://github.com/immich-app/immich/tree/main/docs/docs/administration/files/immich-windows-backup-script.ps1) the backup script
2. Make sure Immich is running
3. Right click and click on Edit
4. Run the script from the Windows PowerShell ISE.

### Restore

:::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`
:::

1. docker compose down -v # CAUTION! Deletes all Immich data to start from scratch
2. rm -rf DB_DATA_LOCATION # CAUTION! Deletes all Immich data to start from scratch
3. docker compose pull # Update to latest version of Immich (if desired)
4. docker compose create # Create Docker containers for Immich apps without running them
5. docker start immich_postgres # Start Postgres server
6. sleep 10 # Wait for Postgres server to start up
7. [Download](https://github.com/immich-app/immich/tree/main/docs/docs/administration/files/immich-windows-restore-script.ps1) the restore script
8. Right click and click on Edit
9. Run the script from the windows PowerShell ISE

</TabItem>
</Tabs>
Expand Down
60 changes: 60 additions & 0 deletions docs/docs/administration/files/immich-windows-backup-script.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# 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
43 changes: 43 additions & 0 deletions docs/docs/administration/files/immich-windows-restore-script.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# 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
Loading