Оглавление

Я давно хотел сделать себе небольшой статический сайт-визитку. Без WordPress, без базы данных, без PHP, без вечного вопроса «а почему опять кеш не сбросился». Просто HTML, CSS, немного JavaScript и нормальная публикация через Git.

В итоге решил попробовать SourceCraft Sites от Яндекса. Это хостинг статических сайтов прямо из репозитория SourceCraft. По смыслу похоже на GitHub Pages, только внутри экосистемы SourceCraft. Для визитки, портфолио, документации или маленького лендинга подходит хорошо.

Спойлер: сайт завёлся, но не с первой попытки. Были SSH-ключи, 404, ветка release, конфиг sites.yaml и немного классического DevOps-шаманства. Без него скучно, конечно. Но когда curl наконец-то вернул 200, стало понятно: жить можно.

Что я хотел получить

Задача была простая: взять готовый статический сайт-визитку и опубликовать его в SourceCraft Sites.

У сайта обычная структура: главная страница, резюме, контакты, стили, скрипты, favicon, robots.txt и sitemap.xml. Никакой серверной части. Никакой базы данных. Никакого WordPress. Только статика, которая должна быстро открываться и не требовать отдельного VPS.

Рабочий адрес в итоге получился такой:

https://krivoshein-slon.sourcecraft.site/drslon-card/

SourceCraft Sites, Spaces и Object Storage: не путаем инструменты

Сначала важно разделить несколько похожих вещей. SourceCraft в целом это платформа для работы с кодом, репозиториями, задачами, CI/CD и связанными инструментами разработки. Внутри неё есть разные возможности.

SourceCraft Spaces это скорее облачное рабочее пространство для разработки. Условно говоря, редактор и окружение в браузере. Это удобно, когда нужно работать с кодом, но это не основной способ опубликовать сайт в продакшен.

SourceCraft Sites это уже то, что нужно для статического сайта. Он берёт файлы из репозитория и отдаёт их как сайт по HTTPS. Никакой отдельный сервер поднимать не надо.

Yandex Object Storage тоже можно использовать для статического сайта, особенно если нужен свой домен и более боевой вариант размещения. Но для первого эксперимента SourceCraft Sites оказался удобнее: репозиторий, конфиг, push, проверка.

Создание репозитория в SourceCraft

Я создал публичный репозиторий с названием:

drslon-card

Для SourceCraft Sites это важный момент. Репозиторий должен быть публичным, и организация тоже должна быть публичной, иначе вместо сайта можно получить красивую, но бесполезную страницу 404. Красивую, конечно, но от этого не легче.

Создание нового репозитория в SourceCraft для статического сайта
Создание публичного репозитория в SourceCraft. Для SourceCraft Sites важно, чтобы репозиторий и организация были публичными.

Адрес репозитория для SSH-клонирования в моём случае выглядел так:

ssh://ssh.sourcecraft.dev/krivoshein-slon/drslon-card.git

SSH-ключ: первая маленькая грабля

Чтобы нормально пушить код в SourceCraft, нужен SSH-ключ. У меня на машине уже были старые ключи, и Git сначала попытался использовать старый id_rsa. В ответ получил ошибку:

identity_sign: private key /home/slon/.ssh/id_rsa contents do not match public
Permission denied (publickey).

Это значит, что локальный приватный ключ и публичный ключ не совпадали. Старые ключи я трогать не стал. Они могли использоваться для GitHub, VPS или других задач. Вместо этого сделал отдельный ключ только для SourceCraft.

ssh-keygen -t ed25519 -f ~/.ssh/sourcecraft_ed25519 -C "slon-desktop-sourcecraft"

Потом вывел публичную часть ключа:

cat ~/.ssh/sourcecraft_ed25519.pub

И добавил её в SourceCraft в разделе SSH-ключей. Важно: добавляется именно файл с расширением .pub. Приватный ключ никому не показываем. Даже если интерфейс смотрит доверчиво.

Чтобы Git использовал именно этот ключ для SourceCraft, можно добавить настройку в ~/.ssh/config:

