🎩 Книга «Денди-код» о том, как сделать код аккуратным и понятным

Илья Лящук

Backend, Frontend, Weekend

Мои первые шаги в Open Source: процессы, тесты и работа с сообществом

Я начал всерьёз погружаться в Open Source в начале 2025 года. Тогда это было скорее любопытство и желание попробовать что-то новое, чем чёткий план. Спустя время я заметил, что мои проекты начали находить отклик, появились первые пользователи, а затем и первые контрибьюторы.

За последний год я выпустил несколько релизов, постепенно выстроил базовые процессы тестирования и начал относиться к своим проектам как к продуктам, за которые я несу ответственность. Это был важный переход в мышлении — от «я что-то написал» к «я поддерживаю и развиваю проект».

Я не могу сказать, что у меня большой или глубокий опыт в Open Source. Скорее наоборот — я всё ещё в начале пути. Но все же я хочу рассказть о том на какие вещи, как мне кажется, стоит обратить внимание тем, кто только думает о создании своего первого открытого проекта.

Мой GitHub – https://github.com/prog-time

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

С чего начинается идея

В основе почти всех Open Source-проектов лежит не прямая монетизация, а социальное признание: звёзды на GitHub, комментарии, репосты, подписчики. Эти метрики становятся своего рода обратной связью — сигналом, что твоя работа кому-то действительно нужна и интересна. Да, иногда появляются донаты или спонсоры, но рассчитывать на стабильный доход в начале пути — плохая идея.

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

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

Для вдохновения вы можете посмотреть проекты которые сейчас в тренде на GitHub или подписаться на Topic по интересующему вас направлению https://github.com/trending.

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

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

Если проект ориентирован на пользователей, не связанных с разработкой (как в моём случае), приоритеты смещаются. Здесь особенно важно уделять внимание:

  • производительности и оптимизации;
  • качественной и понятной документации;
  • простоте установки и быстрому развёртыванию проекта.

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

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

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

В моём случае проекты чаще представляли собой отдельные сервисы, поэтому довольно рано я сделал ставку на контейнеризацию. Docker оказался идеальным инструментом: он позволяет изолировать зависимости, стандартизировать окружение и избавить пользователя от большинства проблем, связанных с локальной настройкой. Это особенно важно в Open Source, где ты не можешь контролировать, в каком окружении проект будут запускать.

Хорошим примером для меня стал проект tg-support-bot. В нём я сразу заложил два сценария установки. Первый — полный, через docker-compose, где поднимаются все необходимые сервисы: PostgreSQL, PgAdmin, Loki, Grafana, Redis и другие компоненты. Второй — упрощённый, рассчитанный на обычный хостинг, с возможностью подключить внешнюю базу данных и отключить необязательные сервисы.

Отдельно я постарался избежать жёстких связей между контейнерами. Для меня было важно, чтобы пользователь мог безболезненно отключать или заменять отдельные сервисы внутри docker-compose, не ломая при этом основное приложение. Такой подход даёт гибкость и делает проект более дружелюбным для разных сценариев использования.

Линтинг, CI и тесты

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

Первое, с чего я начинаю, — это правила code style. Чем более чётко и однозначно они описаны, тем проще поддерживать кодовую базу в читаемом и предсказуемом состоянии, особенно когда в проект приходят новые участники.

Дальше я настраиваю линтеры, которые автоматически проверяют код на несколько ключевых вещей: синтаксические ошибки и проблемы с типизацией, соответствие имен переменных и функций принятому стилю, а также типичные ошибки и потенциальные уязвимости. В результате большая часть проблем отлавливается ещё до ревью или запуска кода, а обсуждения в pull request’ах смещаются с формальных правок к действительно важным архитектурным решениям.

Параллельно этому я активно покрываю весь функционал Unit тестами. Чем больше функциональности покрыто тестами, тем спокойнее ты относишься к изменениям в коде. Это особенно чувствуется в Open Source, где в проект могут прийти сторонние контрибьюторы, и ты не всегда знаешь, какие именно изменения они предложат.

В проекте tg-support-bot я решил подойти к этому вопросу максимально прагматично. Вместо сложных и тяжёлых решений я реализовал набор shell-скриптов, которые тесно интегрированы с git-хуками и работают на нескольких уровнях.

