Files
Homelab/RESTORE.md
KansaiGaijin b2f4d37f19 Split monolithic compose into 5 independent stacks
- docker-compose.infra.yml: core infrastructure (portainer, npm, homepage, wud, etc.)
- docker-compose.media.yml: media stack (arrs, jellyfin, qbittorrent, scrobbling)
- docker-compose.documents.yml: paperless-ngx, onlyoffice, stirling, open-webui
- docker-compose.photo-roms.yml: immich, syncthing, retrom
- docker-compose.utils.yml: gitea, tandoor, speedtest, linkwarden, rustdesk, etc.

Each stack has its own project name (docker-infra, docker-media, etc.) to prevent
orphan warnings. Networks defined in infra.yml, referenced as external by others.
Original preserved as docker-compose.full.yaml.bak.
Updated .gitignore, README, AGENTS.md, and RESTORE.md to reflect new structure.
2026-05-14 22:58:11 +12:00

6.8 KiB

Restoration Guide

This guide walks you through restoring your Docker infrastructure from a backup.

Architecture Alignment

The infrastructure is split into 5 compose files (stacks) sharing a common .env:

Stack File Purpose
Infrastructure docker-compose.infra.yml Portainer, NPM, homepage, WUD, ntopng, newt, dockerproxy
Media docker-compose.media.yml arr stack, Jellyfin, qBittorrent, slskd, metube, scrobbling
Documents docker-compose.documents.yml Paperless-ngx, AI, OnlyOffice, Stirling-PDF, Open WebUI
Photo & ROM docker-compose.photo-roms.yml Immich, Syncthing, Retrom
Utilities docker-compose.utils.yml Gitea, Tandoor, Speedtest, RustDesk, RedBot, Linkwarden, Neolink, iperf3

Refer to README.md for the exact service inventory and ports.

Prerequisites

  • Fresh system with Docker and Docker Compose V2 installed
  • Backup archive containing /docker/ configs
  • Access to NAS storage (if applicable)
  • Root or sudo access

Step 1: Restore Directory Structure

# Create the root docker directory
mkdir -p /docker
cd /docker

# Copy configuration files from backup
cp /path/to/backup/.env .
cp /path/to/backup/.gitignore .
cp /path/to/backup/README.md .
cp /path/to/backup/AGENTS.md .
cp /path/to/backup/RESTORE.md .
cp /path/to/backup/backup.sh .

# Copy all compose files
cp /path/to/backup/docker-compose.infra.yml .
cp /path/to/backup/docker-compose.media.yml .
cp /path/to/backup/docker-compose.documents.yml .
cp /path/to/backup/docker-compose.photo-roms.yml .
cp /path/to/backup/docker-compose.utils.yml .

# Copy the original full backup (for reference)
cp /path/to/backup/docker-compose.full.yaml.bak .

# IMPORTANT: Edit .env file with new system-specific values
nano .env

Step 2: Restore Service Configuration Directories

# Copy service configurations back to /docker
rsync -av /path/to/backup/docker/ /docker/

# Create required subdirectories that may be missing
mkdir -p /docker/Arrs/{Prowlarr,Radarr,Sonarr,Lidarr,Bazarr,Jellyfin,Seerr}/config
mkdir -p /docker/{immich,qBittorrent,paperless,stirling,syncthing,gitea}
mkdir -p /docker/{speedtest-tracker,rustdesk,redbot,maloja,scrobble}
mkdir -p /docker/{retrom/config,retrom/data}
mkdir -p /docker/{wud,ntopng,slskd,npm/data,npm/letsencrypt,npm/mysql}
mkdir -p /docker/{Homepage/config,neolink,tandoor,linkwarden}

# Set correct permissions
PUID=$(id -u)
PGID=$(id -g)
sudo chown -R $PUID:$PGID /docker

Step 3: Restore Docker Volumes

For each volume backup:

# Create the volume if it doesn't exist
docker volume create portainer_data
docker volume create open-webui
docker volume create docker_dbdata
docker volume create docker_aidata
docker volume create docker_onlyoffice
docker volume create docker_redisdata