Host ssh.sourcecraft.dev
    HostName ssh.sourcecraft.dev
    IdentityFile ~/.ssh/sourcecraft_ed25519
    IdentitiesOnly yes

После этого клонирование уже пошло нормально.

cd ~/Work
git clone ssh://ssh.sourcecraft.dev/krivoshein-slon/drslon-card.git
cd drslon-card

Подготовка файлов сайта

Исходный сайт у меня был в архиве с GitHub. Внутри лежали обычные файлы статического сайта:

index.html
contact.html
resume.html
assets/site.css
assets/site.js
favicon.ico
logo_me_mini.png
robots.txt
sitemap.xml

Сначала я попробовал публиковать сайт прямо из корня репозитория. Конфиг выглядел так:

site:
  root: "."
  ref: "main"

Формально это выглядит логично. В документации root может указывать директорию с файлами сайта, а если параметр не задан, используется корень репозитория. Но на практике у меня начались странности: то открывался прямой адрес с index.html, то корень отдавал 404, потом 404 начал отдавать и index.html.

В такой момент главное не начинать удалять половину проекта в приступе инженерного вдохновения. Проверяем спокойно.

curl -I https://krivoshein-slon.sourcecraft.site/drslon-card/
curl -I https://krivoshein-slon.sourcecraft.site/drslon-card/index.html

В какой-то момент я даже поймал 429. То есть проверками я уже начал раздражать не только себя, но и балансировщик. Тут лучше сделать паузу, не долбить curl каждую секунду и привести структуру к более предсказуемому варианту.

Подготовка структуры статического сайта и конфигурации SourceCraft Sites в терминале
Подготовка файлов сайта, создание каталога .sourcecraft и первичная настройка sites.yaml.

Рабочая схема: site плюс ветка release

В итоге стабильной оказалась схема, где в основной ветке main лежит проект, а SourceCraft Sites публикует содержимое папки site из ветки release.

Файл конфигурации:

.sourcecraft/sites.yaml

Итоговое содержимое:

site:
  root: "site"
  ref: "release"

То есть SourceCraft берёт файлы сайта не из main, а из ветки release, из директории site. После этого оба адреса начали отдавать нормальный ответ 200:

curl -L -s -o /tmp/sourcecraft-test.html -w '%{http_code}\n' \
https://krivoshein-slon.sourcecraft.site/drslon-card/index.html

curl -L -s -o /tmp/sourcecraft-test-root.html -w '%{http_code}\n' \
https://krivoshein-slon.sourcecraft.site/drslon-card/

Результат:

200
200

Вот это уже нормальная точка фиксации. Не «вроде открылось в браузере», а понятная проверка через curl.

Репозиторий SourceCraft со статическим сайтом и настроенной выкладкой SourceCraft Sites
SourceCraft увидел конфигурацию .sourcecraft/sites.yaml и показал выкладку статического сайта в правой панели репозитория.

Итоговая структура проекта

После уборки структура получилась такой:

.
├── .sourcecraft/
│   └── sites.yaml
├── site/
│   ├── assets/
│   │   ├── site.css
│   │   └── site.js
│   ├── contact.html
│   ├── index.html
│   ├── resume.html
│   ├── favicon.ico
│   ├── logo_me_mini.png
│   ├── robots.txt
│   └── sitemap.xml
└── README.md

Такой вариант мне нравится больше, чем публикация из корня. В корне остаётся служебная часть проекта, README и конфигурация. А сам сайт лежит отдельно в site. Меньше каши, меньше шансов случайно опубликовать что-то лишнее.

Локальная проверка сайта

Перед push сайт можно быстро проверить локально через встроенный сервер Python:

python3 -m http.server 8000 -d site

После запуска сайт открывается по адресу:

http://localhost:8000/

Проверяем главную, резюме, контакты, стили, картинки и переключение языка. Если локально всё хорошо, можно пушить.

Коммит и публикация

Обычный порядок обновления теперь такой. Сначала работаем в main:

git switch main
git status

git add -A
git commit -m "Update static site"