На этапе коммита запускаются проверки только тех файлов, которые добавлены в индекс. Статический анализатор PHPStan проверяет код на ошибки и проблемы с типизацией, запускаются unit-тесты для изменённых классов. Если в коммите затронут Dockerfile, автоматически запускается Hadolint, а изменения в shell-скриптах проверяются с помощью ShellCheck, который хорошо выявляет типичные ошибки и потенциальные уязвимости.

Пример работы линтеров

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

Финальным уровнем становится CI. Здесь проект проверяется ещё раз полностью, что особенно важно для Open Source. Внешние контрибьюторы могут прислать изменения, которые проходят локальные проверки, но ломают логику или инфраструктуру проекта. CI служит последней линией обороны и не позволяет таким изменениям попасть в основную ветку.

Пример работы CI

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

Структура GitHub-репозитория

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

Во всех своих проектах я стараюсь придерживаться одной и той же схемы работы с ветками. Основной веткой всегда является main, и прямые коммиты в неё запрещены. Любые изменения — даже самые мелкие — попадают туда только через дочерние ветки и pull request’ы.

Для каждой отдельной задачи из релиза создаётся своя ветка. В названии ветки обязательно указывается номер соответствующего Issue — это жёсткое правило, без исключений. Если ветка названа некорректно, она просто не пройдёт проверки CI, и изменения не смогут быть влиты в проект. На первый взгляд это может показаться излишней строгостью, но на практике такой подход сильно упрощает жизнь.

Пример структуры веток и коммитов

Документирование

Даже самая полезная библиотека или сервис теряют смысл, если пользователи и контрибьюторы не понимают, как её использовать.

Для меня документация делится на несколько ключевых элементов:

README.md

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

CONTRIBUTING.md

Он описывает, как внести изменения в проект, какие правила создания веток и коммитов я использую, как отправлять pull request и какие требования предъявляются к тестированию и линтингу. Без такого руководства сторонние контрибьюторы часто тратят лишнее время на догадки и пробные ошибки, что снижает их мотивацию.

GitHub Wiki

Для более детальной и структурированной документации я активно использую Wiki. Данный раздел позволяет создавать несколько страниц, объединённых логикой, и описывать архитектуру проекта, деплой, CI/CD, гайды по использованию библиотек и сервисов.

Практические правила, которыми я руководствуюсь:

  1. Документировать ключевое сразу, не откладывая на потом — иначе теряется контекст и появляются лишние вопросы.
  2. Использовать шаблоны и стандарты (Markdown, OpenAPI, DocBlock), чтобы документация была однородной.
  3. Поддерживать документацию в актуальном состоянии — каждое новое изменение должно сопровождаться обновлением описаний.

GitHub Wiki

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

Взаимодействие с аудиторией

Успешный Open Source-проект — это не только код, но и люди, которые его используют. Активное взаимодействие с аудиторией помогает не только продвигать проект, но и получать ценную обратную связь, которая часто оказывается важнее любой документации.

Первым шагом для меня стало создание удобного канала связи. В tg-support-bot я создал отдельную Telegram-группу, где публикую новости, отвечаю на часто задаваемые вопросы и просто общаюсь с пользователями.

Telegram tg-support-bot

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

Чтобы проект рос, важно привлекать пользователей из внешних источников. Для меня эффективным инструментом стал видеоконтент — Dev-блог, в котором я показываю процесс разработки и делюсь личным опытом. Видеоинструкции по установке и настройке проекта снижают порог входа и делают продукт более доступным для новичков.

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

Заключение

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

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

Автоматизация в Laravel: как ускорить и упростить процесс разработки

Автоматизация в Laravel

Работа над проектом на Laravel становится заметно эффективнее, если автоматизировать как можно больше этапов — от конфигурации окружения до проверки кода и тестирования. В этом материале я расскажу, как сделать рабочий процесс надёжным, уменьшить ручную рутину и поддерживать качество кода на высоком уровне.

Материал рассчитан на тех, кто уже знаком с Laravel и хочет внедрить в проект автоматические проверки, единый стиль кода, статику и готовую Docker-инфраструктуру. Я поделюсь используемыми инструментами, примерами конфигураций и реалистичными скриптами.

Docker-Compose как основа окружения

