Сообщения

Наконец-то GitHub Pages (и GitLab Pages — для симметрии)

Изображение
Давно присматривался к GitHub Pages , но руки никак не доходили. Внезапно решил навести порядок на площадках, где публикую статьи и заметки, и решился-таки на статику (как доп. площадку). Всякие разные Pages GitHub Pages нативно поддерживает Jekyll — пушнул в репозиторий, и сайт сам собрался. Никаких докеров, никаких CI/CD (ну почти), никаких серверов. А чтобы было совсем хорошо, решил поддерживать и GitLab Pages — для симметрии. Чтоб не привязываться к одной платформе и чтоб было куда переключиться, если что. Но тут без CI/CD никак. Структура репозитория и настройки Репозиторий называется как положено — kinnalru.github.io - тогда он будет доступен по этому доменному имени. Gemfile: gem "github-pages", group: :jekyll_plugins group :jekyll_plugins do gem "jekyll-feed" gem "jekyll-sitemap" end Обратите внимание на github-pages — это мета-гем, который тянет Jekyll и все нужные плагины в совместимых версиях. Никаких "а у меня ...

Опять синхронизация, но теперь блогов

Есть у меня небольшой фетиш по синхронизации… И в очередной раз, подойдя к проблеме блога, я наконец собрал разрозненные куски в единую систему :) Кто к нам с чем и зачем? За годы у меня накопилась целая коллекция площадок, куда я (и не только я) что-то публикую: Личный блог на Teletype — сюда пишу руками Корпоративный блог blog.rnds.pro — пишем вместе с коллегами Dev.to — личный аккаунт kinnalru и корпоративная организация RNDSOFT GitHub Pages — kinnalru.github.io Blogger (Blogspot) — kinnalru.blogspot.com Раньше тут обитал ещё и ~~Hashnode~~ , но теперь у этих негодяев платное API для публикации — пусть сами к себе пишут. Как теперь работает схема Пишу статью вручную в Teletype (личное) или в корпоративный блог. Статьи автоматически улетают в черновики Dev.to через RSS Перед публикацией на Dev.to я добавляю FrontMatter original_author=kinnalru . Публикуем: личные — от себя, корпоративные — от организации RNDSOFT По крону (через GitLab Pipelines) запус...

SQLite в Docker: жить хорошо, а хорошо жить — ещё лучше (Litestream)

Изображение
Иногда хочется, чтобы всё было просто. Взял Rails-приложение, завернул в Docker, запустил — и оно работает. Без отдельной СУБД, без монтирования хранилища для картинок и пр. Но вот незадача: если взять SQLite , положить её в контейнер и запустить — при docker rm ваша база улетает в никуда. Навсегда. Вместе с пользователями, настройками и всем, что вы так старательно назаполняли. Сегодня расскажу, как я в pet-проекте RuNiT решил эту проблему с помощью Litestream — и просто кайфую. Проблема Классический путь деплоя pet-проекта выглядит так: Поднять PostgreSQL в отдельном контейнере (найти под него постоянное хранилище и сервак) Прокинуть volume Понять, что вы тратите больше времени на администрирование СУБД, и хранилище картинок, чем на разработку фич Для pet-проекта это ощутимый оверхед. SQLite решает первый пункт, но создаёт два других: файл базы живёт внутри контейнера и при пересоздании исчезает бэкапов нет, и если сервер упал — всё, приплыли. Тут бы и с...

Syncerman: от bash-скриптов к Go cli для пяти облаков одновременно

Изображение
Иногда, чтобы решить свою проблему, приходится написать инструмент. А иногда — чтобы написать инструмент, приходится решить свою проблему. Короче, как обычно, всё началось не с идеи сделать утилиту, а с того, что добавилась пара важных документов (по иппотке) к существующему зоопарку данных, которые надо хранить. Как я к этому пришел У меня давно назрела проблема: синхронизировать разные файлы с разных рабочих мест — по крайней мере дома и на работе. Документы (важные), сохранения из игр, книги для читалки. Ну и надёжный архив всего этого добра, потому что терять даже что-то незначительное это боль 🤕. Просто положить всё в одно облако — хорошо, но нужен ещё постоянный процесс актуализации. Яндекс Диск работает, Google Drive может изменить условия, Dropbox может внезапно ограничить доступ. Поэтому идея была простая: хранить копии везде . Яндекс Диск , Google Drive , Mail.ru Cloud , Dropbox — чем больше, тем надёжнее. Только файлы, только хардкор! Раньше я обходился консол...

