Гид по технологиям

Развёртывание Ghost с Docker: подробное руководство

• 8 min read • DevOps • Обновлено 18 Nov 2025
Ghost с Docker: развёртывание и лучшие практики
Ghost с Docker: развёртывание и лучшие практики

Логотип платформы для создания контента Ghost

Быстрые ссылки

  • Запуск контейнера Ghost
  • Использование внешней базы данных
  • Проксирование трафика к контейнеру
  • Управление обновлениями Ghost
  • Использование ghost-cli
  • Сводка и контрольные списки

Введение

Ghost — популярная платформа для создания контента. Она написана на JavaScript/Node.js и подходит для блогов, изданий и персональных сайтов. Ghost доступен как исходный код, как управляемый сервис Ghost(Pro) и как Docker-образ, который упаковывает все зависимости.

В этом руководстве мы используем Docker и Docker Compose, чтобы быстро поднять работающий блог Ghost. Убедитесь, что на хосте установлены Docker и Docker Compose перед началом. Compose упрощает передачу переменных конфигурации вашему сайту и делает управление стеком чище.


Запуск простого контейнера Ghost

Вы можете быстро запустить базовый сайт Ghost одной командой Docker:

docker run -d -p 2368:2368 --name simple-ghost ghost:4

Скриншот мастера первоначальной настройки Ghost

По умолчанию Ghost будет доступен на порту 2368. Откройте http://localhost:2368 для просмотра сайта или http://localhost:2368/ghost для панели администратора и следуйте мастеру первой настройки для создания учётной записи.

Мастер первичной настройки Ghost с полями регистрации

Этот способ удобен для быстрого тестирования. Но данные хранятся внутри контейнера и исчезнут при его удалении. Для хранения данных используйте Docker томы.

Экран мастера настройки Ghost с примерами информации сайта


Docker Compose: рекомендуемый минимальный пример

Простой файл docker-compose.yml с томом для сохранения контента:

version: "3"

services:
  ghost:
    image: ghost:4
    ports:
      - "8080:2368"
    environment:
      url: https://ghost.example.com
    volumes:
      - ghost:/var/lib/ghost/content
    restart: unless-stopped

volumes:
  ghost:

Пояснения:

  • Контейнер слушает внутренний порт 2368. Мы пробрасываем его на 8080 хоста.
  • Том ghost монтируется в /var/lib/ghost/content и сохраняет темы, изображения и базу данных SQLite, если она используется.
  • Политика перезапуска unless-stopped поднимает контейнер после перезагрузки хоста.

Запускаем сервис:

docker-compose up -d

Скриншот запуска Ghost через Docker Compose


Конфигурация через переменные окружения

Ghost хранит настройки в JSON-структуре. В Docker вы передаёте значения через переменные окружения, заменяя уровни дерева JSON двойными подчёркиваниями (__). Это простой шаблон преобразования.

Пример JSON:

{
  "mail": {
    "transport": "SMTP"
  }
}

То же через переменную окружения:

mail__transport=SMTP

В docker-compose.yml это выглядит так:

services:
  ghost:
    environment:
      mail__transport: SMTP

Основные переменные, которые стоит указать:

  • url — публичный URL вашего сайта (обязательно для продакшена).
  • mail__* — настройки почты для отправки приглашений, уведомлений и рассылок.
  • database__* — если вы используете внешнюю базу, см. ниже.
  • paths__contentPath — переопределение пути контента, если нужно.

Важно: url должен указывать на внешний домен вашего сайта. Для локальной отладки можно использовать localhost с указанием порта.


Использование внешней базы данных MySQL

По умолчанию Ghost использует SQLite и хранит файл в каталоге контента. Для продакшена рекомендуется MySQL (или совместимая MariaDB) для масштабируемости и резервного копирования.

Пример docker-compose.yml с отдельным контейнером MySQL:

version: "3"