Я всегда начинаю проект с продуманной конфигурации Docker Compose — это дает сразу готовое изолированное окружение, минимизирует конфликты зависимостей и ускоряет старт работы. Обычно в моём составе используются следующие сервисы:

  • php-fpm – выполнение PHP-кода приложения
  • PostgreSQL – реляционная база данных
  • Grafana + Loki – визуализация метрик и логов
  • pgAdmin – веб-интерфейс для управления БД
  • Redis – Кэш и очереди Laravel
  • Insight – визуализация данных Redis
  • Queue – выполнение фоновых задач
services:
    app:
        build: .
        container_name: pet
        user: root
        depends_on:
            - pgdb
            - redis
            - loki
        env_file:
            - .env
        working_dir: /var/www/
        volumes:
            - .:/var/www
        networks:
            - pet
        dns:
            - 8.8.8.8
            - 1.1.1.1

    pgdb:
        container_name: pgdb
        image: postgres
        tty: true
        restart: always
        environment:
            - POSTGRES_DB=${DB_DATABASE}
            - POSTGRES_USER=${DB_USERNAME}
            - POSTGRES_PASSWORD=${DB_PASSWORD}
        ports:
            - ${PGDB_PORT}
        volumes:
            - ./docker/postgres:/var/lib/postgresql/data
        networks:
            - pet

    nginx:
        image: nginx:latest
        container_name: nginx
        restart: unless-stopped
        ports:
            - ${NGINX_PORT}
            - "443:443"
        volumes:
            - .:/var/www
            - ./docker/nginx:/etc/nginx/conf.d
            - /etc/letsencrypt:/etc/letsencrypt:ro
        environment:
            - TZ=${SYSTEM_TIMEZONE}
        depends_on:
            - pgdb
            - app
            - pgadmin
        networks:
            - pet

    pgadmin:
        image: dpage/pgadmin4:latest
        restart: always
        depends_on:
            - pgdb
        environment:
            - PGADMIN_DEFAULT_EMAIL=${PGADMIN_EMAIL}
            - PGADMIN_DEFAULT_PASSWORD=${PGADMIN_PASSWORD}
        ports:
            - ${PGADMIN_PORT}
        networks:
            - pet

    redis:
        image: redis:latest
        container_name: redis
        restart: always
        ports:
            - ${REDIS_PORT}
        environment:
            - REDIS_PASSWORD=${REDIS_PASSWORD}
        command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"]
        networks:
            - pet

    redisinsight:
        image: redislabs/redisinsight:latest
        container_name: redisinsight
        ports:
            - ${REDISINSIGHT_PORT}
        volumes:
            - ./docker/redisinsight:/db
        restart: always
        networks:
            - pet

    grafana:
        image: grafana/grafana:latest
        container_name: grafana
        user: "472"
        ports:
            - ${GRAFANA_PORT}
        environment:
            - GF_SECURITY_ADMIN_USER=${GRAFANA_USER}
            - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
        volumes:
            - ./docker/grafana:/var/lib/grafana
        depends_on:
            - loki
        networks:
            - pet

    queue:
        build: .
        image: docker_template:latest
        container_name: laravel_queue
        restart: always
        depends_on:
            - app
            - redis
        env_file:
            - .env
        working_dir: /var/www
        volumes:
            - .:/var/www
        command: php artisan queue:work --sleep=3 --tries=3 --timeout=90
        networks:
            - pet
        dns:
            - 8.8.8.8
            - 1.1.1.1

    loki:
        image: grafana/loki:latest
        container_name: loki
        ports:
            - ${LOKI_PORT}
        networks:
            - pet

volumes:
    pgdata:
networks:
    pet:
        driver: bridge

Каждый из этих сервисов разворачивается в отдельном контейнере. Такой подход даёт преимущества:

  • гибкая настройка окружения под проект;
  • независимое управление зависимостями;
  • возможность обновлять части системы без остановки всего стека.

Совет: можно использовать готовый шаблон docker-compose.yml, который сразу поднимает все сервисы и настраивает базовые параметры Laravel.

Поддержание единого стиля кода с Laravel Pint

Для автоматического форматирования и приведения к единому стилю я использую laravel/pint. Он позволяет:

  • автоматически исправлять стиль кода при запуске;
  • интегрироваться в CI или докерные сценарии;
  • соблюдать стандарт PSR-12 без ручных усилий.

