В быстром мире разработки программного обеспечения крайне важно быстро и надежно предоставлять высококачественные приложения. Здесь на помощь приходит CI/CD (непрерывная интеграция и непрерывная доставка/развертывание).
CI/CD — это набор практик и инструментов, предназначенных для автоматизации и оптимизации процесса интеграции изменений в код, их тестирования и развертывания в производственной среде. Приняв CI/CD, ваша команда сможет сократить количество ручных ошибок, ускорить циклы выпуска и гарантировать, что ваш код всегда находится в состоянии, готовом к развертыванию.
В этом учебнике мы сосредоточимся на подходе, удобном для новичков, к настройке базового CI/CD конвейера с использованием Bitbucket, сервера Linux и Python с Flask. В частности, мы создадим автоматизированный процесс, который будет загружать последние изменения из репозитория Bitbucket на ваш сервер Linux всякий раз, когда происходит пуш или слияние в определенную ветку.
Этот процесс будет управляться вебхуками Bitbucket и простым сервером на Flask, написанным на Python, который слушает входящие события вебхуков и инициирует развертывание.
Важно отметить, что CI/CD — это обширная и сложная область, и этот учебник предназначен для предоставления базового понимания, а не для того, чтобы быть исчерпывающим руководством.
Мы рассмотрим основы настройки CI/CD конвейера с использованием инструментов, доступных для новичков. Просто имейте в виду, что реальные системы CI/CD часто включают более сложные инструменты и конфигурации, такие как контейнеризация, оркестрация и многоуровневые тестовые окружения.
К концу этого руководства у вас будет рабочий пример того, как автоматизировать развертывание с помощью Bitbucket, Linux и Python, который вы сможете развивать по мере того, как будете становиться более уверенными в концепциях CI/CD.
Содержание:
Почему CI/CD важен?
CI/CD стал краеугольным камнем современного программирования по нескольким причинам. Прежде всего, он ускоряет процесс разработки. Автоматизируя повторяющиеся задачи, такие как тестирование и развертывание, разработчики могут сосредоточиться больше на написании кода и меньше на ручных процессах. Это приводит к более быстрой доставке новых функций и исправлений ошибок, что особенно важно на конкурентных рынках, где скорость может быть определяющим фактором.
Еще одним ключевым преимуществом CI/CD является уменьшение ошибок и повышение надежности. Автоматизированное тестирование гарантирует, что каждое изменение кода тщательно проверяется на наличие проблем прежде, чем оно будет интегрировано в основную кодовую базу. Это минимизирует риск появления ошибок, которые могут нарушить работу приложения или потребовать дорогостоящих исправлений позже. Автоматизированные конвейеры развертывания также снижают вероятность человеческой ошибки во время процесса выпуска, обеспечивая, чтобы развертывания были последовательными и предсказуемыми.
CI/CD также способствует лучшему сотрудничеству между участниками команды. В традиционных процессах разработки интеграция изменений кода от нескольких разработчиков может быть времязатратным и подверженным ошибкам процессом. С CI/CD код интегрируется и тестируется часто, зачастую несколько раз в день. Это означает, что конфликты выявляются и решаются на ранней стадии, а кодовая база остается в стабильном состоянии. В результате команды могут работать более эффективно и с большей уверенностью, даже когда несколько участников работают над разными частями проекта одновременно.
Наконец, CI/CD поддерживает непрерывное улучшение и инновации. Автоматизируя процесс развертывания, команды могут чаще выпускать обновления в продуктивную среду и с меньшим риском. Это позволяет им быстрее собирать отзывы от пользователей и более эффективно итеративно улучшать свои продукты.
Что мы рассмотрим в этом учебном пособии
В этом учебном пособии мы пройдем через процесс настройки простой CI/CD пайплайна, который автоматизирует развертывание изменений кода из репозитория Bitbucket на сервер Linux. Вот что вы узнаете:
-
Как настроить репозиторий Bitbucket для отправки уведомлений вебхука всякий раз, когда происходит пуш или слияние в конкретную ветку.
-
Как настроить сервер на базе Flask с использованием Python на вашем сервере Linux, чтобы слушать входящие события вебхука.
-
Как написать скрипт, который будет извлекать последние изменения из репозитория и разворачивать их на сервере.
-
Как протестировать и отладить ваш автоматизированный процесс развертывания.
К концу этого урока у вас будет рабочий пример базового CI/CD пайплайна, который вы сможете настраивать и расширять по мере необходимости. Давайте начнем!
Шаг 1: Настройка вебхука в Bitbucket
Перед началом настройки давайте кратко объясним, что такое вебхук и как он вписывается в наш процесс CI/CD.
Вебхук — это механизм, который позволяет одной системе уведомлять другую систему о событии в реальном времени. В контексте Bitbucket вебхук можно настроить для отправки HTTP-запроса (часто POST-запроса с данными) на указанный URL всякий раз, когда происходит определенное событие в вашем репозитории, например, при пуше в ветку или слиянии пулл-запроса.
В нашем случае вебхук будет уведомлять наш сервер на основе Flask (работающий на вашем Linux-сервере) всякий раз, когда происходит пуш или слияние в определенную ветку. Это уведомление запустит скрипт на сервере, который извлечет последние изменения из репозитория и автоматически развернет их. По сути, вебхук выступает в роли моста между Bitbucket и вашим сервером, обеспечивая бесшовную автоматизацию процесса развертывания.
Теперь, когда вы понимаете роль вебхука, давайте настроим его в Bitbucket:
-
Войдите в Bitbucket и перейдите в ваш репозиторий.
-
В левой боковой панели нажмите на Настройки.
-
В разделе Рабочий процесс найдите и нажмите на Webhooks.
-
Нажмите кнопку Добавить webhook.
-
Введите имя для вашего webhook (например, “Автоматический Pull”).
-
В поле URL укажите URL вашего сервера, на который webhook будет отправлять запрос. Если вы запускаете Flask приложение локально, это будет что-то вроде
http://your-server-ip/pull-repo
. (Для производственных сред настоятельно рекомендуется использовать HTTPS для защиты связи между Bitbucket и вашим сервером.) -
В разделе Триггеры выберите события, на которые вы хотите подписаться. В этом примере мы выберем Push (и при желании, Слияние запросов на вытягивание, если вы хотите развертывать после слияний тоже).
-
Сохраните вебхук с самопоясняющим названием, чтобы его было легко идентифицировать позже.
После настройки вебхука Bitbucket будет отправлять POST-запрос на указанный URL каждый раз, когда происходит выбранное событие. В следующих шагах мы настроим сервер Flask для обработки этих входящих запросов и запуска процесса развертывания.
Вот что вы должны увидеть, когда настраиваете вебхук Bitbucket
Шаг 2: Настройка слушателя Flask на вашем сервере Linux
На следующем шаге вы настроите простой веб-сервер на вашем Linux-машине, который будет слушать вебхуки от Bitbucket. Когда он получит уведомление, он выполнит git pull
или принудительное извлечение (в случае локальных изменений), чтобы обновить репозиторий.
Установите Flask:
Чтобы создать приложение Flask, сначала установите Flask, выполнив:
pip install flask
Создайте приложение Flask:
Создайте новый Python-скрипт (например, app_repo_pull.py
) на вашем сервере и добавьте следующий код:
from flask import Flask
import subprocess
app = Flask(__name__)
@app.route('/pull-repo', methods=['POST'])
def pull_repo():
try:
# Получите последние изменения из удаленного репозитория
subprocess.run(["git", "-C", "/path/to/your/repository", "fetch"], check=True)
# Принудительно сбросьте локальную ветку, чтобы она соответствовала удаленной ветке 'test'
subprocess.run(["git", "-C", "/path/to/your/repository", "reset", "--hard", "origin/test"], check=True) # Замените 'test' на имя вашей ветки
return "Force pull successful", 200
except subprocess.CalledProcessError:
return "Failed to force pull the repository", 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Вот что делает этот код:
-
subprocess.run
(["git", "-C", "/path/to/your/repository", "fetch"])
: Эта команда извлекает последние изменения из удаленного репозитория, не затрагивая локальный рабочий каталог. -
subprocess.run
(["git", "-C", "/path/to/your/repository", "reset", "--hard", "origin/test"])
: Эта команда выполняет жесткий сброс, заставляя локальный репозиторий соответствовать удаленной веткеtest
. Заменитеtest
на имя вашей ветки.
Не забудьте заменить /path/to/your/repository
на фактический путь к вашему локальному репозиторию Git.
Шаг 3: Открытие Flask-приложения (по желанию)
Если вы хотите, чтобы Flask-приложение было доступно извне вашего сервера, вам нужно сделать его общедоступным. Для этого вы можете настроить обратный прокси с помощью NGINX. Вот как это сделать:
Сначала установите NGINX, если он у вас еще не установлен, выполнив эту команду:
sudo apt-get install nginx
Далее вам нужно будет настроить NGINX, чтобы проксировать запросы к вашему Flask-приложению. Откройте файл конфигурации NGINX:
sudo nano /etc/nginx/sites-available/default
Измените конфигурацию, чтобы включить этот блок:
server {
listen 80;
server_name your-server-ip;
location /pull-repo {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Теперь просто перезагрузите NGINX, чтобы применить изменения:
sudo systemctl reload nginx
Шаг 4: Проверьте настройку
Теперь, когда все настроено, запустите Flask-приложение, выполнив этот скрипт на Python:
python3 app_repo_pull.py
Теперь, чтобы протестировать, работает ли всё:
- Создайте коммит: Отправьте коммит в ветку
test
вашего репозитория Bitbucket. Это действие вызовет вебхук.
-
Срабатывание вебхука: Вебхук отправит POST-запрос на ваш сервер. Приложение Flask получит этот запрос, выполнит принудительное извлечение из ветки
test
и обновит локальный репозиторий. -
Проверьте извлечение: Проверьте вывод журнала вашего приложения Flask или просмотрите локальный репозиторий, чтобы убедиться, что изменения были успешно извлечены и применены.
Шаг 5: Соображения по безопасности
При открытии приложения Flask в интернете важно обеспечить безопасность вашего сервера и приложения, чтобы защитить их от несанкционированного доступа, утечек данных и атак. Вот ключевые области, на которые следует обратить внимание:
1. Используйте защищённый сервер с правильными правилами брандмауэра
Защищённый сервер — это тот, который настроен для минимизации воздействия внешних угроз. Это включает использование правил брандмауэра, минимизацию ненужных служб и обеспечение того, чтобы только необходимые порты были открыты для связи.
Пример настройки защищённого сервера:
-
Минимальное программное обеспечение: Устанавливайте только необходимое программное обеспечение (например, Python, Flask, NGINX) и удаляйте ненужные службы.
-
Обновления операционной системы: Убедитесь, что операционная система вашего сервера обновлена и содержит последние исправления безопасности.
-
Настройка брандмауэра: Используйте брандмауэр для контроля входящего и исходящего трафика и ограничения доступа к вашему серверу.
Например, базовая конфигурация UFW (Uncomplicated Firewall) на Ubuntu может выглядеть так:
# Разрешить SSH (порт 22) для удаленного доступа
sudo ufw allow ssh
# Разрешить HTTP (порт 80) и HTTPS (порт 443) для веб-трафика
sudo ufw allow http
sudo ufw allow https
# Включить брандмауэр
sudo ufw enable
# Проверить статус брандмауэра
sudo ufw status
В этом случае:
-
Брандмауэр разрешает входящие SSH-соединения на порту 22, HTTP на порту 80 и HTTPS на порту 443.
-
Любые ненужные порты или службы должны быть заблокированы по умолчанию, чтобы ограничить уязвимость к атакам.
Дополнительные правила брандмауэра:
-
Ограничить доступ к конечной точке вебхука: В идеале, разрешить трафик к конечной точке вебхука только с IP-адресов Bitbucket, чтобы предотвратить внешний доступ. Вы можете настроить это в своем брандмауэре или с помощью вашего веб-сервера (например, NGINX), принимая запросы только из диапазона IP-адресов Bitbucket.
-
Запретить весь другой входящий трафик: Для любых служб, которые не должны быть доступны из интернета (например, порты базы данных), убедитесь, что эти порты заблокированы.
2. Добавить аутентификацию в приложение Flask
Поскольку ваше приложение Flask будет общедоступным через URL вебхука, вы должны рассмотреть возможность добавления аутентификации, чтобы гарантировать, что только авторизованные пользователи (например, серверы Bitbucket) могут инициировать получение.
Пример базовой аутентификации:
Вы можете использовать простую аутентификацию на основе токенов для защиты вашего вебхука. Вот пример того, как модифицировать ваше приложение Flask, чтобы оно требовало аутентификационный токен:
from flask import Flask, request, abort
import subprocess
app = Flask(__name__)
# Определите секретный токен для проверки вебхука
SECRET_TOKEN = 'your-secret-token'
@app.route('/pull-repo', methods=['POST'])
def pull_repo():
# Проверьте, содержит ли запрос правильный токен
token = request.headers.get('X-Hub-Signature')
if token != SECRET_TOKEN:
abort(403) # Запрет доступа, если токен неверный
try:
subprocess.run(["git", "-C", "/path/to/your/repository", "fetch"], check=True)
subprocess.run(["git", "-C", "/path/to/your/repository", "reset", "--hard", "origin/test"], check=True)
return "Force pull successful", 200
except subprocess.CalledProcessError:
return "Failed to force pull the repository", 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Как это работает:
-
Заголовок
X-Hub-Signature
— это пользовательский заголовок, который вы добавляете в запрос при настройке вебхука в Bitbucket. -
Только запросы с правильным токеном будут разрешены для выполнения pull. Если токен отсутствует или неверный, запрос отклоняется с ответом
403 Forbidden
.
Вы также можете использовать более сложные формы аутентификации, такие как OAuth или HMAC (Message Authentication Code на основе хэша), но простой подход с токеном работает во многих случаях.
3. Используйте HTTPS для безопасной передачи данных
Очень важно шифровать данные, передаваемые между вашим приложением Flask и вебхуком Bitbucket, а также любые конфиденциальные данные (например, токены или пароли), передаваемые по сети. Это гарантирует, что злоумышленники не смогут перехватить или изменить данные.
Почему HTTPS?
-
Шифрование данных: HTTPS шифрует коммуникацию, гарантируя, что такие чувствительные данные, как ваш токен аутентификации, не будут подвергнуты атакам типа “человек посередине”.
-
Доверие и целостность: HTTPS помогает гарантировать, что данные, полученные вашим сервером, не были изменены.
Использование Let’s Encrypt для защиты вашего Flask-приложения с помощью SSL:
- Установите Certbot (инструмент для получения сертификатов Let’s Encrypt):
sudo apt-get update
sudo apt-get install certbot python3-certbot-nginx
Получите бесплатный SSL-сертификат для вашего домена:
sudo certbot --nginx -d your-domain.com
-
Эта команда автоматически настроит Nginx для использования HTTPS с бесплатным SSL-сертификатом от Let’s Encrypt.
-
Убедитесь, что используется HTTPS: Убедитесь, что ваше Flask-приложение или конфигурация Nginx заставляют весь трафик использовать HTTPS. Вы можете сделать это, настроив правило перенаправления в Nginx:
server {
listen 80;
server_name your-domain.com;
# Перенаправление HTTP на HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# Другие настройки Nginx...
}
Автоматическое обновление: сертификаты Let’s Encrypt действительны в течение 90 дней, поэтому важно настроить автоматическое обновление:
sudo certbot renew --dry-run
Эта команда проверяет процесс обновления, чтобы убедиться, что все работает.
4. Логирование и мониторинг
Реализуйте логирование и мониторинг для вашего приложения Flask, чтобы отслеживать несанкционированные попытки, ошибки или необычную активность:
-
Логировать запросы: Логируйте все входящие запросы, включая IP-адрес, заголовки запроса и статус ответа, чтобы вы могли отслеживать любую подозрительную активность.
-
Используйте инструменты мониторинга: Настройте такие инструменты, как Prometheus, Grafana или New Relic, чтобы следить за производительностью сервера и состоянием приложения.
Заключение
В этом руководстве мы рассмотрели, как настроить простой и удобный для новичков CI/CD процесс, который автоматизирует развертывания с использованием Bitbucket, сервера Linux и Python с Flask. Вот краткое резюме того, что вы узнали:
-
Основы CI/CD: Мы обсудили основы Непрерывной Интеграции (CI) и Непрерывной Доставки/Развертывания (CD), которые являются основными практиками для автоматизации интеграции, тестирования и развертывания кода. Вы узнали, как CI/CD помогает ускорить разработку, снизить количество ошибок и улучшить сотрудничество между разработчиками.
-
Настройка вебхуков Bitbucket: Вы узнали, как настроить вебхук Bitbucket для уведомления вашего сервера каждый раз, когда происходит push или merge в конкретную ветку. Этот вебхук служит триггером для автоматического запуска процесса развертывания.
-
Создание слушателя вебхуков на Flask: Мы показали вам, как настроить приложение Flask на вашем сервере Linux для прослушивания входящих запросов вебхуков от Bitbucket. Это приложение Flask получает уведомления и выполняет необходимые команды Git для получения и развертывания последних изменений.
-
Автоматизация процесса развертывания: С помощью Python и Flask мы автоматизировали процесс получения изменений из репозитория Bitbucket и выполнения принудительного получения для обеспечения развертывания последнего кода. Вы также узнали, как настроить сервер для экспонирования приложения Flask и безопасного приема запросов.
-
Соображения по безопасности: Мы рассмотрели критически важные шаги по обеспечению безопасности вашего процесса развертывания:
-
Правила файрвола: Мы обсудили настройку правил файрвола для ограничения доступа и обеспечения того, чтобы только авторизованный трафик (из Bitbucket) мог получить доступ к вашему серверу.
-
Аутентификация: Мы добавили аутентификацию на основе токенов, чтобы гарантировать, что только авторизованные запросы могут инициировать развертывания.
-
HTTPS: Мы объяснили, как защитить связь между вашим сервером и Bitbucket с помощью SSL-сертификатов от Let’s Encrypt.
-
Журналирование и мониторинг: Наконец, мы рекомендовали настроить журналирование и мониторинг, чтобы отслеживать любую необычную активность или ошибки.
-
Следующие шаги
К концу этого учебника у вас теперь есть рабочий пример автоматизированного пайплайна развертывания. Хотя это базовая реализация, она служит основой, на которой вы можете строить. По мере того как вы будете становиться более уверенными в CI/CD, вы сможете исследовать более сложные темы, такие как:
-
Многоступенчатые пайплайны развертывания
-
Интеграция с инструментами контейнеризации, такими как Docker
-
Более сложные стратегии тестирования и развертывания
-
Использование инструментов оркестрации, таких как Kubernetes, для масштабирования
Практики CI/CD постоянно развиваются, и, освоив основы, вы подготовили себя к успеху, расширяя свои навыки в этой области. Удачной автоматизации и спасибо за чтение!
Вы можете скопировать код отсюда.
Source:
https://www.freecodecamp.org/news/create-a-basic-cicd-pipeline-with-webhooks-on-linux/