Helcode | Хелкод | Скрипты и автоматизация
992 subscribers
52 photos
34 links
☎️ Контакты для связи: @helcodeadm
Download Telegram
"Пару слов" про оптимизацию Docker-образов

Коллеги, есть у меня одна "больная тема". Вижу в CI/CD пайплайнах образы на гигабайты, которые тянут за собой пол-интернета при каждом деплое. При этом внутри - бубунту с полным набором пакетов ради одного скрипта на питоне.

Почему это плохо? Каждый лишний мегабайт в образе - это:
- Медленный пулл на нодах
- Лишнее место в регистри
- Долгий старт подов
- Лишний трафик

Что с этим делать:

Используйте alpine где можно. Базовый образ питона на alpine весит 50 МБ вместо 900 МБ на дебиане. Разница очень ощутима.

Чистите за собой кэши. Если ставите пакеты через apt, не забывайте про apt-get clean && rm -rf /var/lib/apt/lists/*. В том же alpine с apk та же история.

Многослойная сборка. Классика: в одном слое компилируете, во второй кладёте только результат. В итоге в финальном образе нет ни компиляторов, ни исходников, ни временных файлов.

# Билдер
FROM golang:1.20 AS builder
COPY app.go .
RUN go build -o /app app.go

# Финальный образ
FROM alpine:latest
COPY --from=builder /app /app
CMD ["/app"]


Объединяйте RUN-инструкции. Каждый RUN создаёт отдельный слой. Если разнести установку пакетов и чистку по разным RUN, то в промежуточном слое кэши останутся и будут торчать в финальном образе.

# Плохо
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get clean

# Хорошо
RUN apt-get update && \
apt-get install -y curl && \
apt-get clean


Не тащите лишние файлы. .dockerignore рулит. Не тащите в образ .git, тесты, документацию и локальные конфиги.

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

🌐 @helcode
3👍3🔥2
Скрипты на bash и их предсказуемость

Поймал себя на мысли, что многие пишут bash-скрипты как придётся. Запустили, оно вроде работает, и ладно. А потом скрипт падает в три часа ночи, потому что переменная оказалась пустой или в названии файла попался пробел.

Есть вещи, которые я всегда добавляю в начало любых скриптов:

#!/bin/bash
set -euo pipefail


➤ Разбор полётов:
- -e — скрипт умирает при первой же ошибке. Без этого флага он продолжит выполнение, даже если команда упала, и вы можете получить кашу.
- -u — если переменная не объявлена, скрипт сразу падает. Без этого флага пустая переменная превратится в пустую строку и может натворить дел (например, rm -rf $UNDEFINED удалит всё, потому что команда превратится в rm -rf).
- -o pipefail — если в пайпе что-то упало, весь пайп считается упавшим. Без этого флага false | true вернёт успех.

Проверка аргументов. Если скрипт требует аргументы, проверяйте их сразу.

if [ -z "${1:-}" ]; then
echo "Ошибка: не указан конфигурационный файл"
exit 1
fi


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

# Плохо
rm -rf $SOME_DIR

# Хорошо
rm -rf "$SOME_DIR"


Проверка на существование. Если скрипт работает с файлами, проверяйте, что они есть.

if [ ! -f "$CONFIG_FILE" ]; then
echo "Файл конфигурации не найден: $CONFIG_FILE"
exit 1
fi


Логирование. Пишите в stdout, что происходит. Это потом спасёт при разборе инцидентов.

echo "[$(date +'%Y-%m-%d %H:%M:%S')] Начинаю бэкап базы данных"


Я иногда смотрю на чужие скрипты и вижу там отсутствие этих простых вещей. В итоге скрипт работает на машине автора, потому что там есть нужные файлы и переменные, но падает на чистой системе. А виноват потом "кривой линух".

У вас были случаи, когда bash-скрипт падал из-за неожиданного пробела в имени файла или незаданной переменной?

🌐 @helcode
🔥9👍32🙏2
Про автоматизацию обновления сертификатов

Каждый, кто админит свои сервера, через это проходил. Просыпаешься утром, а сайт не открывается. Лезешь в логи, а там "SSL certificate expired". Руки чешутся, кофе стынет, сертификат протух ещё неделю назад.

Почему это вообще происходит. Let's Encrypt даёт сертификаты на 90 дней. Это не их прихоть, а стандарт индустрии - короткие сертификаты безопаснее. Но человеческая память короче 90 дней, и ручное обновление рано или поздно проспишь.

➤ 1. Ставим certbot. Он умеет не только получать сертификаты, но и продлевать их.
apt-get install certbot python3-certbot-nginx


➤ 2. Разово получаем сертификат.
certbot --nginx -d example.com -d www.example.com


➤ 3. Настраиваем автоматическое продление. Certbot создаёт systemd-таймер сам при установке. Проверить можно так:
systemctl status certbot.timer
systemctl list-timers | grep certbot


Таймер запускается два раза в день и проверяет, не пора ли обновить сертификаты. Если до истечения осталось меньше 30 дней - обновляет.

➤ 4. Добавляем хуки на перезагрузку. После обновления nginx нужно перезагрузить, чтобы он подхватил новый сертификат.
certbot renew --renew-hook "systemctl reload nginx"


➤ 5. Проверяем, что всё работает.
certbot renew --dry-run


Если вдруг certbot не вариант. Бывает, что сервер в закрытом контуре или используются внутренние CA. Тогда пишется простой скрипт в cron:

#!/bin/bash
# renew-internal-cert.sh

CERT_PATH="/etc/ssl/certs/myapp.crt"
EXPIRY_DAYS=$(openssl x509 -in "$CERT_PATH" -noout -enddate | cut -d= -f2 | xargs -I{} date -d "{}" +%s)
CURRENT=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_DAYS - CURRENT) / 86400 ))

if [ $DAYS_LEFT -lt 7 ]; then
echo "Сертификат скоро истекает ($DAYS_LEFT дней). Запускаю обновление..."
/usr/local/bin/update-internal-cert.sh
systemctl reload nginx
fi


В cron добавляется еженедельный запуск:
0 2 * * 1 /root/renew-internal-cert.sh


Важный момент. Автоматика автоматикой, но я всё равно добавляю мониторинг на дату истечения. Например, в Prometheus можно экспортировать метрику с днями до протухания и настроить алерт, если осталось меньше недели. Тогда даже если автоматика почему-то не сработала, будет время вмешаться вручную.

У кого как организовано обновление сертификатов? Доверяете автоматике или ходите раз в три месяца ручками продлевать?

🌐 @helcode
4👍3🔥1
Коллеги, рад всех приветствовать! Мы закончили миграцию: теперь нас можно читать не только в Телеграм!

Недавно я запускал голосование с вопросом: куда мигрируем на случай блокировки Телеграм? Вы ответили - и довольно однозначно. Спасибо всем, кто участвовал в опросе и оставлял комментарии.

Всё это время я не сидел сложа руки. Была изучена статистика, проанализированы площадки, где присутствует техническая аудитория, проанализировано удобство работы с контентом на различных площадках. Выводы сделаны, инфраструктура настроена.

Что имеем на выходе:

Основной канал как был в Телеграм, так и остается. Сюда я буду писать в первую очередь, здесь же будет основное обсуждение. Никаких "уходим навсегда" не планируется. Также, был переработан формат постов для адекватного репоста в иные соц. сети, весь .md формат (код) уходит в изображение. В ближайшее время мы с ним "познакомимся".

Но теперь у @helcode есть официальные зеркала на двух дополнительных площадках:

VK - для тех, кто привык читать ленту в соцсети и не хочет ставить лишние мессенджеры. Туда уходят все посты синхронно с Телеграм. Минус - в комментарии захожу реже, но читаю.

Boosty - для любителей блог-формата. Там же будет постепенно появляться расширенная версия некоторых материалов, если тема глубокая и не влезает в короткий пост. Об этом буду обязательно оповещать.

Статический сайт пока отложил. Идея хорошая, но требует времени на поддержку, которого и так в обрез. Возможно, вернусь к ней, когда накопится критическая масса контента, которую неудобно искать в соцсетях.

Резюмирую. Канал жив, контент выходит по плану, темы по автоматизации, Linux и утилитам никуда не делись. Если завтра Телеграм вдруг станет совсем недоступен - вы знаете, где искать. Все "перекрестные" ссылки будут под каждым постом!

🌐 @helcode
👍13👌41🔥1
Коллеги, всех приветствую!

Давно хотел показать что-то действительно полезное и при этом созданное внутри нашего сообщества. Знакомьтесь: DevToolbox Cheats - проект подписчика @boomlavka.

Для тех, кто, как и я, работает в Linux и постоянно ловит себя на мысли: "А какой там флаг у tar...?", "Как правильно смонтировать диск...?", "А как сбросить настройку iptables...?".

Что сделал автор? Он взял и упаковал более 100 готовых шпаргалок (Git, Bash, Docker, RegEx, Ansible и ещё много чего) в удобный интерфейс, который встраивается прямо в панель вашего рабочего стола.

Чем проект цепляет лично меня:
1. Универсальность: неважно, сидите вы в KDE, GNOME, XFCE или даже в голом i3 - утилита сама подстроится и будет выглядеть как родная.
2. Скорость: кэширование отрабатывает так, что список команд появляется быстрее, чем открывается браузер.
3. Копирование в один клик: нашёл команду - ткнул - она уже в буфере. Минимум телодвижений.
4. Умное редактирование: если встроенных шпаргалок вдруг покажется мало, автор продумал сценарий на любой случай. Можно открыть конфиг в любимом редакторе (VS Code, Geany и др.) - скрипт сам определит, что у вас стоит. Если редактор не найден или вы работаете в minimal окружении - файл откроется прямо во всплывающем окошке zenity.

Мы часто обсуждаем автоматизацию на уровне систем и скриптов, но автоматизация личного рабочего процесса - это то, что экономит часы каждую неделю. DevToolbox Cheats - именно про это. Не надо гуглить, не надо лезть в заметки. Просто кликнул на иконку и продолжил работу.

ВАЖНО:

Я знаю, что @boomlavka продолжает развивать проект, и ему, как любому разработчику, важна обратная связь. Если вы покопаетесь в репозитории и найдёте баг, или наоборот - придумаете, как улучшить - не стесняйтесь писать автору или создавать issue на GitHub. Сообщество сильное только тогда, когда Мы помогаем друг другу становиться лучше.

👉 Ссылка на [GitHub](https://github.com/dominatos/devtoolbox-cheats)
Буду благодарен, если поставите звёздочку тем, кто зайдёт. Автору будет приятно, а каналу - почётно, что наши коллеги делают полезные инструменты.

P.S. Если у кого-то тоже есть свои проекты или полезные наработки - смело пишите в личку (@helcodeadm). Покажем, обсудим, поддержим.

🌐 @helcode
6🤔3
Helcode | Хелкод | Скрипты и автоматизация pinned «Коллеги, рад всех приветствовать! Мы закончили миграцию: теперь нас можно читать не только в Телеграм! Недавно я запускал голосование с вопросом: куда мигрируем на случай блокировки Телеграм? Вы ответили - и довольно однозначно. Спасибо всем, кто участвовал…»
Ansible: миф об идемпотентности и как не прострелить себе ногу

Ansible позиционируется как идемпотентный инструмент: можно запустить плейбук сто раз, и система будет в одном и том же состоянии. В теории - красиво, на практике - не всегда. Главная боль возникает, когда вы начинаете писать собственные сценарии с модулями command или shell. Они по умолчанию не идемпотентны. Запустите их дважды - они выполнятся дважды.

Чтобы побороть это, используют параметры creates и removes (проверка наличия файла-маркера), changed_when и failed_when (тонкая настройка условий изменения и ошибки). Но это всё костыли. Если вы ловите себя на том, что часто используете shell вместо специализированных модулей (copy, template, file, lineinfile, package), значит, вы пишете не декларативный код, а процедурный скрипт на bash внутри Ansible.

Стоит помнить: Ansible хорош ровно настолько, насколько хорошо вы используете его модули. Если задача сложная и требует логики, может быть, проще написать скрипт на Python и вызвать его через модуль script, сохранив идемпотентность на уровне внешнего скрипта.

🌐 @helcode
👍9🤔32
Доброго времени суток! Попробуем истории из личной практики?)

Довелось мне на одном из проектов поработать с человеком, который писал комментарии к каждой строчке кода. Буквально к каждой, никаких преувеличений. Выглядело это примерно так:

# Увеличиваем счетчик на 1
i = i + 1;
# Проверяем, не больше ли 10
if (i > 10) {
# Если больше, сбрасываем
i = 0;
}

Сначала это было действительно забавно. Спустя время мы пытались объяснить, что код должен быть "самодокументируемым" (поясню для тех, кто с термином не знаком. Это некий стиль написания кода, при котором он пишется настолько ясно, чисто и понятно, что не требует внешних комментариев для понимания его логики работы).

Через примерно год его код превратился в простыню, где читать комментарии было дольше, чем разбираться в логике. А когда он уволился и нужно было править его модуль, мы осознали весь звиздец ситуации: комментарии были на русском, переменные на английском, а логика - на каком-то своём, крайне непонятном.

При этом, половина комментариев уже давно не соответствовала реальности, потому что код меняли, а комментарии не трогали. Зачем, верно?)

На самом деле, даже рад случившемуся, много полезного усвоил. После той ситуации и отношение к коду/комментариям поменялось. Стараюсь писать максимально понятно.

🌐 @helcode
😁51👎1🌚1
Небольшая история про оптимизацию

Была у нас микросервисная архитектура. Красивая, как в учебниках. Каждый сервис делал что-то одно и делал хорошо. Только вот беда - их было 47 штук.

Один сервис отвечал за генерацию PDF, второй за отправку писем, третий за превьюшки картинок, четвёртый за сборку всего этого в отчёты... Ну, вы поняли.

Прилетает задача: ускорить генерацию отчёта. Менеджеры жалуются - целых 3 секунды приходится ждать, "пока там крутится".

Полез оптимизировать. Лимиты поднял, запросы распараллелил, кэширование добавил. В общем, добился ускорения до 1.5 секунд. Пошёл к руководству, отчитываться.

Получил вопрос: "А логи посмотрел?". Вернулся, пошёл смотреть логи... 0.5 секунды из 1.5 - сбор метрик для нашего же мониторинга, ещё 0.5 - запись в лог...

Выключил метрики на тестовом стенде, отчёт прилетел за 0.3 секунды. Теперь стараюсь придерживаться правила: прежде чем оптимизировать - посмотреть, сколько времени жрёт наблюдаемость.

P.S. Если вдруг заходит подобный формат - пишите, буду периодически рассказывать что-то из личной практики)

🌐 @helcode
👍272😁2
Недавно в комментариях упоминал сайт SadServers. Обещал рассказать - выполняю.

Фактически, это некий тренажёр для получения практических навыков. Вкратце: вам дают сервер, который "сломан" определённым образом. Нам дают описание проблемы, время на выполнение и задачу: пофиксить. После изучения задачи тыкаем "run" и получаем доступ по SSH к проблемной машине прямо в браузере. Интересно, не так ли?)

Сценариев там под сотню (если не больше), разбиты по категориям: Linux/Bsh, Web Servers, Databases, Data Processing, Docker, Kubernetes, Tooling, Hacking, Languages. Описал буквально всё. Также, сценарии разбиты на категории по сложности:

- Easy - для разминки. Типа "почему не стартует SSH?" или "кто жрёт память". Проходятся за 10-15 минут, если руками всё умеешь.
- Medium - тут уже интереснее. Может быть проблема с неправильными правами, кривым конфигом или процессом, который падает при старте, но оставляет мутные логи.
- Hard - для тех, кто хочет поплакать. Например: "PostgreSQL не отвечает, но в логах тишина, и всё настроено правильно. Спойлер: не правильно".

Большая часть доступна бесплатно, но присутствуют и сценарии по подписке. Также, важно упомянуть:

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


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

Ссылку прилагаю: https://sadservers.com/scenarios

🌐 @helcode
👍142🔥1
Я храню список своих факапов...

У меня есть файл. Называется "failures .md". Там лежат все мои ошибки за последние годы.

Не чтобы себя мучить, а чтобы не наступать на те же грабли. Проблемы часто повторяются, решение забывается. Следовательно, повторяются и ошибки...

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

Иногда я перечитываю этот файл перед сложными задачами. Знаете, как некую мантру: "Проверь права доступа, не деплой в пятницу, сделай бекап".

Некоторые коллеги говорят, что это паранойя. Но когда в очередной раз кто-то наступает на те же грабли, я открываю свой файл и скидываю ссылку: "Почитай, у меня уже было".

Стыдно за ошибки? Сначала было. Потом понял, что ошибаются все. Умные просто стараются не повторять.

А вы ведёте дневник ошибок или полагаетесь на память?

🌐 @helcode
👍161🔥1
Три вещи, которые я проверяю, когда сервер тормозит

Был у меня период, когда любое падение производительности я встречал с одним рефлексом - лезть в код. Казалось, что если сервер еле дышит, значит, я где-то накосячил с алгоритмами.

Переписывал запросы, оптимизировал функции, добавлял кэши там, где они не нужны. А потом выяснялось, что проблема была вообще не в коде. Просто кто-то запустил бекап в "час пик" или диск забился логами.

Со временем выработался некий чек-лист. Три точки, которые я проверяю в первую очередь, прежде чем трогать код.

Первое - память.

Самый частый сценарий: какой-то процесс утёк и сожрал всю оперативку. Система начинает свопиться - сбрасывать данные на диск. А диск даже самый быстрый - это не оперативная память. Всё встаёт колом.

Смотрю free -h. Если used почти равно total, а swap использован - значит, память под завязку. Дальше htop показывает, кто жрёт. Часто помогает простой перезапуск проблемного процесса, чтобы выиграть время на поиск настоящей причины.

Второе - диск.

Бывает, памяти дофига, процессор простаивает, а сервер еле шевелится. Это классический I/O wait - процессы висят в очереди на чтение или запись.

Смотрю iotop. Если вижу, что какой-то процесс постоянно долбит диск на максимальной скорости - вот он, виновник. Чаще всего это:

- Забытый бекап, который решил запуститься в обед
- Логи, которые пишутся в один файл без ротации годами
- База, которая выполняет тяжёлый запрос и не влезает в память

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

Третье - сеть.

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

Смотрю mtr до сервера из внешней точки. Если потери начинаются на конкретном узле до моего железа - вопрос к провайдеру. Если на самом сервере - проверяю загрузку сетевого интерфейса через iftop.

Что дальше

Если с памятью, диском и сетью всё в порядке - тогда уже лезу в код, логи, базу. Но в восьми случаях из десяти проблема находится на этом первом этапе. И решается не оптимизацией запросов, а убийством кривого процесса или разговором с коллегой, который запустил бекап не вовремя.

А вы с чего начинаете диагностику?

🌐 @helcode
👍10🔥72💯1
Makefile: единый интерфейс для команд проекта

Каждый проект обрастает набором команд для установки, тестирования и запуска. Хранить их в памяти или в wiki - неэффективно. Makefile позволяет собрать все команды в одном месте и сделать их доступными через короткие алиасы.

Новый разработчик в проекте выполняет make help и видит все доступные операции.

* Вариант 1 (Python-проект): сокращение часто используемых команд.
.PHONY: install run test clean

install:
pip install -r requirements.txt

run:
python app.py

test:
pytest tests/

clean:
find . -type d -name "__pycache__" -exec rm -rf {} +


* Вариант 2 (Node.js + Docker): объединение нескольких шагов в один.
.PHONY: docker-build docker-run logs

docker-build:
docker build -t myapp .

docker-run: docker-build
docker run -p 3000:3000 myapp

logs:
docker logs myapp-container


Makefile работает как документация. Если команда сложная, ее не нужно искать в истории терминала - она записана и всегда под рукой.

Используете ли вы Makefile в проектах, не связанных с C/C++?

P.S. Make умеет отслеживать изменения файлов и перезапускать только те команды, которые действительно нужны.

Важно! На Boosty расписал пост подробно. Телеграм имеет определенные ограничения на длину.

Я в Telegram - t.me/helcode
Я в VK - vk.com/helcode
Я на Boosty - boosty.to/helcode
👍61
Pre-commit хуки: автоматические проверки до коммита

Код-ревью часто превращается в обсуждение форматирования, отступов и забытых отладочных принтов. Это отвлекает от реальных проблем - архитектуры и логики работы.

Pre-commit хуки запускают проверки автоматически и не дают создать коммит, если код не соответствует стандартам.

Вариант 1 (Базовый конфиг для Python): автоматическое приведение кода к единому стилю.
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace # Удаляет пробелы в концах строк
- id: end-of-file-fixer # Добавляет перевод строки в конце файла
- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black # Форматирует код


Вариант 2 (Проверка секретов): блокировка коммита с потенциальными ключами доступа.
  - repo: https://github.com/Yelp/detect-secrets
rev: v1.4.0
hooks:
- id: detect-secrets


После настройки хуков код в репозитории всегда проходит базовые проверки. Это снижает нагрузку на ревьюверов.

Есть ли у вас в проекте автоматические проверки перед коммитом?

P.S. Конфигурация pre-commit хранится в репозитории, поэтому все разработчики в команде используют одинаковые проверки.

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
5👍2🔥1
Bash-скрипты для регулярных операций

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

Скрипт можно запустить вручную или по расписанию через cron. Результат всегда предсказуем.

Вариант 1 (Бэкап БД с ротацией):
#!/bin/bash
BACKUP_DIR="/backups/postgres"
DB_NAME="myapp"
DATE=$(date +%Y%m%d_%H%M%S)

# Создание дампа
pg_dump $DB_NAME > $BACKUP_DIR/db_backup_$DATE.sql

# Сжатие
gzip $BACKUP_DIR/db_backup_$DATE.sql

# Удаление бэкапов старше 7 дней
find $BACKUP_DIR -name "db_backup_*.sql.gz" -mtime +7 -delete

echo "Backup completed: db_backup_$DATE.sql.gz"


Вариант 2 (Синхронизация с S3):
tar -czf logs_$(date +%Y%m%d).tar.gz /var/log/myapp && aws s3 cp logs_$(date +%Y%m%d).tar.gz s3://myapp-logs-bucket/ --storage-class STANDARD_IA

Скрипты в репозитории обеспечивают прозрачность процессов. Любой член команды может посмотреть, как именно выполняется бэкап или синхронизация.

Что в ваших проектах автоматизировано скриптами, а что до сих пор делается вручную?

P.S. Добавление в скрипты проверок кодов возврата (set -e) и логирования делает их пригодными для использования в промышленной среде.

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
👍52🔥1
GitLab CI: автоматизация сборки и доставки

Ручной деплой на сервер требует запоминания последовательности команд и несет риск ошибки из-за человеческого фактора. CI/CD-пайплайны делают процесс воспроизводимым: одна и та же последовательность шагов выполняется каждый раз.

GitLab CI встроен в систему контроля версий, что позволяет привязать деплой к событиям в репозитории.

Вариант 1 (Тесты и деплой на staging):
# .gitlab-ci.yml
stages:
- test
- deploy

run_tests:
stage: test
script:
- npm install
- npm run test

deploy_staging:
stage: deploy
script:
- rsync -avz --delete ./ user@staging-server:/var/www/html/
only:
- develop


Вариант 2 (Ручной деплой на продакшн по тегу):
deploy_production:
stage: deploy
script:
- ansible-playbook -i prod.inventory deploy.yml
only:
- tags
when: manual


Пайплайн гарантирует, что код перед попаданием на продакшен проходит все необходимые проверки в одинаковом окружении.

Кто выполняет деплой в вашей команде - разработчик или CI-система?

P.S. В GitLab CI можно переиспользовать шаблоны через include, чтобы не дублировать код пайплайнов в разных проектах.

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
👍2
Управление зависимостями Python: фиксация версий

Обновление пакетов в Python-проекте без системы управления зависимостями часто приводит к неожиданным поломкам. Пакет обновляется, тянет за собой другие версии библиотек, и приложение перестает работать.

Современные инструменты разделяют понятия "зависимости, которые нам нужны" и "конкретные версии, которые установлены".

* Вариант 1 (Poetry):
# Команды для работы с зависимостями
poetry add requests@latest # Добавление или обновление пакета
poetry update # Обновление всех пакетов в рамках ограничений
poetry export -f requirements.txt --output requirements.txt # Экспорт для Docker


* Вариант 2 (pip-tools): pазделение на прямые и транзитивные зависимости.
# update_deps.sh
pip-compile requirements.in # Генерация requirements.txt с фиксированными версиями
pip-sync requirements.txt # Приведение окружения к состоянию из requirements.txt


Фиксация версий через lock-файлы гарантирует, что у всех разработчиков и на сервере будет одинаковый набор библиотек.

Используете ли вы pip freeze или более продвинутые инструменты для управления зависимостями?

P.S. Файл с зафиксированными версиями (poetry.lock или requirements.txt) должен быть в репозитории, а файл с верхнеуровневыми зависимостями (pyproject.toml или requirements.in) - тем более.

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
👍2
Vagrant: изоляция через виртуальные машины

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

Vagrant позволяет поднимать виртуальные машины с заданными параметрами и автоматически их настраивать.

* Вариант 1 (Веб-сервер под Ubuntu):
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
config.vm.network "private_network", ip: "192.168.56.10"
config.vm.provider "virtualbox" do |vb|
vb.memory = "2048"
vb.cpus = 2
end
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y apache2
SHELL
end


* Вариант 2 (Кластер из двух машин): поднятие взаимодействующих серверов для тестирования распределенных приложений.

vagrant up создает чистую среду, vagrant destroy полностью ее удаляет. Это позволяет тестировать установку и настройку с нуля без захламления основной системы.

Для каких задач в вашей команде используют виртуальные машины вместо контейнеров?

*P.S. Vagrant работает поверх VirtualBox, VMware или гипервизоров облачных провайдеров, предоставляя единый интерфейс управления.*

🌐 @helcode
5👍4
ERR в bash: отлавливаем ошибки там, где set -e бессилен

Все знают про set -e, который прерывает скрипт при первой ошибке. Но у него есть особенности: он срабатывает не на все ошибки, и его поведение может меняться в зависимости от контекста. Например, ошибка в конвейере (`cmd1 | cmd2`) не остановит скрипт, если не включен set -o pipefail. Или ошибка в условии if — там set -e вообще игнорируется.

Но есть механизм, который дает полный контроль над обработкой ошибок — ловушка ERR. trap 'echo "Ошибка в строке $LINENO"' ERR сработает при любой ошибке выполнения команды, независимо от настроек set -e. Причем вы получите номер строки, где это случилось.

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

Важно помнить: ловушка ERR не ловит ошибки в функциях, если они вызываны в подшеллах. И если вы явно игнорируете ошибку через cmd || true, ERR тоже не сработает.

Как вы обрабатываете неожиданные ошибки в скриптах — надеетесь на set -e или пишете полноценные обработчики?

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
👍61🔥1
Midnight Commander - это та утилита, которая кажется бессмысленной, пока не появится задача на сервере, где нужно быстро перекинуть 50 файлов из одной папки в другую. cp -r с кучей флагов - это долго. А в mc это делается секунд за 10.

Как это работает:

Запустили mc - две панели. Левая папка, правая папка. Стрелки - навигация. Tab - переключить панель. F5 - копировать, F6 - переместить, F7 - создать папку, F8 - удалить. Всё.

Где реально выручает

· Выборочное копирование. Нужно из 500 файлов перенести 20 конкретных? Отмечаем их пробелом, жмём F5 - готово.
· Редактирование на месте. Нажали F4 - открылся редактор с подсветкой. Поправили конфиг - Ctrl+S, F10 - вышел.
· Архивы. Нажали Enter на .tar.gz - внутри, как в обычной папке. Копируем файлы наружу, не распаковывая всё.

Скрытые плюсы

· Alt+O - открыть текущую папку на второй панели. Удобно, когда нужно скопировать файл в параллельную ветку.
· Внизу можно писать команды, не выходя из mc. Например, tar -czf backup.tar.gz * - и архив готов.
· Мышь работает, но лучше привыкнуть к клавишам.

Если вы помните все флаги rsync и find - mc не нужен. Если нет - ставится одной командой и экономит время каждый раз, когда нужно что-то переложить на сервере.

P.S. Прошу прощения за несколько уведомлений, Телеграм решил, что не будет планировать мой пост, а дропнет сразу…

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
🔥7👍51
fzf: поиск, который работает везде

Каждый день мы ищем: файлы в проекте, команды в истории, процессы для убийства. grep находит, но не выбирает. fzf добавляет интерактивный поиск с нечетким сопоставлением туда, где его раньше не было.

Утилита принимает список строк на вход, а на выходе отдаёт выбранную.

➤ Вариант 1 (Поиск по истории команд): привязка к Ctrl+R превращает поиск в истории из слепого перебора в интерактивную прогулку.
# Добавить в .bashrc или .zshrc
bind '"\C-r": "\C-e \C-u history | fzf --tac --no-sort | xargs -I {} echo {}"'

➤ Вариант 2 (Быстрый переход в папку): больше не нужно помнить, где лежит проект, запущенный месяц назад.
# Переход в любую папку в проектах
cd $(find ~/projects -type d 2>/dev/null | fzf)

# Или с предпросмотром содержимого
cd $(find ~/projects -type d | fzf --preview 'ls -la {}')

➤ Вариант 3 (Поиск и убийство процесса): нашел процесс глазами — убил, не выходя из поиска.
# Выбрали процесс — отправили SIGTERM
kill -15 $(ps aux | fzf | awk '{print $2}')

# С предпросмотром деталей процесса
kill -15 $(ps aux | fzf --preview 'echo {}' | awk '{print $2}')

fzf
работает как пайплайн: слева что угодно (файлы, процессы, строки), справа — действие над выбранным. Один раз настроив, вы получаете интерактивность там, где раньше был только слепой grep.

Используете ли вы интерактивный поиск в терминале или предпочитаете старый добрый Ctrl+R?

*P.S. В zsh можно настроить автодополнение команд через fzf — набираем kill **, нажимаем Tab, и выбираем процесс из списка.*

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode (тут выходит более подробный материал)
6🔥2👍1