Пример конфигурации pint.json:

{
    "preset": "psr12",
    "exclude": [
        "vendor",
        "storage",
        "node_modules",
        "bootstrap/cache"
    ],
    "rules": {
        "array_syntax": {
            "syntax": "short"
        },
        "binary_operator_spaces": {
            "default": "single_space"
        },
        "braces": true,
        "class_attributes_separation": {
            "elements": {
                "const": "one",
                "method": "one",
                "property": "one"
            }
        },
        "no_unused_imports": true,
        "ordered_imports": true,
        "phpdoc_separation": true,
        "phpdoc_align": true,
        "single_quote": true,
        "ternary_to_null_coalescing": true,
        "trailing_comma_in_multiline": {
            "after_heredoc": true
        },
        "types_spaces": {
            "space": "none"
        },
        "phpdoc_no_empty_return": false,
        "no_superfluous_phpdoc_tags": false,
        "concat_space": {
            "spacing": "one"
        }
    }
}

Такая конфигурация помогает стандартизировать стиль: синтаксис массивов, расположение операторов, форматирование импортов и PHPDoc.

Запуск Pint перед коммитом — хорошая практика, она поддерживает чистоту кода автоматически.

Статический анализ: PHPStan + Larastan

Чтобы ловить ошибки и потенциальные проблемы ещё на этапе разработки, я применяю комбинацию phpstan/phpstan и nunomaduro/larastan. Эти инструменты позволяют:

  • находить некорректное использование типов;
  • выявлять отсутствие проверок;
  • предупреждать баги до запуска приложения.

Пример конфигурации phpstan.neon:

parameters:
    level: 6
    paths:
        - app
        - routes
    excludePaths:
        - vendor
        - storage
        - bootstrap

    errorFormat: table
    checkMissingVarTagTypehint: false
    inferPrivatePropertyTypeFromConstructor: true

    ignoreErrors:
        - identifier: missingType.iterableValue
        - identifier: missingType.generics
        - '#referenced with incorrect case#'

includes:
    - vendor/phpstan/phpstan/conf/bleedingEdge.neon

Основные преимущества такого подхода:

  • ошибки фиксируются ещё до запуска функционала;
  • повышается надёжность и стабильность кода;
  • анализ становится частью процесса разработки.

Автоматические проверки через Git Hooks и shell-скрипты

Чтобы гарантировать, что все коммиты соответствуют стандартам, я применяю Git Hooks + shell-скрипты:

Основные идеи:

Pre-commit: проверка изменённых файлов обрабатываются только изменённые файлы (для скорости); запускаются Pint и PHPStan на этих файлах; при ошибках коммит блокируется до исправления.

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

Проверка наличия тестов Скрипт проверяет, что для любого нового или изменённого класса создан соответствующий тест в директории tests. Например, если добавлен класс app/Services/UserService.php, ожидается файл tests/Unit/Services/UserServiceTest.php.

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

Примеры скриптов

Скрипт для проверки с PHPStan (pre-commit / push)

Скрипт для проверки с PHPStan

#!/bin/bash
COMMAND="$1"  # commit или push

if [ "$COMMAND" = "commit" ]; then
  NEW_FILES=$(git diff --cached --name-only --diff-filter=A | grep '\.php$')
  if [ -n "$NEW_FILES" ]; then
    vendor/bin/phpstan analyse --no-progress --error-format=table $NEW_FILES || exit 1
  fi
fi

BASELINE_FILE=".phpstan-error-count.json"
[ ! -f "$BASELINE_FILE" ] && echo "{}" > "$BASELINE_FILE"

if [ "$COMMAND" = "commit" ]; then
  ALL_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.php$' || true)
elif [ "$COMMAND" = "push" ]; then
  BRANCH=$(git rev-parse --abbrev-ref HEAD)
  ALL_FILES=$(git diff --name-only origin/$BRANCH --diff-filter=ACM | grep '\.php$' || true)
fi