services:
  ghost:
    image: ghost:4
    ports:
      - "8080:2368"
    environment:
      url: https://ghost.example.com
      database__client: mysql
      database__connection__host: ghost_mysql
      database__connection__user: root
      database__connection__password: databasePw
      database__connection__database: ghost
    volumes:
      - ghost:/var/lib/ghost/content
    restart: unless-stopped

  ghost_mysql:
    image: mysql:5.7
    expose:
      - "3306"
    environment:
      MYSQL_DATABASE: ghost
      MYSQL_ROOT_PASSWORD: databasePw
    volumes:
      - mysql:/var/lib/mysql
    restart: unless-stopped

volumes:
  ghost:
  mysql:

Пояснения и практические советы:

  • Compose автоматически создаёт сеть, и Ghost подключается к контейнеру ghost_mysql по имени сервиса.
  • Для внешней, не Docker-овской БД укажите IP/имя хоста вместо ghost_mysql и оставьте переменные подключения соответствующими.
  • Не используйте root в продакшене. Создайте отдельного пользователя с ограниченными правами на схему ghost.
  • Для HA можно разместить MySQL вне Docker и настроить репликацию там.

Когда менять SQLite на MySQL:

  • У вас много пользователей и подписчиков.
  • Планируется резервное копирование и экспорт/импорт БД.
  • Вы ожидаете роста нагрузки и хотите масштабировать БД отдельно.

Проксирование трафика и SSL

В простом случае вы можете пробросить порт 80/443 на контейнер Ghost. Но чаще применяют обратный прокси. Это даёт SSL, виртуальные хосты и гибкое маршрутиование.

Пример установки NGINX на Ubuntu/Debian:

sudo apt update
sudo apt install nginx
sudo ufw allow 80
sudo ufw allow 443

Создайте файл сайта /etc/nginx/sites-available/ghost.example.com:

