1 Commits
Author SHA1 Message Date
ddadmin 86c67951da fix(site): сборка runner переведена со Snap uv на venv
- Зачем:
  - Snap uv не запускался внутри ограниченного systemd-сервиса без cap_dac_override.
- Что:
  - workflow переведён на системный Python, venv и pinned pip-зависимости.
  - Snap удалён из PATH runner, а runbook дополнен пакетом python3-venv.
- Проверка:
  - от имени gitea-runner выполнены clone, создание venv, pip install и mkdocs build --strict.
  - обновлённый systemd unit прошёл systemd-analyze verify и успешно перезапущен.
2026-08-04 16:06:24 -04:00
11 changed files with 58 additions and 225 deletions
-2
View File
@@ -1,2 +0,0 @@
mkdocs-material==9.6.14
mkdocs-same-dir==0.1.3
-31
View File
@@ -1,31 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
readonly venv_dir="/var/lib/gitea-runner/venvs/site"
if [[ $# -ne 1 ]]; then
echo "Usage: $0 SOURCE_DIR" >&2
exit 2
fi
source_dir=$(realpath "$1")
requirements_file="${source_dir}/.gitea/requirements-site.txt"
if [[ ! -f $requirements_file ]]; then
echo "Requirements file not found: ${requirements_file}" >&2
exit 2
fi
mkdir -p "$(dirname "$venv_dir")"
if [[ ! -x "${venv_dir}/bin/python" ]]; then
python3 -m venv "$venv_dir"
fi
"${venv_dir}/bin/python" -m pip install \
--disable-pip-version-check \
--no-input \
--requirement "$requirements_file"
"${venv_dir}/bin/python" -m pip check
cd "$source_dir"
"${venv_dir}/bin/python" -m mkdocs build --strict
+10 -1
View File
@@ -31,7 +31,16 @@ jobs:
git -C source -c advice.detachedHead=false checkout --detach FETCH_HEAD git -C source -c advice.detachedHead=false checkout --detach FETCH_HEAD
- name: Build the site strictly - name: Build the site strictly
run: source/.gitea/scripts/build-site.sh source run: |
set -euo pipefail
cd source
python3 -m venv .venv
.venv/bin/python -m pip install \
--disable-pip-version-check \
--no-input \
'mkdocs-material==9.6.14' \
'mkdocs-same-dir==0.1.3'
.venv/bin/python -m mkdocs build --strict
- name: Publish the complete release atomically - name: Publish the complete release atomically
env: env:
+2 -4
View File
@@ -55,12 +55,10 @@ All `.md` files MUST render correctly on both GitHub and the MkDocs Material sit
- Avoid: em-dash ``, en-dash `` — slug behavior differs between GitHub and MkDocs. - Avoid: em-dash ``, en-dash `` — slug behavior differs between GitHub and MkDocs.
## MkDocs Site Commands ## MkDocs Site Commands
- Initialize or update the persistent local environment:
`python3 -m venv "${HOME}/.cache/de-roadmap-mkdocs" && "${HOME}/.cache/de-roadmap-mkdocs/bin/python" -m pip install -r .gitea/requirements-site.txt`
- Local preview (user starts, ask user to run via `!`): - Local preview (user starts, ask user to run via `!`):
`"${HOME}/.cache/de-roadmap-mkdocs/bin/python" -m mkdocs serve` `uv run --with 'mkdocs-material==9.6.14' --with 'mkdocs-same-dir==0.1.3' mkdocs serve`
- Build with strict validation (catches broken links/anchors): - Build with strict validation (catches broken links/anchors):
`"${HOME}/.cache/de-roadmap-mkdocs/bin/python" -m mkdocs build --strict` `uv run --with 'mkdocs-material==9.6.14' --with 'mkdocs-same-dir==0.1.3' mkdocs build --strict`
- Visual check via Playwright (when `mkdocs serve` is running on port 8000): - Visual check via Playwright (when `mkdocs serve` is running on port 8000):
`npx playwright screenshot --viewport-size='1280,800' 'http://127.0.0.1:8000/#anchor' /path/to/screenshot.png` `npx playwright screenshot --viewport-size='1280,800' 'http://127.0.0.1:8000/#anchor' /path/to/screenshot.png`
Then read the screenshot with the Read tool to inspect rendering. Use `--viewport-size='1280,2000'` for tall pages. Then read the screenshot with the Read tool to inspect rendering. Use `--viewport-size='1280,2000'` for tall pages.
+8 -8
View File
@@ -159,7 +159,7 @@ SQL и моделирование данных специально идут р
- [SkillFactory: Виртуальные окружения в Python](https://blog.skillfactory.ru/venv-virtualnoe-okruzhenie-v-python/) - [SkillFactory: Виртуальные окружения в Python](https://blog.skillfactory.ru/venv-virtualnoe-okruzhenie-v-python/)
- Jupyter Lab - Jupyter Lab
- [Блог Практикума: «Что такое Jupyter Notebook: как установить и открыть»](https://practicum.yandex.ru/blog/chto-takoe-jupyter-notebook/) - [Блог Практикума: «Что такое Jupyter Notebook: как установить и открыть»](https://practicum.yandex.ru/blog/chto-takoe-jupyter-notebook/)
- Готовый Docker-образ Jupyter Lab со Spark: [Jupyter Docker Stacks, pyspark-notebook](https://jupyter-docker-stacks.readthedocs.io/en/latest/using/selecting.html#jupyter-pyspark-notebook) - Готовая реализация Jupyter Lab, включающая в себя Spark, в Docker: [jupyter-spark-docker](https://github.com/dementev-dev/jupyter-spark-docker)
- Pandas - Pandas
- [GeeksforGeeks: “Why Pandas is Used in Python”](https://www.geeksforgeeks.org/pandas/why-pandas-is-used-in-python/) - [GeeksforGeeks: “Why Pandas is Used in Python”](https://www.geeksforgeeks.org/pandas/why-pandas-is-used-in-python/)
- [Skillbox: «Для чего нужна библиотека Pandas»](https://skillbox.ru/media/code/rabotaem-s-pandas-osnovnye-ponyatiya-i-realnye-dannye/) - [Skillbox: «Для чего нужна библиотека Pandas»](https://skillbox.ru/media/code/rabotaem-s-pandas-osnovnye-ponyatiya-i-realnye-dannye/)
@@ -283,7 +283,7 @@ Apache Airflow — инструмент для оркестрации ETL-про
Материалы: Материалы:
- [Учебник по Airflow](https://git.dementev.space/ddmitry/airflow-manual) - [Учебник по Airflow](https://github.com/dementev-dev/airflow-manual)
**Когда блок Airflow считаем пройденным:** **Когда блок Airflow считаем пройденным:**
@@ -313,7 +313,7 @@ Apache Airflow — инструмент для оркестрации ETL-про
**Курс Yandex по Greenplum** — основной учебный курс, рекомендуется пройти целиком: **Курс Yandex по Greenplum** — основной учебный курс, рекомендуется пройти целиком:
- [Бесплатный курс Yandex Cloud по Greenplum](https://yandex.cloud/ru/training/greenplum) - [Бесплатный курс Yandex Cloud по Greenplum](https://yandex.cloud/ru/training/greenplum)
- Практику по курсу удобно делать на стенде [airflow-dwh-gp-lab](https://git.dementev.space/ddmitry/airflow-greenplum) — `make up` поднимает рабочий Greenplum с PXF, не нужен облачный кластер. - Практику по курсу удобно делать на стенде [airflow-dwh-gp-lab](https://github.com/dementev-dev/airflow-greenplum) — `make up` поднимает рабочий Greenplum с PXF, не нужен облачный кластер.
- Стенд покрывает основные темы курса: типы таблиц (heap / appendonly), политики дистрибуции, сжатие, PXF, анализ планов выполнения (`EXPLAIN`). - Стенд покрывает основные темы курса: типы таблиц (heap / appendonly), политики дистрибуции, сжатие, PXF, анализ планов выполнения (`EXPLAIN`).
- Единственное ограничение: cloud-специфичные темы (тема 2 курса — развёртывание в Yandex Cloud) на локальном стенде не покрыты. - Единственное ограничение: cloud-специфичные темы (тема 2 курса — развёртывание в Yandex Cloud) на локальном стенде не покрыты.
@@ -326,7 +326,7 @@ Apache Airflow — инструмент для оркестрации ETL-про
### Курсовая работа ### Курсовая работа
Курсовая работа — важный майлстоун роадмапа: ваш первый end-to-end data-проект. После неё у вас есть ключевые технические навыки для старта карьеры в Data Engineering. Курсовая работа — важный майлстоун роадмапа: ваш первый end-to-end data-проект. После неё у вас есть ключевые технические навыки для старта карьеры в Data Engineering.
Курсовая выполняется на том же стенде [airflow-dwh-gp-lab](https://git.dementev.space/ddmitry/airflow-greenplum), который вы уже использовали для практики по Greenplum. Курсовая выполняется на том же стенде [airflow-dwh-gp-lab](https://github.com/dementev-dev/airflow-greenplum), который вы уже использовали для практики по Greenplum.
**Что внутри:** **Что внутри:**
@@ -417,7 +417,7 @@ NiFi — визуальный конструктор потоков данных
- [Apache NiFi с нуля за 3 часа (Youtube-плейлист)](https://youtube.com/playlist?list=PL4MpKy3QjNp_rOEEibc4Ro8UK4g8vLX6_&si=W_hidjHmBOZ_aUfS) — первые 4 видео, дальше — по желанию - [Apache NiFi с нуля за 3 часа (Youtube-плейлист)](https://youtube.com/playlist?list=PL4MpKy3QjNp_rOEEibc4Ro8UK4g8vLX6_&si=W_hidjHmBOZ_aUfS) — первые 4 видео, дальше — по желанию
- [Лучший Гайд по Kafka для Начинающих За 1 Час (Youtube)](https://www.youtube.com/watch?v=hbseyn-CfXY) - [Лучший Гайд по Kafka для Начинающих За 1 Час (Youtube)](https://www.youtube.com/watch?v=hbseyn-CfXY)
Практика — на стенде [nifi-kafka-postgres-lab](https://git.dementev.space/ddmitry/nifi-kafka-postgres-lab) (Docker Compose с NiFi, Kafka и Postgres): Практика — на стенде [nifi-kafka-postgres-lab](https://github.com/dementev-dev/nifi-kafka-postgres-lab) (Docker Compose с NiFi, Kafka и Postgres):
- настраиваем в NiFi простой генератор данных и поток в Postgres; - настраиваем в NiFi простой генератор данных и поток в Postgres;
- строим поток NiFi → Kafka → NiFi → Postgres. - строим поток NiFi → Kafka → NiFi → Postgres.
@@ -434,8 +434,8 @@ ClickHouse — колоночная СУБД для аналитики на бо
Практика: Практика:
- Упражнения курса Яндекса можно выполнять в их облаке (с оплатой за ресурсы) или бесплатно у себя — на учебном кластере [clickhouse-learning-cluster](https://git.dementev.space/ddmitry/clickhouse-learning-cluster): 4 узла ClickHouse в Docker Compose, репликация, шардинг, балансировка через HAProxy. - Упражнения курса Яндекса можно выполнять в их облаке (с оплатой за ресурсы) или бесплатно у себя — на учебном кластере [clickhouse-learning-cluster](https://github.com/dementev-dev/clickhouse-learning-cluster): 4 узла ClickHouse в Docker Compose, репликация, шардинг, балансировка через HAProxy.
- Следующий шаг — стенд [clickstream-ch-kafka-superset-demo](https://git.dementev.space/ddmitry/clickstream-ch-kafka-superset-demo), имитирующий полноценное аналитическое хранилище на ClickHouse: Kafka, Airflow, дашборды в Superset, мониторинг (Prometheus/Grafana), слои STG → ODS → DDS → DM. Внутри — собственный продвинутый курс «Кликстрим на ClickHouse» с уроками прямо на стенде. - Следующий шаг — стенд [clickstream-ch-kafka-superset-demo](https://github.com/dementev-dev/clickstream-ch-kafka-superset-demo), имитирующий полноценное аналитическое хранилище на ClickHouse: Kafka, Airflow, дашборды в Superset, мониторинг (Prometheus/Grafana), слои STG → ODS → DDS → DM. Внутри — собственный продвинутый курс «Кликстрим на ClickHouse» с уроками прямо на стенде.
### Lakehouse (Spark, Iceberg, Trino) ### Lakehouse (Spark, Iceberg, Trino)
@@ -450,7 +450,7 @@ Lakehouse — архитектурный подход, который соеди
- Введение в тему: [«Как не утонуть в данных: выбираем между DWH, Data Lake и Lakehouse» (Habr, Arenadata)](https://habr.com/ru/companies/arenadata/articles/885722/) — что такое Lakehouse, чем он отличается от классического DWH и Data Lake и зачем появился - Введение в тему: [«Как не утонуть в данных: выбираем между DWH, Data Lake и Lakehouse» (Habr, Arenadata)](https://habr.com/ru/companies/arenadata/articles/885722/) — что такое Lakehouse, чем он отличается от классического DWH и Data Lake и зачем появился
- [DataLearn: «Что такое Apache Spark»](https://youtu.be/Tl9YzC-dQLI) — введение в Spark с нуля, ~40 минут - [DataLearn: «Что такое Apache Spark»](https://youtu.be/Tl9YzC-dQLI) — введение в Spark с нуля, ~40 минут
Практика — курс [«Lakehouse без магии»](https://git.dementev.space/ddmitry/mini-lakehouse-lab) на стенде mini-lakehouse-lab (Spark + Iceberg + Trino + MinIO, всё локально в Docker, без облаков и регистраций): Практика — курс [«Lakehouse без магии»](https://github.com/dementev-dev/mini-lakehouse-lab) на стенде mini-lakehouse-lab (Spark + Iceberg + Trino + MinIO, всё локально в Docker, без облаков и регистраций):
- 8 модулей на ~12–15 часов самостоятельной работы; в каждом — объяснение, демонстрация, задание и checkpoint; - 8 модулей на ~12–15 часов самостоятельной работы; в каждом — объяснение, демонстрация, задание и checkpoint;
- пайплайн `raw → bronze → silver` на реальном датасете NYC Taxi; - пайплайн `raw → bronze → silver` на реальном датасете NYC Taxi;
+3 -3
View File
@@ -540,7 +540,7 @@ flowchart TD
### Готовые SQL-скрипты ### Готовые SQL-скрипты
Все необходимые скрипты для построения хранилища находятся в папке [`sql/`](https://git.dementev.space/ddmitry/de-roadmap/src/branch/main/dwh-modeling/sql): Все необходимые скрипты для построения хранилища находятся в папке [`sql/`](https://github.com/dementev-dev/de-roadmap/tree/main/dwh-modeling/sql):
- [`01_ddl_stg-dds.sql`](sql/01_ddl_stg-dds.sql) — создание схем и таблиц (STG, ODS, DDS); - [`01_ddl_stg-dds.sql`](sql/01_ddl_stg-dds.sql) — создание схем и таблиц (STG, ODS, DDS);
- [`02_dml_stg-dds.sql`](sql/02_dml_stg-dds.sql) — первичная загрузка данных и демонстрация SCD2 через полный пересчёт (`full backfill`) из STG; - [`02_dml_stg-dds.sql`](sql/02_dml_stg-dds.sql) — первичная загрузка данных и демонстрация SCD2 через полный пересчёт (`full backfill`) из STG;
@@ -791,7 +791,7 @@ SELECT 'OK' WHERE EXISTS (
### Мини-датасет (для практики) ### Мини-датасет (для практики)
Все данные для практики находятся в папке [`data/`](https://git.dementev.space/ddmitry/de-roadmap/src/branch/main/dwh-modeling/data) — тренируйтесь: Все данные для практики находятся в папке [`data/`](https://github.com/dementev-dev/de-roadmap/tree/main/dwh-modeling/data) — тренируйтесь:
[`customers.csv`](data/customers.csv): [`customers.csv`](data/customers.csv):
```csv ```csv
@@ -832,7 +832,7 @@ product_id,valid_from,valid_to,price
9002,2023-01-01,,50 9002,2023-01-01,,50
``` ```
> 📂 Все SQL-скрипты для построения хранилища находятся в папке [`sql/`](https://git.dementev.space/ddmitry/de-roadmap/src/branch/main/dwh-modeling/sql). > 📂 Все SQL-скрипты для построения хранилища находятся в папке [`sql/`](https://github.com/dementev-dev/de-roadmap/tree/main/dwh-modeling/sql).
--- ---
+1 -2
View File
@@ -88,8 +88,7 @@ GitHub README — рабочий, но не презентабельный фо
### 4.2. Желательные (Спринт 2+) ### 4.2. Желательные (Спринт 2+)
- [x] Кастомный домен: `de.dementev.space` (подключён 2026-03-27, переведён на - [x] Кастомный домен: `de.dementev.space` (подключён 2026-03-27).
VPS 2026-08-05).
- [x] Тёмная тема (переключатель light/dark). - [x] Тёмная тема (переключатель light/dark).
- [x] Сворачиваемые блоки (`<details>`) — точечно, для подсказок/решений в домашках (2026-03-29). - [x] Сворачиваемые блоки (`<details>`) — точечно, для подсказок/решений в домашках (2026-03-29).
- [x] Кнопка «Написать в Telegram» — floating-кнопка + иконки в футере (2026-03-29). - [x] Кнопка «Написать в Telegram» — floating-кнопка + иконки в футере (2026-03-29).
+6 -5
View File
@@ -2,6 +2,12 @@
Приоритеты: P1 — делаем в первую очередь; P2 — полезно, когда дойдут руки; P3 — идеи под вопросом. Приоритеты: P1 — делаем в первую очередь; P2 — полезно, когда дойдут руки; P3 — идеи под вопросом.
## P1
- [ ] **Перенести публикацию сайта на Gitea Actions и VPS.**
Настроить repository-scoped host runner, строгую сборку MkDocs, атомарные
релизы, nginx и TLS для `de.dementev.space` по согласованной спецификации.
## P2 ## P2
- [ ] **Перенос учебника Airflow в de-roadmap.** - [ ] **Перенос учебника Airflow в de-roadmap.**
@@ -39,11 +45,6 @@
## Сделано ## Сделано
- [x] **Публикация сайта перенесена на Gitea Actions и VPS**
2026-08-05: настроены repository-scoped host runner, строгая сборка MkDocs,
атомарные релизы, nginx и TLS для `de.dementev.space`; GitHub Pages сохранён
как неактивный резерв.
- [x] **Подраздел «Linux и терминал» в блоке базовых инструментов** - [x] **Подраздел «Linux и терминал» в блоке базовых инструментов**
2026-07-12: видео-интро («Девопс на троечку», покрытие проверено по 2026-07-12: видео-интро («Девопс на троечку», покрытие проверено по
субтитрам) + три статьи (навигация и grep — habr, права — FirstVDS, субтитрам) + три статьи (навигация и grep — habr, права — FirstVDS,
+25 -151
View File
@@ -12,38 +12,14 @@
- Пользователь сервиса: `gitea-runner`, без `sudo` и Docker. - Пользователь сервиса: `gitea-runner`, без `sudo` и Docker.
- Корень публикации: `/srv/de-roadmap`. - Корень публикации: `/srv/de-roadmap`.
- Хранение: текущий релиз и две предыдущие версии. - Хранение: текущий релиз и две предыдущие версии.
- Окружение сборки: `/var/lib/gitea-runner/venvs/site`.
- Публичный IPv4 VPS: `167.224.64.252`.
## Предварительные условия
- Есть пользователь с `sudo` и рабочий SSH-доступ к VPS.
- Есть доступ к управлению DNS-зоной `dementev.space`.
- В репозитории `ddmitry/de-roadmap` включены Gitea Actions.
## Подготовка VPS ## Подготовка VPS
Установить Git, HTTP-сервер, Certbot, UFW и Python venv: Установить HTTP-сервер и Certbot:
```bash ```bash
sudo apt-get update sudo apt-get update
sudo apt-get install \ sudo apt-get install nginx certbot python3-certbot-nginx python3-venv
ca-certificates \
certbot \
curl \
git \
jq \
nginx \
python3-certbot-nginx \
python3-venv \
ufw
```
Получить административный checkout, из которого устанавливаются tracked-файлы:
```bash
git clone https://git.dementev.space/ddmitry/de-roadmap.git
cd de-roadmap
``` ```
Создать пользователя и каталоги: Создать пользователя и каталоги:
@@ -117,19 +93,14 @@ sudo rm /var/lib/gitea-runner/.registration-token
sudo chmod 0600 /var/lib/gitea-runner/.runner sudo chmod 0600 /var/lib/gitea-runner/.runner
sudo systemctl daemon-reload sudo systemctl daemon-reload
sudo systemctl enable --now gitea-runner sudo systemctl enable --now gitea-runner
systemctl is-enabled gitea-runner
systemctl is-active gitea-runner
``` ```
Временный файл с токеном удаляют сразу после успешной регистрации. В Gitea на Временный файл с токеном удаляют сразу после успешной регистрации.
странице Settings → Actions → Runners runner `de-roadmap-vps` должен перейти в
состояние online и показывать метку `de-roadmap-host`.
## Nginx и первичная публикация ## Nginx и первичная публикация
Из корня репозитория установить bootstrap-конфигурацию nginx, создать ссылку, Из корня репозитория установить virtual host, создать ссылку и только затем
отключить стандартный сайт Ubuntu и только затем перечитать проверенную перечитать проверенную конфигурацию:
конфигурацию:
```bash ```bash
sudo install -o root -g root -m 0644 \ sudo install -o root -g root -m 0644 \
@@ -138,146 +109,49 @@ sudo install -o root -g root -m 0644 \
sudo ln -s \ sudo ln -s \
/etc/nginx/sites-available/de-roadmap \ /etc/nginx/sites-available/de-roadmap \
/etc/nginx/sites-enabled/de-roadmap /etc/nginx/sites-enabled/de-roadmap
sudo unlink /etc/nginx/sites-enabled/default
sudo nginx -t sudo nginx -t
sudo systemctl reload nginx sudo systemctl reload nginx
``` ```
Первый server block в `nginx.conf` возвращает `404` для неизвестных HTTP Host, Default-сайт можно отключить только после успешной проверки нового virtual
не раскрывает версию nginx и отклоняет TLS handshake для IP или неизвестного host.
SNI. Поэтому сертификат `de.dementev.space` не выдаётся при обращении к VPS по
IP. Если проверка конфигурации не прошла, отключить новый virtual host, До первого workflow можно собрать сайт вручную и опубликовать его тем же
восстановить стандартный сайт и перечитать проверенную конфигурацию: скриптом с тестовым release id. Проверка до переключения DNS:
```bash ```bash
sudo unlink /etc/nginx/sites-enabled/de-roadmap curl --header 'Host: de.dementev.space' http://127.0.0.1/
sudo ln -s \
/etc/nginx/sites-available/default \
/etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx
``` ```
Файл `project/ops/gitea-vps-site/nginx.conf` предназначен только для запуска до После локальной проверки разрешить профили `Nginx Full` в UFW. До этого
выпуска сертификата. После выпуска сертификата Certbot изменяет установленный публичные порты `80/tcp` и `443/tcp` должны оставаться закрытыми.
virtual host. Повторная установка bootstrap-файла поверх рабочего конфига
удалит TLS-директивы.
## Окружение сборки
Скрипт `.gitea/scripts/build-site.sh` создаёт persistent venv при первом запуске
и переиспользует его в следующих сборках. `pip install` выполняется каждый раз,
чтобы применить изменения `.gitea/requirements-site.txt`, но уже установленные
версии пакетов не переустанавливаются.
## Первый деплой
В Gitea открыть Actions → Deploy MkDocs to VPS, выбрать ветку `main` и нажать
Run workflow. Job `deploy` должен завершиться успешно. Проверить опубликованный
release и локальную выдачу nginx до переключения DNS:
```bash
readlink -f /srv/de-roadmap/current
curl --fail --header 'Host: de.dementev.space' http://127.0.0.1/
```
Затем разрешить SSH, HTTP и HTTPS в UFW. Если SSH работает не на стандартном
порту `22`, сначала разрешить фактический порт вместо профиля `OpenSSH`:
```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status verbose
```
Ожидается политика `deny (incoming)` и разрешения только для SSH, `80/tcp` и
`443/tcp`.
## DNS и TLS ## DNS и TLS
1. Уменьшить TTL записи `de.dementev.space`. 1. Уменьшить TTL записи `de.dementev.space`.
2. Направить `A` на VPS; удалить или корректно направить `AAAA`. 2. Направить `A` на VPS; удалить или корректно направить `AAAA`.
3. Убедиться, что сайт доступен извне по HTTP: 3. Убедиться, что сайт доступен извне по HTTP.
4. Выпустить сертификат:
```bash ```bash
curl --fail --head http://de.dementev.space/ sudo certbot --nginx -d de.dementev.space
``` ```
4. Выпустить сертификат и включить перенаправление HTTP на HTTPS: 5. Проверить HTTPS и `systemctl status certbot.timer`.
6. Вернуть обычный DNS TTL.
```bash
sudo certbot --nginx \
--non-interactive \
--agree-tos \
--email me@dementev.space \
--redirect \
-d de.dementev.space
```
5. В созданном Certbot HTTP-блоке для `de.dementev.space` добавить
`server_tokens off;`, затем проверить и перечитать конфигурацию:
```bash
sudoedit /etc/nginx/sites-available/de-roadmap
sudo nginx -t
sudo systemctl reload nginx
```
6. Проверить перенаправление, HTTPS, сертификат и автоматическое продление:
```bash
curl --head http://de.dementev.space/
curl --fail --head https://de.dementev.space/
! curl --insecure --head https://167.224.64.252/
sudo certbot certificates
systemctl is-enabled certbot.timer
systemctl is-active certbot.timer
```
Ожидаются `301 Moved Permanently`, затем `200 OK`, отказ TLS по IP,
действующий сертификат и состояния таймера `enabled` и `active`.
7. Вернуть обычный DNS TTL.
## Проверка и откат ## Проверка и откат
Активная версия определяется ссылкой `/srv/de-roadmap/current`. Для ручного Активная версия определяется ссылкой `/srv/de-roadmap/current`. Для ручного
отката сначала выбрать точный release id из сохранённых каталогов, затем создать отката создать временную ссылку на нужный каталог в `releases/` и атомарно
временную ссылку и атомарно заменить `current`: заменить `current` через `mv -Tf`. Перед удалением релиза всегда проверять
результат `readlink -f /srv/de-roadmap/current`.
```bash
find /srv/de-roadmap/releases \
-mindepth 1 \
-maxdepth 1 \
-type d \
-printf '%f\n' \
| sort
rollback_release='<COMMIT_SHA>-<RUN_ID>'
rollback_link='/srv/de-roadmap/.current.rollback'
[[ "$rollback_release" =~ ^[0-9a-f]{40}-[0-9]+$ ]]
sudo test -d "/srv/de-roadmap/releases/${rollback_release}"
sudo test ! -e "$rollback_link"
sudo -u gitea-runner \
ln -s "releases/${rollback_release}" "$rollback_link"
sudo -u gitea-runner \
mv -Tf "$rollback_link" /srv/de-roadmap/current
readlink -f /srv/de-roadmap/current
curl --fail --head https://de.dementev.space/
```
Откат не удаляет более новые releases. Перед их ручным удалением всегда
проверять результат `readlink -f /srv/de-roadmap/current`.
Диагностика: Диагностика:
```bash ```bash
sudo systemctl status gitea-runner systemctl status gitea-runner
sudo journalctl -u gitea-runner journalctl -u gitea-runner
sudo nginx -t nginx -t
readlink -f /srv/de-roadmap/current curl --header 'Host: de.dementev.space' http://127.0.0.1/
curl --fail --head https://de.dementev.space/
``` ```
-13
View File
@@ -1,16 +1,3 @@
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _;
server_tokens off;
ssl_reject_handshake on;
return 404;
}
server { server {
listen 80; listen 80;
listen [::]:80; listen [::]:80;
@@ -1,9 +1,7 @@
# Публикация сайта через Gitea Actions и VPS # Публикация сайта через Gitea Actions и VPS
Статус: реализовано 2026-08-05; механизм синхронизации GitHub-резерва требует Статус: согласовано 2026-08-04; механизм синхронизации GitHub-резерва
отдельного решения после восстановления доступа к GitHub. Инструкции по требует отдельного решения после восстановления доступа к GitHub.
восстановлению и эксплуатации находятся в
[`project/ops/gitea-vps-site/README.md`](../ops/gitea-vps-site/README.md).
## Проблема ## Проблема
@@ -28,7 +26,7 @@
- Изменение существующих файлов в `.github/workflows/`. - Изменение существующих файлов в `.github/workflows/`.
- Добавление динамического приложения, авторизации или серверной базы данных. - Добавление динамического приложения, авторизации или серверной базы данных.
## Исходное состояние на 2026-08-04 ## Текущее состояние
- MkDocs Material собирает статический каталог `site/`; `site_url` уже равен `https://de.dementev.space/`. - MkDocs Material собирает статический каталог `site/`; `site_url` уже равен `https://de.dementev.space/`.
- Публичный репозиторий `ddmitry/de-roadmap` в Gitea является текущим `origin`. - Публичный репозиторий `ddmitry/de-roadmap` в Gitea является текущим `origin`.