GIT_SSH_COMMAND='ssh -i ~/.ssh/sourcecraft_ed25519 -o IdentitiesOnly=yes' git push

Потом обновляем ветку release:

git switch -C release

GIT_SSH_COMMAND='ssh -i ~/.ssh/sourcecraft_ed25519 -o IdentitiesOnly=yes' \
git push -u origin release --force-with-lease

git switch main

После push сайт обновляется не мгновенно. Лучше подождать несколько минут и только потом проверять. И не надо запускать curl двадцать раз подряд. Проверено практикой: можно получить 429 и немного философии о смысле rate limiting.

Публикация статического сайта через ветку release в SourceCraft Sites
Финальный push в main и обновление ветки release, из которой SourceCraft Sites берёт файлы для публикации.

Проверка после публикации

Проверяем главную страницу:

curl -L -s -o /tmp/sourcecraft-root.html -w '%{http_code}\n' \
https://krivoshein-slon.sourcecraft.site/drslon-card/

Проверяем прямой index.html:

curl -L -s -o /tmp/sourcecraft-index.html -w '%{http_code}\n' \
https://krivoshein-slon.sourcecraft.site/drslon-card/index.html

Ожидаемый ответ:

200

Также полезно проверить robots.txt и sitemap.xml:

curl -L -s -o /tmp/sourcecraft-robots.txt -w '%{http_code}\n' \
https://krivoshein-slon.sourcecraft.site/drslon-card/robots.txt

curl -L -s -o /tmp/sourcecraft-sitemap.xml -w '%{http_code}\n' \
https://krivoshein-slon.sourcecraft.site/drslon-card/sitemap.xml

README тоже нужно привести в порядок

Так как сайт был перенесён из GitHub Pages, в README сначала оставались старые упоминания GitHub. Это лучше убрать сразу. Репозиторий должен честно описывать текущую схему: SourceCraft Sites, папка site, ветка release.

Минимальный README должен содержать:

  • что это за проект;
  • где находится публичный адрес;
  • какая структура файлов;
  • где лежит конфигурация SourceCraft Sites;
  • как запустить сайт локально;
  • как обновить ветку release;
  • как проверить публикацию через curl.

Это не бюрократия. Через месяц сам себе скажешь спасибо, особенно если параллельно ведёшь WordPress, DevOps, Python, рекламу и ещё три проекта, которые «сейчас только быстренько поправлю».

Что в итоге получилось

В результате получился рабочий статический сайт-визитка на SourceCraft Sites.

Публичный адрес:

https://krivoshein-slon.sourcecraft.site/drslon-card/

Рабочая конфигурация:

site:
  root: "site"
  ref: "release"

Главный вывод простой: SourceCraft Sites можно использовать для статических сайтов, но лучше сразу делать аккуратную структуру и не надеяться на магию. Папка site для файлов сайта и отдельная ветка release для публикации оказались самым стабильным вариантом.

Для маленькой визитки, портфолио или технической демо-страницы это хороший вариант. Не нужен VPS, не нужна база данных, не нужен Nginx. Только Git, HTML, CSS, JavaScript и немного терпения. Правда, терпение всё равно понадобится. Это же разработка, а не рекламный буклет.

Ссылки на проект

Рабочий сайт:

https://krivoshein-slon.sourcecraft.site/drslon-card/

Репозиторий в SourceCraft:

https://sourcecraft.dev/krivoshein-slon/drslon-card

Что дальше

Следующий логичный шаг, если делать сайт совсем по-взрослому, это подключить свой домен. Тут я бы уже смотрел в сторону Yandex Object Storage или отдельной схемы с доменом, DNS и HTTPS. SourceCraft Sites хорош для быстрой публикации из репозитория, но для боевого домена нужно отдельно проверить, какой способ будет надёжнее и удобнее.

А как эксперимент и как техническая заметка этот кейс получился полезным. Сначала всё выглядело как простая задача на пять минут. Потом появились SSH-ключи, 404 и ветка release. В общем, обычный вечер разработчика: хотел залить визитку, а в итоге написал мини-инструкцию по деплою.

Полезные ссылки