Перейти к содержанию

Автоматизация сборки статического сайта

В этой статье используется технология контейнеризации приложений Docker. Подразумевается, что Docker Engine установлен без применения прав суперпользователя.

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

Для хранения исходных данных используется Gitlab. В качестве генератора статического сайта используется mkdocs. Для предоставления доступа к содержимому сайта используется nginx.

Общая схема установки системы администратором:

  • установка и первичная настройка Gitlab
  • установка и первичная настройка gitlab-runner
  • установка nginx

Общий алгоритм работы пользователя с системой:

  • клонирование репозитория сайта на свой ПК (для начала работы или после удаления локальной копии)
  • внесение изменений в файлы репозитория
  • загрузка изменений на Gitlab

После загрузки изменений на Gitlab корректно настроенная система автоматически обновляет содержимое сайта.

Установка системы

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

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

В командах ниже, данные всех запускаемых контейнеров хранятся в директории /home/USERNAME. Вы можете выбрать другую директорию в завимости от ваших требований.

Создайте директорию, в которой будут содержаться данные Gitlab:

mkdir /home/USERNAME/gitlab-data

Запустите контейнер Gitlab:

Обратите внимание, что контейнер запускается для прослушивания портов на конкретном IP (здесь: DOCKER_HOST_IP). Если это не требуется, или необходимо прослушивать порты на всех интерфейсах, внесите соответствующие изменения.

Прослушивание портов на конкретном интерфейсе позволяет запустить несколько контейнеров, использующих, например, порт 80 на одном хосте Docker.

Порт 22 может быть заменен на другой (здесь: 2222) в случае, если на хосте Docker какая-то служба уже прослушивает данный порт, например, openssh.

В команде ниже замените значение HOST.DOMAIN на адрес или доменное имя, которое будет использоваться для доступа к веб-интерфейсу Gitlab.

docker run -d --name gitlab \
-e GITLAB_OMNIBUS_CONFIG="external_url 'http://HOST.DOMAIN'" \
-p DOCKER_HOST_IP:443:443 \
-p DOCKER_HOST_IP:80:80 \
-p DOCKER_HOST_IP:2222:22 \
-v /home/USERNAME/gitlab-data/config:/etc/gitlab \
-v /home/USERNAME/gitlab-data/logs:/var/log/gitlab \
-v /home/USERNAME/gitlab-data/data:/var/opt/gitlab \
--shm-size 256m \
gitlab/gitlab-ce

После первого запуска контейнера, узнайте пароль администратора Gitlab:

docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password

При первом входе в Gitlab не забудьте заменить этот пароль на свой.

Подготовка репозитория

  1. Создайте учетную запись пользователя
  2. Войдите в Gitlab от имени созданного пользователя
  3. Создать пустой проект (т.к. проект будет предназначен для автоматизированной генерации сайта при помощи MkDocs, создайте в корне директорию docs и файл mkdocs.yml)
  4. Создайте Runner для проекта (т.к. использование Registration tokens запрещено): для этого перейдите в Settings - CI/CD - Runners и нажмите кнопку Create project runner. Затем, на странице настроек Runner, установите флаг Run untagged jobs и нажмите Create runner. На следующей странице скопируйте строку регистрации, содержащую Authentication token, т.к. он необходим для работы Runner.

Создание токена для доступа к проекту

В целях минимизации доступа к репозиторию со стороны Runner, создайте токен для чтения данных из репозитория. Для этого в веб-интерфейсе перейдите в Settings - Access Tokens - Add new token.

На форме создания нового токена сбросьте дату срока действия (если нужно), выберите роль Reporter и установите области действия read_api и read_repository. После этого нажмите Create project access token.

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

Установка и регистрация Gitlab Runner

Создайте директории для хранения данных контейнера:

mkdir /home/USERNAME/gitlab-runner-data
mkdir /home/USERNAME/site-data

Обратите внимание на создаваемую директорию site-data. Она будет использоваться для хранения данных сайта.

Запустите контейнер Gitlab Runner:

docker run -d --name gitlab-runner \
-v /home/USERNAME/docker-runner-data/config:/etc/gitlab-runner \
-v /home/USERNAME/docker-runner-data/docker.sock:/var/run/docker.sock \
-v /home/USERNAME/site-data:/site-data \
gitlab/gitlab-runner

Так как в директорию site-data записывать будет процесс контейнера gitlab-runner, а читать из этой директории процесс контейнера веб-сервера (устанавлиается далее), то необходимо установить минимальные права. Причем делать это нужно именно через выполнение команд из контейнера Gitlab, т.к. в этом случае будет установлено корректный идентификатор владельца.

