Работа с новым клиентом на техподдержке всегда начинается с того, что мы подключаем его проект к системе контроля версий и налаживаем рабочий процесс. Разберём, как это происходит. Пусть это будет интернет-магазин с названием vsemzaponki.ru, который хостится на Таймвебе.
Получение доступов
Нам нужен доступ к хостингу и админке. С админкой всё просто — клиент обычно сам в неё заходит, а потому знает, какой логин и пароль нужно вводить в окне авторизации.
С хостингом сложнее. Иногда клиент даже не в курсе, где располагается его сайт, и нам приходится выяснять это самостоятельно, просматривая DNS-записи домена (например, так). Спрашивать у клиента контакты разработчиков сайта, чтобы узнать эту информацию у них — бесполезно, потому что всегда оказывается, что они канули в лету.
Как только мы определяем, где лежит сайт и как попасть в кабинет хостера, нужно получить логин и пароль для SSH-доступа к серверу. Разнообразие проблем, которые могут возникнуть на этом этапе настолько широко, что для простоты будем считать, что мы это сделали.
Теперь мы случайным образом выбираем одного из тимлидов, назначаем его самым главным (СГ) и ставим задачу о подключении проекта к техподдержке. Дальнейшую работу и перенос изменений будет курировать назначенный СГ, поэтому выдаём ему все полученные доступы
Подключение проекта
Создание репозитория
Сначала СГ должен создать репозиторий на GitLab’е. У нас есть отдельная группа “support”, в которую мы помещаем всех клиентов на техподдержке, названием репозитория обычно служит доменное имя сайта.
С этим этапом справляются все без исключения:
Настройка SSH-ключей
Чтобы Git работал, нужно настроить SSH-доступ по ключам с сервера, где лежит сайт к серверу, где лежит GitLab. Обычно на сервере вновь прибывшего сайта никаких ключей нет, но для очистки совести можно проверить их наличие:
ls -alh ~/.ssh/*.pub
После того, как эта команда ожидаемо ничего не найдёт, можно создать новые:
ssh-keygen -t rsa
Нажимаем Enter до тех пор, пока генератор не перестанет задавать вопросы. Вывести на экран публичную часть созданного ключа можно другой командой:
cat ~/.ssh/id_rsa.pub
Кто никогда не видел, как выглядит SSH ключ — он выглядит так:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfIlgVlFzDwR6UMPpdInI+
sulAmoSjaldEwwZebGK7+DKv3EU+dDcUKiAti0GThx/8pxpa4kVEvrGj6ilH
4BfgFuVbNZQmwVJNIT59fX6PYWX7gpvH0G6BQCl1yQH/4cRlPwts8J7PY4uj
9O08wpbjc1DthXOeBujepeS/3hOOgkgXjuJ1jKQEPjUfhw8v8DBS5tOgIA1Z
STvXNP4HJFV6J57nmCLNWusbe07TwdtvzhEBVzvhTQtOL/lmDi96c4B29rOP
zJrD80vZPUkpHgZyvr0wOdTtTeGwFTwdZeG4q6aE9XIng+QGkkFyNPfsKOS+
Dq207245OsOtqGFjMsl1 it@bizprofi
Копируем то, что отобразилось и добавляем в настройках проекта на GitLab’е:
Можно убедиться, что всё сделано правильно:
someone@mintey:~$ ssh -T git@gitlab.magnifico.pro
Welcome to GitLab, Igor Denisenko!
Если такой надписи не появилось — что-то сделано неправильно.
Настройка GIT
Поскольку в будущем нам придётся коммитить непосредственно с сервера сайта, нужно настроить на нём имя пользователя, от чьего лица будут создаваться коммиты:
git config –global user.name ‘Igor Denisenko’
git config –global user.email ‘im.denisenko@yandex.ru’
Я корыстно использовал в примере свои личные имя и ящик, чтобы все коммиты с сервера шли от моего имени и было видно, кто в компании старается больше всех. На самом деле, можно было написать там что угодно.
Часто на удалённых серверах при попытке запушить коммиты на GitLab возникает такая ошибка:
bizprofi@bitrix120:~/vsemzaponki.ru$ git push origin master
Counting objects: 54294, done.
Delta compression using up to 32 threads.
fatal: unable to create thread: Resource temporarily unavailable
error: failed to push some refs to ‘git@gitlab.magnifico.pro:support/vsemzaponki.ru.git’
Чтобы её избежать, нужно добавить в .gitconfig такой блок:
cat <> ~/.gitconfig
[pack]
windowMemory = 100m
packSizeLimit = 100m
threads = 1
SizeLimit = 100m
EOF
Создание ветки «master»
Будем считать, что сайт vsemzaponki.ru находится в директории ~/vsemzaponki.ru на сервере и зайдём в неё:
cd ~/vsemzaponki.ru
Тут у нас будет располагаться ветка «master» созданного репозитория. Мы умышленно инициируем репозиторий на один уровень выше, чем DOCUMENT_ROOT сайта, чтобы можно было добавить в корне репозитория служебные файлы и не бояться за их сохранность.
git init
git remote add origin git@gitlab.magnifico.pro:support/example.com.git
Перед тем, как создать первый коммит, нужно задать правила исключения для файлов, которые мы в будущем не хотим видеть в ветке «master». Это директория загрузок, дистрибутив Битрикса, внешние зависимости, временные файлы и логи. Так и запишем:
cat < .gitignore
/vendor/
/node_modules/
public_html/upload
public_html/upload/
public_html/cgi-bin/
public_html/bitrix/
public_html/prices/*.csv
public_html/*.xml
public_html/*.csv
public_html/**/*.log
*.tar.gz*
*.gz*
*_cs.cache
*.min.css
*.min.js
.DS_Store
docker-compose.override.yml
/access_log
/error_log
EOF
Теперь добавим все файлы сайта и отправим их на Gitlab:
git add .
git commit -m ‘Here be dragons’
git push -u origin master
Создание ветки bitrix
В созданном нами .gitignore мы исключаем директорию /bitrix/ из ветки master. Но на самом деле нам хотелось бы, чтобы файлы Битрикса также лежали под контролем версий, чтобы можно было упростить процесс переноса сайта между серверами и иметь возможность отслеживать изменения в них.
Методом проб и ошибок мы пришли к тому, что правильнее всего хранить их в том же репозитории, что и основной сайт, но в отдельной ветке, созданной специально под них и независимой от ветки « master». Назовём такую ветку «bitrix»:
cd ~/vsemzaponki.ru/public_html/bitrix
git init
git checkout -b bitrix
git remote add origin git@gitlab.magnifico.pro:support/vsemzaponki.ru.git
У Битрикса — собственные правила исключения:
cat < .gitignore
/tmp/
/cache/
/html_pages/
/stack_cache/
/managed_cache/
/catalog_export/*
!/catalog_export/.gitkeep
/backup/*
!/backup/index.php
/.settings.php
/.settings_extra.php
/php_interface/dbconn.php
*.log*
*.tar.gz*
*_cs.cache
*.min.css
*.min.js
EOF
После того, как мы их создали, можно добавить все файлы и отправить их на GitLab:
git add .
git commit -m ‘Here be dragons too’
git push -u origin bitrix
В репозитории получается такая структура:
Внешние зависимости
В отличие от Битрикса, внешние зависимости, которые можно поставить через npm и composer, в репозиторий не включаются, так как их можно поставить в две команды, восстановив в точности те самые версии, которые нам нужны. Эпичные провалы, как с пакетом leftpad — бывают, но довольно редко, поэтому можно скрестить пальцы и не рассматривать их.
Служебные файлы
Затем СГ копирует из шаблонного проекта служебные файлы, которые облегчат дальнейшее сопровождение созданного репозитория. Таких файлов четыре.
1. Makefile
Позволяет автоматизировать рутинные задачи, не прибегая к сложным системам сборки типа Chef или Ansible. Минимальный набор — команда для переноса изменений с GitLab’а на сайт:
.PHONY: deploy
deploy:
ssh -t vsemzaponki.ru “\
cd ~/vsemzaponki.ru &&\
git fetch origin master –prune &&\
git merge origin/master &&\
cd ~/vsemzaponki.ru/public_html/bitrix &&\
git fetch origin bitrix –prune &&\
git merge origin/bitrix \
“
Теперь можно забыть про особенности конкретного проекта, так как он переносится одной командой:
make deploy
Если в будущем перенос усложнится — добавится сборка скриптов и стилей, установка зависимостей, сброс кеша — разработчик этого не заметит, так как для него интерфейс останется тем же самым.
2. .editorconfig
Файл, который позволяет задать основные правила форматирования для исходников проекта, такие как кодировка файлов, удаление пробелов в конце строк, символ окончания строки. Вопрос следования стандартам оформления кода, к сожалению, не снимает, но хотя бы базовые вещи становятся одинаковыми для всех.
Об этом расширении писали на хабре.
Типичные настройки выглядят так:
root = true
[*]
charset = cp1251
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.yml] indent_size = 2
[Makefile] indent_style = tab
3. .gitattributes
Часть файлов может редактироваться контент-менеджерами прямо на боевом сайте через админку Битрикса. Админка Битрикса, к сожалению, не воспринимает файл .editorconfig, и если менеджер работает с Windows, то в качестве окончаний строк будет использоваться CRLF.
Хуже того, при смене окончаний строк git будет считать, что в редактируемом файле поменялось вообще всё, а не отдельные строки. Это делает невозможным просмотр diff’ов и ведёт к конфликтам при мёрже.
Чтобы всего этого не происходило, можно настроить автоматическую конвертацию окончаний в Unix’овый формат:
cat < .gitattributes
* text=auto
*.js text eol=lf
*.css text eol=lf
*.php text eol=lf
EOF
4. docker-compose.yml
Файл задаёт правила развёртывания локальной копии проекта на компьютере разработчика. Обычно мы его просто копируем из другого проекта:
version: “2”
volumes:
mysql_data: {}
services:
phpfpm:
image: “magnifico/bitrix:phpfpm5.6”
network_mode: “host”
nginx:
image: “magnifico/bitrix:nginx”
network_mode: “host”
mysql:
image: “magnifico/bitrix:mysql”
network_mode: “host”
volumes: [ “mysql_data:/var/lib/mysql” ]
Резервная копия и инструкции
Последний этап: СГ снимает с сайта резервную копию, загружает её на Gitlab и пишет одностраничную инструкцию по разворачиванию проекта на локальной машине. За счёт использования docker’а — в ней минимальное количество пунктов, которые новый разработчик выполняет за 5 минут перед началом работы.
В итоге
Проект успешно интегрирован с системой контроля версий и gitlab’ом: мы можем работать с его исходниками простым и проверенным способом.
Настроен автоматический перенос изменений и интеграция с docker’ом: программист может работать на локальной копии проекта, перенося изменения на продакт только по мере завершения. В потенциально проблемных местах постелена соломка.
Что можно ещё сделать
- Подключить к проекту composer
- Настроить автоматическое тестирование
- Подключить минификацию скриптов и стилей
Когда ситуация нестандартна
Импровизируем. Описанный процесс универсален, и с небольшим количеством отклонений может быть использован на любом хостинге и с любой CMS.