# Restore volume data
for volume in portainer_data open-webui docker_dbdata docker_aidata docker_onlyoffice docker_redisdata; do
  if [ -f "/path/to/backup/volumes/${volume}.tar.gz" ]; then
    docker run --rm \
      -v ${volume}:/volume \
      -v /path/to/backup/volumes:/backup \
      alpine \
      tar xzf /backup/${volume}.tar.gz -C /volume
  fi
done

Step 4: Start Infrastructure First

# Start infrastructure (creates shared networks: media_net, db_net, web_net, internal_net)
docker compose -f docker-compose.infra.yml up -d

# Verify networks were created
docker network ls | grep -E "media_net|db_net|web_net|internal_net"

Step 5: Start Database Services

# Start database-dependent stacks
docker compose -f docker-compose.documents.yml up -d paperless-db paperless-broker
docker compose -f docker-compose.photo-roms.yml up -d immich-postgres immich-redis retrom-db
docker compose -f docker-compose.utils.yml up -d gitea-db speedtest-db tandoor_db linkwarden-db meilisearch

# Wait for databases to be healthy
docker compose -f docker-compose.documents.yml ps
docker compose -f docker-compose.utils.yml ps

Step 6: Restore Database Dumps (if available)

Paperless MariaDB

docker exec -i paperless-db mysql -u root -p"${PAPERLESS_DB_ROOT_PASSWORD}" paperless < /path/to/backup/database-dumps/paperless.sql

Immich PostgreSQL

docker exec -i immich_postgres psql -U postgres immich < /path/to/backup/database-dumps/immich.sql

Gitea MySQL

docker exec -i gitea-db mysql -u root -pgitea gitea < /path/to/backup/database-dumps/gitea.sql

Speedtest Tracker MariaDB

docker exec -i speedtest-db mysql -u root -p"${SPEEDTEST_DB_PASSWORD}" speedtest < /path/to/backup/database-dumps/speedtest.sql

Tandoor PostgreSQL

docker exec -i tandoor_DB psql -U "${TANDOOR_POSTGRES_USER}" "${TANDOOR_POSTGRES_DB}" < /path/to/backup/database-dumps/tandoor.sql

Step 7: Mount NAS Storage (if applicable)

# Create mount point
sudo mkdir -p /mnt/nas-storage

# Add to /etc/fstab for permanent mounting
# Example for NFS:
# nas-server:/volume1/data /mnt/nas-storage nfs defaults 0 0

# Mount immediately
sudo mount -a

# Verify mount
df -h /mnt/nas-storage

Step 8: Start All Services

# Deploy all stacks
for f in docker-compose.infra.yml docker-compose.media.yml docker-compose.documents.yml docker-compose.photo-roms.yml docker-compose.utils.yml; do
  docker compose -f "$f" up -d
done

# Watch the startup process for a specific stack
docker compose -f docker-compose.media.yml logs -f

# Check service health across all stacks
for f in docker-compose.*.yml; do
  if [ "$f" != "docker-compose.full.yaml.bak" ]; then
    echo "=== $f ==="
    docker compose -f "$f" ps
  fi
done

Step 9: Verify Services

Check Web Interfaces

Verify Databases

# Paperless
docker exec paperless-db mysql -u root -p"${PAPERLESS_DB_ROOT_PASSWORD}" -e "SELECT COUNT(*) FROM paperless.documents_document;"

# Immich
docker exec immich_postgres psql -U postgres -d immich -c "SELECT COUNT(*) FROM assets;"

Step 10: Restore Independent Stacks (if applicable)

These services have their own compose files and are restored separately:

# Discord Agent Bot
cd /docker/discord-agent
docker compose up -d

# LiteLLM
cd /docker/litellm
docker compose up -d

# Gramps genealogy
cd /docker/gramps-jamie
docker compose up -d
cd /docker/gramps-helen
docker compose up -d

# Other independent stacks
cd /docker/kasm && docker compose up -d
cd /docker/foundry-watcher && docker compose up -d

Architecture Alignment

  • This section connects to the Architecture table described in README.md.
  • Each compose file corresponds to a functional domain in the architecture.
  • Networks are created by infra.yml and shared across all other stacks.

Last Updated: May 2026