docker exec -it gitlab-runner chmod 705 /site-data
docker exec -it gitlab-runner chown gitlab-runner:gitlab-runner /site-data

Выполните регистрацию Gitlab Runner. Для этого потребуется строка с токеном аутентификации (см. Подготовка репозитория).

Вместо GITLAB_AUTH_TOKEN введите значение токена аутентификации. Вместо GITLAB_SERVER_ADDRESS введите адрес или доменной имя сервера Gitlab.

docker exec -it gitlab-runner gitlab-runner register --non-interactive --url http://GITLAB_SERVER_ADDRESS --token GITLAB_AUTH_TOKEN --executor shell

Установка mkdocs

В данном варианте исполнения, установка генератора статических сайтов mkdocs выполняется в контейнер gitlab-runner.

В команде ниже представлена установка переменных среды http_proxy и https_proxy, которые требуются, если контейнер должен получать доступ к Интернет через прокси. В этом случае замените значения имени, пароля и адреса прокси на актуальные для вас. Если прокси не используется, строки установки переменных среды нужно убрать.

docker exec -it gitlab-runner sh -c \
"export http_proxy=http://PROXY_USER:PROXY_PASSWORD@PROXY_ADDRESS:3128 && \
export http_proxy=http://PROXY_USER:PROXY_PASSWORD@PROXY_ADDRESS3128 && \
apt update && \
apt upgrade -y && \
apt install mkdocs -y"

Подготовка сценария CI/CD

В репозитории проекта создайте файл .gitlab-ci.yml со следующим содержимым:

stages:
  - build

job_build:
  stage: build
  script:
    - mkdir ~/tmp
    - git clone http://GITLAB_USERNAME:GITLAB_AUTH_TOKEN@GITLAB_SERVER_ADDRESS/GITLAB_USERNAME/REPO_NAME.git ~/tmp
    - rm -rf ~/tmp/.git
    - rm -rf ~/tmp/.gitlab-ci.yml
    - rm -rf ~/tmp/README.md
    - cd ~/tmp
    - mkdocs build
    - cd ..
    - rm -rf /site-data/*
    - mv -f ~/tmp/site/* /site-data
    - rm -rf ~/tmp

Установка веб-сервера

В команде ниже укажите, если это необходимо, IP хоста Docker, на котором должен прослушиваться порт веб-сервера (здесь: 8000). Порт 8000 также можно заменить на нужный.

Запустите контейнер веб-сервера nginx:

docker run --name site-nginx \
-v /home/USERNAME/site-data:/usr/share/nginx/html:ro \
-p DOCKER_HOST_IP:8000:80 \
-d nginx

Работа с репозиторием

Получите содержимое репозитория:

git clone http://GITLAB_USERNAME@GITLAB_SERVER_ADDRESS/GITLAB_USERNAME/REPO_NAME.git

Перейдите в директорию проекта:

cd REPO_NAME

Внесите изменения в файлы репозитория.

Выполните добавление измененных файлов в индекс репозитория:

git add .

Зафиксируйте изменения с указанием автора, его адреса электронной почты и примечения к коммиту:

git -c user.name='GITLAB_USERNAME' -c user.email=GITLAB_USER_EMAIL commit -m "COMMENT"

Передайте зафикированные изменения на сервер Gitlab:

git push http://GITLAB_USERNAME@GITLAB_SERVER_ADDRESS/GITLAB_USERNAME/REPO_NAME.git

После этого вы можете видеть результаты выполнения конвейера развертывания сайта в интерфейсе Gitlab. Для этого перейдите в раздел Build - Pipelines. Здесь можно отслеживать появления ошибок и просматривать события сборки.

Автоматизация внесения изменений в репозиторий

Чтобы не набирать команды работы с репозиторием вручную, создайте в домашней директории файл push_repo.sh со следующим содержимым:

#!/bin/bash

COMMENT=$1

if [ "$1" == "" ]; then
  COMMENT='Комментарий к коммиту не указан'
fi

GITLAB_USERNAME='GITLAB_USERNAME'
GITLAB_SERVER='GITLAB_SERVER_ADDRESS'
FULL_USERNAME='GITLAB_FULL_USERNAME'
USER_EMAIL='GITLAB_USER_EMAIL'
REPO_NAME='REPO_NAME'

cd docs
git add .
git -c user.name="$FULL_USERNAME" -c user.email="$USER_EMAIL" commit -m "$COMMENT"
git push http://"$GITLAB_USERNAME"@"$GITLAB_SERVER"/"$GITLAB_USERNAME"/"$REPO_NAME".git
cd ..

Замените значения переменных на свои собственные.

Теперь, чтобы внести изменения в репозиторий на сервере, достаточно выполнить:

bash push_repo.sh COMMENT