Реализация переноса медиафайлов при миграции сайта

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация переноса медиафайлов при миграции сайта
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1214
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    852
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    823
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    815

Реализация переноса медиафайлов при миграции сайта

Медиафайлы — изображения, документы, видео, архивы — нередко составляют десятки гигабайт. Перенос требует не только копирования файлов, но и обновления всех ссылок в контенте.

Инвентаризация медиафайлов

# Сводка по размерам и типам
find /var/www/uploads -type f | \
  awk -F. '{print $NF}' | sort | uniq -c | sort -rn

# Общий размер
du -sh /var/www/uploads

# Файлы без соответствия в БД (возможный мусор)
# Получить список файлов из БД
mysql myapp -e "SELECT file_path FROM media ORDER BY file_path" > db_files.txt

# Сравнить с диском
find /uploads -type f -printf "%P\n" | sort > disk_files.txt
comm -23 disk_files.txt db_files.txt | head -50  # файлы на диске, которых нет в БД

Копирование через rsync

# Первоначальная синхронизация (можно запускать несколько раз)
rsync -avz --progress \
  --checksum \
  user@old-server:/var/www/uploads/ \
  /var/www/new-site/uploads/

# С исключением ненужных директорий
rsync -avz \
  --exclude='.git' \
  --exclude='cache/' \
  --exclude='tmp/' \
  user@old-server:/var/www/uploads/ \
  /var/www/new-site/uploads/

# Delta-синхронизация перед финальным переключением
rsync -avz --delete \
  user@old-server:/var/www/uploads/ \
  /var/www/new-site/uploads/

--checksum — сравнивать по контрольной сумме, не только по времени изменения. --delete — удалять файлы, которых нет на источнике (для финальной синхронизации).

Загрузка в S3

# Загрузка с одновременностью
aws s3 sync /var/www/uploads/ \
  s3://company-media-bucket/uploads/ \
  --storage-class STANDARD \
  --exclude "*.tmp" \
  --exclude "cache/*" \
  --acl public-read

# Проверить количество загруженных файлов
aws s3 ls s3://company-media-bucket/uploads/ --recursive | wc -l

Обновление URL в контенте

После переноса файлов ссылки в контенте указывают на старые URL. Нужно заменить все вхождения:

import re
import mysql.connector

def update_media_urls_in_content(db_conn, old_base, new_base):
    cursor = db_conn.cursor()

    # Найти все поля с медиа-ссылками
    tables_columns = [
        ('posts', 'content'),
        ('posts', 'excerpt'),
        ('pages', 'body'),
        ('users', 'avatar_url'),
    ]

    for table, column in tables_columns:
        cursor.execute(f"SELECT id, {column} FROM {table} WHERE {column} LIKE %s",
                      (f'%{old_base}%',))
        rows = cursor.fetchall()

        for row_id, content in rows:
            if content:
                new_content = content.replace(old_base, new_base)
                cursor.execute(
                    f"UPDATE {table} SET {column} = %s WHERE id = %s",
                    (new_content, row_id)
                )

    db_conn.commit()
    print(f"Updated {cursor.rowcount} rows")

update_media_urls_in_content(
    db_conn,
    'https://old-site.com/wp-content/uploads',
    'https://new-site.com/uploads'
)

Для WordPress: плагин Better Search Replace или SQL:

UPDATE wp_posts
SET post_content = REPLACE(post_content,
    'https://old-site.com/wp-content/uploads/',
    'https://cdn.new-site.com/uploads/')
WHERE post_content LIKE '%old-site.com/wp-content/uploads/%';

-- Не забыть про postmeta (thumbnail URLs)
UPDATE wp_postmeta
SET meta_value = REPLACE(meta_value,
    'https://old-site.com',
    'https://new-site.com')
WHERE meta_value LIKE '%old-site.com%';

Оптимизация при переносе

Миграция — хорошее время для оптимизации изображений:

from PIL import Image
import os

def optimize_images(source_dir, target_dir):
    for root, dirs, files in os.walk(source_dir):
        for filename in files:
            if not filename.lower().endswith(('.jpg', '.jpeg', '.png')):
                continue

            source_path = os.path.join(root, filename)
            rel_path = os.path.relpath(source_path, source_dir)
            target_path = os.path.join(target_dir, rel_path)

            os.makedirs(os.path.dirname(target_path), exist_ok=True)

            img = Image.open(source_path)

            # Конвертировать в WebP
            webp_path = os.path.splitext(target_path)[0] + '.webp'
            img.save(webp_path, 'WEBP', quality=85, method=6)

            # Сохранить оригинал с оптимизацией
            img.save(target_path, optimize=True, quality=85)

Верификация после переноса

import requests
import hashlib

def verify_file_integrity(source_server, dest_server, file_list):
    errors = []

    for path in file_list:
        # Скачать с обоих серверов
        src = requests.get(f"{source_server}/{path}")
        dst = requests.get(f"{dest_server}/{path}")

        if src.status_code != 200:
            errors.append(f"Source missing: {path}")
            continue
        if dst.status_code != 200:
            errors.append(f"Destination missing: {path}")
            continue

        src_hash = hashlib.md5(src.content).hexdigest()
        dst_hash = hashlib.md5(dst.content).hexdigest()

        if src_hash != dst_hash:
            errors.append(f"Checksum mismatch: {path}")

    return errors

301-редиректы для старых медиа URL

Если URL медиафайлов изменились, настроить nginx:

# Редирект старых путей WP
location ~* ^/wp-content/uploads/(.*)$ {
    return 301 /uploads/$1;
}

# Или через map для индивидуальных редиректов
map $uri $media_redirect {
    /wp-content/uploads/2022/01/image.jpg /uploads/2022/01/image.webp;
    # ...
}

Срок выполнения

Перенос медиафайлов с обновлением ссылок в контенте для сайта объёмом до 10GB — 2–3 рабочих дня.