Перенос стека магазина: Linux → Windows + Docker Desktop¶
Это пошаговое руководство по переносу Django-магазина со старого устройства на базе Linux (PostmarketOS ARM64) на Windows-машину с Docker Desktop.
В примере используется реальный сценарий: перенос с Xiaomi Redmi 4 (postmarketOS, Alpine, aarch64) на Windows 10/11 + Docker Desktop.
Что вы получите в итоге¶
Windows 10/11
├── Docker Desktop
│ ├── [db] PostgreSQL 16
│ ├── [web] Django + Gunicorn
│ └── [nginx] статика + прокси → 127.0.0.1:8080
│
└── device_client_windows_x86_64.exe (туннель dix.su)
↕ localhost:8080
↕
dix.su → ваш-слаг.dix.su (HTTPS)
Магазин доступен в интернете по прежнему адресу eskimos.dix.su (или вашему
кастомному домену). Все данные, загруженные изображения и история заказов
сохранены.
Два клиента с одним slug одновременно не держать
Пока не убедитесь что новый стек работает, не останавливайте старый.
Но два device_client с одинаковым slug одновременно держать нельзя —
новый вытолкнет старый. Переключайтесь только после проверки.
Требования¶
- Windows 10 (21H2+) или Windows 11
- Docker Desktop для Windows с включённым WSL2-бэкендом
- WSL2 Ubuntu (устанавливается вместе с Docker Desktop или через
wsl --install -d Ubuntu) - Git в WSL2:
sudo apt install git - Доступ к старому устройству (SSH или физически)
Шаг 1. Экспорт данных со старого устройства¶
На старом устройстве (в нашем примере — Xiaomi Redmi 4 с postmarketOS, доступный через туннель dix.su):
Находясь на старом устройстве, запустите скрипт экспорта из репозитория:
Скрипт делает три вещи:
pg_dump --no-owner --no-privileges— дамп PostgreSQL без зависимостей от конкретного пользователя (важно при переносе на другую СУБД-инсталляцию)tarзагрузок изstatic/images/иstatic/upload/(CKEditor)- Упаковывает всё в
shop-<дата>.bundle.tarс файломMANIFEST
Что внутри архива
Скопируйте архив на Windows-машину. Вариант через SCP (из WSL2):
scp -P 2222 \
-o "ProxyCommand=bash -c '{ echo DIXSU:eskimos; cat; } | nc eskimos.dix.su 2222'" \
root@eskimos.dix.su:/root/shop-*.bundle.tar ~/
Или скопируйте через USB-флешку, если нет прямого доступа.
Шаг 2. Клонировать репозиторий в WSL2¶
Откройте терминал WSL2 (Ubuntu) и клонируйте репозиторий:
Почему именно WSL2, а не Windows-путь?
Скрипты (restore.sh, backup.sh) — bash-скрипты с Unix-окончаниями
строк. Запускайте их из WSL2, не из PowerShell.
Репозиторий держите в ~/django_shop (файловая система WSL2),
не в /mnt/c/… — Docker Desktop на Windows-путях работает
значительно медленнее.
Шаг 3. Заполнить .env¶
Минимальный набор переменных:
# БД
DB_PASSWORD=сильный_пароль_сюда
# Django
SECRET_KEY=длинная-случайная-строка-минимум-50-символов
ALLOWED_HOSTS=eskimos.dix.su,localhost
SITE_URL=https://eskimos.dix.su
CSRF_TRUSTED_ORIGINS=https://eskimos.dix.su
# Суперпользователь (создаётся при первом запуске)
ADMIN_EMAIL=ваш@email.ru
ADMIN_PASSWORD=пароль_администратора
# HTTP-порт nginx на хосте Windows
HTTP_PORT=8080
DIXSU_SLUG и DIXSU_TOKEN
Эти переменные больше не нужны в compose-файле — туннель запускается
отдельным exe-файлом на Windows. Оставьте их в .env если хотите, но
сервис tunnel по умолчанию не стартует.
Шаг 4. Восстановить данные¶
Из WSL2, в директории ~/django_shop:
Скрипт:
- Собирает Docker-образ
web(docker compose build) - Поднимает только
dbи дожидается готовности PostgreSQL - Загружает
db.sql.gzчерезpsql - Распаковывает
uploads.tar.gzв томuploads - Поднимает
webиnginx webпри старте запускаетcollectstaticиmigrate
Если база данных уже содержит данные (например, при повторном запуске),
скрипт откажется без флага --force:
Проверьте что сайт работает локально:
Или откройте в браузере Windows: http://localhost:8080
Шаг 5. Запустить туннель dix.su (Windows-бинарь)¶
Почему не контейнер¶
Docker Desktop на Windows не поддерживает network_mode: host. Контейнер
с этим режимом видит свой собственный localhost, а не Windows-хост. Из-за
этого туннель не может достучаться до nginx на порту 8080.
Решение: запускать туннель как обычный exe-файл прямо на Windows. Он нативно
обращается к localhost:8080, куда nginx прокидывает порт через
127.0.0.1:8080:80.
Docker Desktop:
[nginx] — слушает :80 внутри контейнера
↕
[127.0.0.1:8080:80] — порт-маппинг Docker Desktop
Windows Host:
device_client.exe → localhost:8080 → nginx → web → db
Скачать бинарь¶
# В PowerShell:
Invoke-WebRequest -Uri "https://dix.su/downloads/device_client_windows_x86_64" `
-OutFile "device_client_windows_x86_64.exe"
Запустить туннель¶
Убедитесь что eskimos.dix.su отвечает:
Автозапуск через Планировщик задач¶
Чтобы туннель запускался автоматически при входе в Windows:
$action = New-ScheduledTaskAction `
-Execute "$PWD\device_client_windows_x86_64.exe" `
-Argument "start --slug eskimos --token ВАШ_ТОКЕН --port 8080" `
-WorkingDirectory $PWD
$trigger = New-ScheduledTaskTrigger -AtLogOn
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit 0
Register-ScheduledTask `
-TaskName "dixsu-tunnel" `
-Action $action `
-Trigger $trigger `
-Settings $settings `
-RunLevel Highest `
-Force
# Запустить сразу, не дожидаясь перезагрузки:
Start-ScheduledTask -TaskName "dixsu-tunnel"
Шаг 6. Остановить старый стек¶
Только после того как убедились что новый стек работает и туннель отвечает:
# На старом устройстве (eskimos):
docker compose \
-f /root/deploy-django/itdid3/docker-compose/docker-compose.yaml \
down
# Остановить хостовый device_client:
rc-service dixsu-device-client stop
Не держите два клиента одновременно
Два device_client с одним и тем же slug — один выталкивает другой.
Остановите старый только после того как новый проверен.
Резервное копирование на новом стеке¶
Создание бэкапа (из WSL2):
Автоматический бэкап через Планировщик задач Windows (один раз):
$wslAction = New-ScheduledTaskAction `
-Execute "wsl.exe" `
-Argument '-d Ubuntu -- bash -lc "cd ~/django_shop && bash scripts/backup.sh"'
$dailyTrigger = New-ScheduledTaskTrigger -Daily -At "03:00"
Register-ScheduledTask -TaskName "django-shop-backup" `
-Action $wslAction -Trigger $dailyTrigger -Force
Adminer (доступ к БД)¶
Adminer не запускается по умолчанию. Поднять его временно:
Adminer слушает только на 127.0.0.1:8081 (не проброшен наружу).
Откройте в браузере: http://localhost:8081
Сервер: db, логин и пароль из .env.
По завершении работы остановите:
Проблемы и решения¶
exec /entrypoint.sh: no such file or directory¶
Git на Windows конвертирует окончания строк LF → CRLF. Bash в контейнере
видит #!/bin/bash\r — невалидный shebang — и не может запустить скрипт.
Решение: в репозитории уже есть .gitattributes с правилом
*.sh text eol=lf. При первом клонировании этот файл применяется
автоматически. Если репозиторий уже был склонирован до добавления
.gitattributes, выполните:
nginx возвращает 502 сразу после старта¶
web контейнер стартует несколько секунд — collectstatic + migrate.
Подождите 10–15 секунд и обновите страницу.
Загруженные изображения возвращают 404¶
Убедитесь что архив восстановлен правильно и том uploads не пустой:
Если пустой — повторите restore.sh --force с правильным путём к архиву.
Туннель запустился, но сайт не открывается по slug-адресу¶
Проверьте что nginx работает и порт 8080 занят:
Порт должен принадлежать процессу Docker Desktop.