server {
    server_name ghost.example.com;
    index index.html;

    access_log /var/log/nginx/ghost_access.log;
    error_log /var/log/nginx/ghost_error.log error;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_redirect off;
        proxy_set_header Host $http_host;
        proxy_set_header X-Original-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Активируйте сайт и перезапустите NGINX:

sudo ln -s /etc/nginx/sites-available/ghost.example.com /etc/nginx/sites-enabled/ghost.example.com
sudo nginx -t
sudo service nginx restart

Настройка HTTPS с Certbot (Let’s Encrypt):

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d ghost.example.com

Certbot автоматически обновит конфигурацию NGINX и настроит редиректы. Проверьте автоматическое обновление сертификатов:

sudo systemctl status certbot.timer

Альтернативы NGINX:

  • Traefik — интеграция с Docker, автоматическое получение сертификатов и маршрутизация по меткам.
  • HAProxy — балансировка нагрузки на уровне TCP/HTTP.

Выбор зависит от архитектуры и привычек команды.


Управление обновлениями Ghost

Обновления Ghost проще применять через замену контейнера.

Обновление до последней минорной версии при зафиксированном major-теге:

docker-compose up -d --pull

Смена тега на новый major (пример для перехода на ghost:5):

  1. Обновите image: ghost:5 в docker-compose.yml.
  2. Выполните docker-compose pull и docker-compose up -d.

Проверяйте CHANGELOG перед крупными апгрейдами. Иногда требуется миграция данных или обновление тем.

Критерии успешного обновления:

  • Сайт отвечает по HTTPS на реальном домене.
  • Админ-панель доступна и можно войти.
  • Контент и изображения отображаются без повреждений.
  • Логи контейнера не содержат ошибок миграции.

Использование ghost-cli в контейнере

ghost-cli доступен внутри образа Ghost. Но многие команды бессмысленны в Docker-среде. Пример проверки версии через docker exec:

docker exec -it my-ghost-container ghost version

Команды install, setup, update и uninstall не рекомендуются внутри Docker. Они рассчитаны на установку в системе, где Ghost управляет сервисами и файлами вручную. В Docker обновления делаются заменой образа/контейнера.


Резервное копирование и восстановление

Регулярное резервное копирование томов и базы данных критично.

Пример резервной копии тома контента:

docker run --rm -v ghost:/volume -v $(pwd):/backup alpine \
  ash -c "cd /volume && tar czf /backup/ghost-content-$(date +%F).tgz ."

Резервное копирование MySQL (контейнер):

docker exec ghost_mysql sh -c 'exec mysqldump --databases ghost' > ghost-db-$(date +%F).sql

Восстановление контента из архива:

docker run --rm -v ghost:/volume -v $(pwd):/backup alpine \
  ash -c "cd /volume && tar xzf /backup/ghost-content-2024-01-01.tgz"

Для MySQL используйте mysql CLI для импорта дампа.

Рекомендации:

  • Храните резервные копии вне основного хоста (облачное хранилище, SFTP).
  • Тестируйте восстановление на отдельном стенде.
  • Автоматизируйте резервное копирование и мониторьте ошибки.

Безопасность и жёсткое укрепление

Короткий чеклист безопасности:

  • Работайте под непривилегированными пользователями хоста для Docker.
  • Ограничьте порты: открывайте только 80/443 на хосте и используйте локальные порты для внутренних сервисов.
  • Используйте TLS для всех внешних подключений.
  • Ограничьте доступ к админ-панели через брандмауэр или IP allowlist, если возможно.
  • Обновляйте базовую ОС и Docker-engine.
  • Регулярно сканируйте контейнеры на уязвимости.
  • Не храните пароли в публичных репозиториях; используйте секреты Docker или менеджеры секретов.

Дополнительные меры:

  • Настройте WAF перед NGINX, если ожидается высокий трафик.
  • Включите журналирование (access_log / error_log) и централизуйте логи.

Приватность и соответствие требованиям (GDPR и др.)

Несколько практических заметок:

  • Ghost хранит данные пользователя и контент. Определите, какие поля пользовательских данных вы собираете.
  • Для GDPR: документируйте цель обработки, срок хранения и способы удаления данных.
  • Реализуйте экспорт/удаление данных по запросу: Ghost поддерживает экспорт подписчиков и контента через админ.
  • Шифруйте резервные копии, особенно содержащие персональные данные.
  • Уведомляйте пользователей об использовании cookie и способах отказа.

Если вы обслуживаете пользователей в конкретной юрисдикции, проконсультируйтесь с юридическим специалистом по требованиям локального законодательства.


Миграционные заметки и подсказки

Когда переходите с локального Ghost (ghost-cli) на Docker:

  • Экспортируйте контент (Settings → Labs → Export content) и импортируйте в новую инстанцию.
  • Если вы используете SQLite, перенесите файл content/data/ghost.db в том контейнера.
  • При переходе на MySQL выполните дамп из SQLite и импортируйте в MySQL с помощью подходящих инструментов миграции.

Избегайте прямого копирования системных путей; используйте стандартные методы экспорта/импорта и проверяйте корректность приёмки.


Отладка и распространённые ошибки

Список быстрых проверок при проблемах:

  • Контейнер не стартует: проверьте docker logs на ошибки.
  • 502 Bad Gateway через NGINX: проверьте, слушает ли Ghost правильный порт и доступен ли localhost:8080.
  • Проблемы с загрузкой изображений: проверьте права и целостность тома content.
  • Ошибки миграции при обновлении: откройте логи контейнера и changelog; при необходимости восстановите резервную копию.

Ключевые команды:

docker ps

docker logs -f 
docker-compose restart ghost

Рольные контрольные списки

Администратор (тот, кто поддерживает сервер):

  • Установить Docker и Docker Compose.
  • Создать системного пользователя для запуска сервисов.
  • Настроить брандмауэр и NGINX/Traefik.
  • Настроить регулярные резервные копии и мониторинг.

Разработчик/редактор контента:

  • Настроить тему и предварительно протестировать локально.
  • Загружать статические ресурсы в раздел «Контент».
  • Тестировать публикации в staging перед релизом.

Оператор/DevOps:

  • Автоматизировать деплой через CI/CD (pull образов, проверка конфигураций).
  • Управлять секретами и конфигурациями как кодом.
  • Планировать тестовые обновления и откат.

План действий в случае неудачного обновления и откат

Короткий runbook отката:

  1. Остановить новый контейнер: docker-compose stop.
  2. Подключить том с резервной копией контента, если требуется.
  3. Вернуть старый тег образа в docker-compose.yml (например, ghost:4).
  4. Выполнить docker-compose up -d и проверить сайт.
  5. Проанализировать логи и changelog перед повторной попыткой обновления.

Примечание: наличие рабочей резервной копии базы данных критично для безопасного отката.


Примеры конфигураций и сниппеты

Полный пример docker-compose.yml для продакшена (расширенный):

version: "3.8"

services:
  ghost:
    image: ghost:4
    restart: unless-stopped
    environment:
      url: https://ghost.example.com
      database__client: mysql
      database__connection__host: db
      database__connection__user: ghostuser
      database__connection__password: strongpassword
      database__connection__database: ghostdb
      mail__transport: SMTP
      mail__options__service: Mailgun
      mail__options__auth__user: postmaster@example.com
      mail__options__auth__pass: mailgun-password
    volumes:
      - ghost-content:/var/lib/ghost/content
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.ghost.rule=Host(`ghost.example.com`)"
      - "traefik.http.routers.ghost.entrypoints=websecure"
      - "traefik.http.routers.ghost.tls.certresolver=myresolver"

  db:
    image: mariadb:10.5
    environment:
      MYSQL_DATABASE: ghostdb
      MYSQL_USER: ghostuser
      MYSQL_PASSWORD: strongpassword
      MYSQL_ROOT_PASSWORD: rootpassword
    volumes:
      - db-data:/var/lib/mysql
    restart: unless-stopped

volumes:
  ghost-content:
  db-data:

Пример простого NGINX прокси (см. ранее) и Certbot — уже приведён выше.


Решение: когда использовать Traefik

Traefik целесообразен, если:

  • Вы хотите автоматически получать TLS через Let’s Encrypt.
  • У вас мультиинстансная среда с множеством сервисов в Docker.
  • Нужна динамическая маршрутизация через метки контейнеров.

NGINX удобен, если вы предпочитаете явную конфигурацию и знаете, как управлять виртуальными хостами вручную.


Матрица совместимости и примечания по версиям

  • Ghost в Docker: образы выпускаются и содержат рабочую комбинацию Node.js и зависимостей.
  • Тег major (например, ghost:4) означает совместимость с определённой веткой. Минорные релизы включают исправления.
  • Перед переходом на новый major читайте CHANGELOG и тестируйте на стенде.

Decision tree для выбора архитектуры

flowchart TD
  A[Начало: Нужно ли продакшн?] -->|Нет| B[Локальная разработка: Используйте простой docker run]
  A -->|Да| C[Требуется высокая доступность?]
  C -->|Нет| D[Compose + одномашинный прокси 'NGINX/Traefik']
  C -->|Да| E[Рассмотреть внешнюю БД, балансировщик и кластеризацию]
  D --> F[SQLite допустим для небольших сайтов]
  D --> G[Для роста: использовать MySQL/MariaDB]
  E --> H[Оркестрация 'Kubernetes' или управляемые сервисы]

Тесты и критерии приёмки

Критерии приёмки развёртывания:

  • Сайт доступен по HTTPS на публичном домене.
  • Админ-панель доступна и авторизация работает.
  • Контент, изображения и темы корректно загружаются.
  • Резервное копирование проходит без ошибок, восстановление проверено.

Минимальные тесты после деплоя:

  • Проверить HTTP статусы 200/302 на главной и /ghost.
  • Создать и опубликовать статью, проверить фронтенд.
  • Осуществить экспорт контента и импорт на тестовую инстанцию.

Заключение

Ghost в Docker упрощает развёртывание и переносимость. Для локальной разработки достаточно быстрого docker run, а для продакшена лучше использовать Docker Compose, тома и внешнюю базу данных. Обратный прокси (NGINX или Traefik) даёт HTTPS и управление доменами. Планируйте резервное копирование, обновления и процедуры отката заранее.

Важно: тестируйте крупные обновления на стенде и проверяйте changelog перед миграцией.


Ключевые действия прямо сейчас:

  • Установите Docker и Docker Compose на хост.
  • Подготовьте docker-compose.yml с томом для контента.
  • Настройте обратный прокси и Certbot для HTTPS.
  • Настройте регулярное резервное копирование и тесты восстановления.

Спасибо за прочтение. Если нужно, подготовлю playbook для конкретного хостинга или CI/CD конфигурацию для автоматического обновления образов.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро