Thumbnail image

Миграция Базы Данных Ghost С SQLite3 На MySQL8

Дороу, гики! Я недавно столнулся с этой задачей и потратил достаточно много времени, потому что официальная докуменация ghost довольно туманная по этой теме.

Итак у меня есть блог на ghost со 100+ постами развёрнутый посредством официального docker образа в кубере, с sqlite базой на PersistentVolume. Мне надо тот-же сервис с облачной mysql8 базой.

Официальный путь

Как описано в How to migrate from SQLite3 для миграции придётся выполнить полную переустановку Ghost. Первый шаг в переустановке это выполнить бекап с помощью ghost-cli(команда ghost backup), база будет выгружена в JSON/CSV файлы и упакована в zip-файл вместе со статическим контентом(картинки, видяшки и прочее). И вот какой результат выполнения я имею в контейнере:

blog-84f446d9b-5x8h8:/var/lib/ghost$ ghost backup

Love open source? We’re hiring JavaScript Engineers to work on Ghost full-time.
https://careers.ghost.org


Process manager 'systemd' will not run on this system, defaulting to 'local'
? Ghost instance is not currently running. Would you like to start it? No
A SystemError occurred.

Message: Ghost instance is not currently running

Debug Information:
    OS: Alpine Linux, v3.17.4
    Node Version: v16.20.1
    Ghost Version: 5.54.0
    Ghost-CLI Version: 1.24.2
    Environment: production
    Command: 'ghost backup'

Try running ghost doctor to check your system for known issues.

You can always refer to https://ghost.org/docs/ghost-cli/ for troubleshooting.

Утилита ghost-cli работает только с ghost сервером управляемом через systemd, но systemd внутри контейнера конечно же избыточен.

Так что бекап можно сделать только вручную через админку ghost. Ручной бекап состоит из нескольких шагов и минимальный даунтайм будет в районе 30 минут.

С помощью утилиты mysql-to-sqlite3

Так как нам нужна только миграция базы данных, можно уменьшить даунтайм и объём ручной работы используя утилиту на python для миграции данных из sqlite в mysql.

  1. Запускаем контейнер с mysql и mysql-to-sqlite3 утилитами в кубере:
% kubectl -n blog run mysql --image mysql:8.0.31-debian -it --rm bash

root@mysql:/# apt-get update && apt-get install -y python3-pip &&  pip install sqlite3-to-mysql
  1. Выставляем заглушку “ведутся работы” на сайт блога (чтобы избежать потерю данных)

(зависит от лоад-балансера)

  1. Копируем базу из пода blog в под mysql:
% kubectl -n blog cp --retries=10 blog-84f446d9b-5x8h8:/var/lib/ghost/content/data/ghost.db /tmp/ghost.db
% kubectl -n blog cp --retries=10 /tmp/ghost.db mysql:/ghost.db
% rm /tmp/ghost.db

% kubectl -n blog exec blog-84f446d9b-5x8h8 -- md5sum /var/lib/ghost/content/data/ghost.db
fee07fabdbf9e076dfaab0763f74e26a  /var/lib/ghost/content/data/ghost.db
% kubectl -n blog exec mysql -- md5sum /ghost.db
fee07fabdbf9e076dfaab0763f74e26a  /ghost.db
  1. Запускаем миграцию из sqlite в mysql
root@mysql:/# sqlite3mysql -X -f ghost.db -h 192.168.0.1 -d blog -u blog -p 
MySQL password:
....
2023-08-16 09:36:04 INFO     Done!
  1. Меняем env переменные в statefulset (deployment) спеке
...
        env:
         - name: database__client
-          value: sqlite3
-        - name: database__connection__filename
-          value: content/data/ghost.db
+          value: mysql
+        - name: database__connection__host
+          value: 192.168.0.1
+        - name: database__connection__user
+          value: blog
+        - name: database__connection__database
+          value: blog
...
  1. Удаляем заглушку “ведутся работы” с сайта

Готово!

Выбирайте способ который вам больше подходит и успешной миграции

Нет войне! ☮