if [ -n "$ALL_FILES" ]; then
  for FILE in $ALL_FILES; do
    ERR_NEW=$(vendor/bin/phpstan analyse --error-format=raw --no-progress "$FILE" 2>/dev/null | grep -c '^')
    ERR_OLD=$(jq -r --arg file "$FILE" '.[$file] // empty' "$BASELINE_FILE")
    [ -z "$ERR_OLD" ] && ERR_OLD=$ERR_NEW

    TARGET=$((ERR_OLD - 1))
    [ "$TARGET" -lt 0 ] && TARGET=0

    if [ "$ERR_NEW" -le "$TARGET" ]; then
      jq --arg file "$FILE" --argjson errors "$ERR_NEW" '.[$file] = $errors' "$BASELINE_FILE" > tmp && mv tmp "$BASELINE_FILE"
    else
      echo "Ошибка статического анализа в $FILE: $ERR_NEW (допустимо ≤ $TARGET)"
      vendor/bin/phpstan analyse --error-format=table "$FILE"
      exit 1
    fi
  done
fi

exit 0

Скрипт для проверки Pint стиля

Скрипт для проверки Pint стиля

#!/bin/bash
COMMAND="$1"

if [ "$COMMAND" = "commit" ]; then
  ALL_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.php$' || true)
elif [ "$COMMAND" = "push" ]; then
  BRANCH=$(git rev-parse --abbrev-ref HEAD)
  ALL_FILES=$(git diff --name-only origin/$BRANCH --diff-filter=ACM | grep '\.php$' || true)
fi

if [ -n "$ALL_FILES" ]; then
  vendor/bin/pint --test $ALL_FILES
  if [ $? -ne 0 ]; then
    vendor/bin/pint $ALL_FILES
    echo "$ALL_FILES" | xargs git add
    exit 1
  fi
fi

exit 0

Проверка наличия тестов для классов

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

Скрипт получает список изменённых и добавленных PHP-файлов и ищет соответствующий тестовый файл в директории tests.

Например, если в проекте есть класс app/Services/UserService.php, скрипт потребует создать файл теста tests/Unit/Services/UserServiceTest.php. Таким образом, любой новый или изменённый класс обязательно должен иметь соответствующий тест, что помогает поддерживать качество и надёжность кода.

Это скрипт, который постоянно дополняется, поэтому актуальную версию вы можете посмотреть здесь – https://github.com/prog-time/git-hooks

Скрипт для проверки Pint стиля

Проверка работы Docker сборки

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

Скрипт может автоматически останавливать текущие контейнеры, заново собирать их и запускать в фоне. После запуска выполняется проверка состояния через docker ps или docker compose ps, чтобы убедиться, что все контейнеры находятся в статусе healthy или up.

#!/bin/bash

echo "=== Остановка всех контейнеров ==="
docker-compose down

echo "=== Сборка контейнеров ==="
docker-compose build

echo "=== Запуск контейнеров в фоне ==="
docker-compose up -d

# Пауза для запуска сервисов
echo "=== Ждем 5 секунд для старта сервисов ==="
sleep 5

echo "=== Проверка состояния контейнеров ==="
# Получаем статус всех контейнеров
STATUS=$(docker-compose ps --services --filter "status=running")

if [ -z "$STATUS" ]; then
  echo "Ошибка: ни один контейнер не запущен!"
  exit 1
else
  echo "Запущенные контейнеры:"
  docker-compose ps
fi

# Дополнительно можно проверять HEALTHCHECK каждого контейнера
echo "=== Проверка состояния HEALTH ==="
docker ps --filter "health=unhealthy" --format "table {{.Names}}\t{{.Status}}"

echo "=== Скрипт завершен ==="

exit 0

Вывод

Автоматизация разработки в Laravel — не просто модный тренд, а способ сделать вашу команду эффективнее, а проект — надежнее.

Основные принципы:

  • использование Docker Compose для стандартизированного и устойчивого окружения;
  • автоматическое форматирование кода (Pint) для единого стиля;
  • статический анализ (PHPStan + Larastan) для раннего обнаружения ошибок;
  • Git Hooks и скрипты, проверяющие файлы, тесты и работоспособность окружения.

Если вы внедрите эти практики, вы:

  • уменьшите время на исправление ошибок;
  • сделаете код более однородным и понятным;
  • минимизируете риск регрессий;
  • ускорите выпуск нового функционала.

Автоматизируйте рутинные задачи — и команда сможет сфокусироваться на настоящей ценности: создании функционала и развитии продукта.

7