[DevOps] GitLab-CI — делаем себе просто

Mihael Savin
3 min readNov 5, 2020

Привет, %username%! Я решил вернуться к генераторам статических сайтов. На просторах данного блога я уже писал о переезде с Wordpress на Hugo. В сентябре я решил дать Wordpress'у второй шанс, но увы и ах.

Короче я решил основательно упороться, придумать некоторые костыли, приправить их велосипедами и сделал следующую схему:

  1. Установил себе локально Hugo;
  2. Завел на GitLab репозиторий с Markdown файлами статей своего бложика (включая и эту);
  3. Подключил к репе CI;

Идеологически получилось следующее. Создается директория для будущей стати, в которую кладется заготовленный шаблонный файлик с именем index.md. После чего файлик сразу открывается в моем редакторе для Markdown - Mark Text. Делается это вот таким скриптиком:

#!/usr/bin/env bash 
set -e
BLOG_PATH="/Users/jtprog/workplace/blog"
post_name=$1
cd "${BLOG_PATH}"
hugo new "${post_name}/index.md"
open -a "Mark Text" ${BLOG_PATH}/content/${post_name}/index.md
exit 0

Его я положил в отдельную директорию, которая добавлена в $PATH, а запускается это вот так:

hugo-new.sh "my-new-post-in-blog"

Строка my-new-post-in-blog сразу считается URL'ом для данного поста.

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

  1. SSH_PRIVATE_KEY - приватный ключ для доступа по ssh/rsync/scp;
  2. SSH_USER - пользователь под которым подключаемся;
  3. SSH_HOST - хост куда подключаемся;
  4. REMOTE_PATH - куда на удаленном хосте кладем файлики;

Важно: добавлять приватный ключик можно как угодно, но кмк правильнее его добавлять как Masked переменную. Тут есть нюанс: после генерации нового ключа, его необходимо перевести в base64, т.к. именно такой формат может быть Masked. Сделать это можно следующим способом:

cat .ssh/gitlabci | base64 -w0 ; echo

Соответственно обратная “расшифровка” ключа у нас происходит уже внутри контейнера при сборке.

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

FROM ubuntu:20.04
LABEL maintainer="mail@jtprog.ru"
LABEL version="1.0"
WORKDIR /site
COPY . /site/
ARG SSH_PRIVATE_KEY
ARG SSH_USER
ARG SSH_HOST
ARG REMOTE_PATH
RUN DEBIAN_FRONTEND=noninteractive apt-get -y update \
&& apt-get install -y openssh-client hugo rsync git \
&& rm -rf /var/cache/apt/* \
&& mkdir -p /root/.ssh \
&& echo "Host *\n\tStrictHostKeyChecking no\n\n" > /root/.ssh/config \
&& cat /root/.ssh/config && chmod 700 /root/.ssh \
&& ssh-keyscan -p 22 ${SSH_HOST} > /root/.ssh/known_hosts \
&& git submodule update --remote --merge \
&& echo "Генерирование страниц началось" && hugo \
&& echo "${SSH_PRIVATE_KEY}" | tr -d ' ' | base64 --decode > /root/.ssh/id_rsa \
&& chmod 600 /root/.ssh/id_rsa && cat /root/.ssh/id_rsa \
&& cp ./content/.htaccess ./public/.htaccess && cp ./content/robots.txt ./public/robots.txt \
&& echo "Запуск rsync" && rsync -avz -e "ssh -i ~/.ssh/id_rsa" --progress --delete public/ ${SSH_USER}@${SSH_HOST}:${REMOTE_PATH} \
&& echo "Завершён деплой"

Я запускаю сборку image на базе данного файла и совершенно не сохраняю его — он мне не нужен.

Для сборки подключается .gitlab-ci.yml с довольно простым содержимым:

image: docker:19.03.12services:
- docker:19.03.12-dind
variables:
CI_DEBUG_TRACE: "false"
GIT_SUBMODULE_STRATEGY: recursive
DOCKER_DRIVER: overlay
deploy fozzy:
stage: build
script:
- docker build --build-arg SSH_PRIVATE_KEY="${SSH_PRIVATE_KEY}" --build-arg SSH_USER="${SSH_USER}" --build-arg SSH_HOST="${SSH_HOST}" --build-arg REMOTE_PATH="${REMOTE_PATH}" --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest .
only:
- master

А дальше по пушу в ветку master у меня автоматически запускается все вышеописанное, а примерно через 1.5-2 минуты статья оказывается опубликованной.

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

На это всё! Если есть замечания — велком в чат!

Originally published at https://jtprog.ru on November 5, 2020.

--

--