DevSecOps подкрался незаметно, хотя заметен был издалека…

Изображение
DevSecOps уверенно шагает по нашей индустрии, и горе тому, кто попадёт под его поступь… Эта статья про ~~ультимативную~~ сборку базовых образов для Ruby для удовлетворения самых параноидальных потребностей ИБ. Да, именно об этом мы и расскажем - что такое "инсталляция ruby", где, что, почему лежит и как с этим жить нашему пайплайну сборки и самому приложению. Статья подойдёт тем, кто хочет более глубоко понимать, какие процессы происходят в системе, когда вызывается gem install , bundle install или (не дай Бог) gem update –system Как было до? С самого начала появления docker мы в RNDSOFT использовали парадигму "всё включено". Для нас это означало, что в образ мы включаем всё, что нам надо не только для продуктовой эксплуатации, но и для проведения всех тестов. При прохождении CI пайплайна на следующие стадии продвигался образ целиком и, в конце концов, выкатывался на прод. Это было очень удобно и позволяло быть максимально (насколько это вообще во...

Использование Scientist для рефакторинга критических участков Ruby on Rails приложения

Изображение
Перевод статьи “Using Scientist to Refactor Critical Ruby on Rails Code” Darren Broemmer от 18 мая 2022 года. Попросите любого программиста просмотреть ключевые участки продуктового кода, и он обязательно укажет на несколько моментов, требующих рефакторинга. Почему же так много плохого, ненадежного или непонятного кода продолжает работать в продуктовом окружении? Ответ прост: инженеры боятся его трогать. Задачи для рефакторинга обнаруживаются и добавляются в бэклог, но редко попадают в текущий спринт. Для этого есть множество причин. Код мог быть написан программистом, давно покинувшим команду и теперь в нём никто не разбирается. Бывает что этот код имеет решающее значение для бизнеса и из-за этого никто не хочет нести ответственность за потенциальный сбой или потерю дохода. В данном посте мы рассмотрим, как можно использовать гем Scientist для уверенной миграции, рефакторинга и изменения критического продуктового Ruby-кода. Но сначала вы спросите — а нельзя ли использов...

Чистка build-агентов Gitlab

Изображение
Оригинал: https://blog.rnds.pro/030-gitlab-janitor Спешим поделиться с вами нашим инструментом для поддержания чистоты и порядка на наших (RNDSOFT) сборочных серверах gitlab-janitor . О том, как мы к нему пришли, и каков первый опыт - далее по тексту. С каждым годом инфраструктура RNDSOFT, обеспечивающая процессы CI/CD, растёт. Появляются новые проекты, усложняются процессы (pipelines) сборки и тестирования, растет количество сборщиков (build agents), и всё это приносит дополнительные накладные расходы. Сегодня мы рассмотрим конкретную проблему - чистку/освобождение ресурсов на самих сборочных серверах. Мы используем Gitlab и несколько Gitlab runners с докером ( docker executor ) под капотом. Вот с проблем и начнём. Проблемы Вся терминология будет опираться на Gitlab , но всё это применимо и к другим решениям, опирающимся на docker. Типовой процесс сборки и доставки состоит из 4х больших этапов (stages), по несколько задач (jobs) в каждом: сборка docker-образа (обычно о...

Согласование потоков Qt и не только. Активная 'посылка'

Решил поиграться с библиотекой Wt для написания веб сервисов на c++ и столкнулся с интересной задачей согласования произвольных потоков и Qt фреймворка, а точнее как доставить событие нажатия Wt::WButton в мой Qt::QWidget. В общем случае задача проста - есть колбэк из произвольного(не Qt) потока и надо выполнить действие над обычным QObject‘ом. Мне, почему-то, сразу пришла в голову следующая аналогия: Qt это огромный футуристический город из вращающихся по своим законам шестерёнок, в котором могут легко жить только исконно местные жители - КуЖители, общающиеся на своём ‘языке сигналов‘. А я(сторонний фреймворк) стою перед входом в город с сообщением, которое надо передать одному из этих жителей. Теперь немного о том как это вообще можно сделать: Ринуться с посылкой прямо в город, рискуя быть перемолотым шестернями(нарваться на гонки потоков): MyQObject* object; wtbutton.clicked().connect(object, &MyQObject::doSomethig); //Или если используем лямбды: wtbutton.clicked().c...