• Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0
    Я вспомнил, что был на этой странице, когда изучал Git и выдумывал нашу предыдущую «систему». Видимо, тогда мне этот подход понравился, но со старым GitLab и Jenkins не получилось сделать удобный и понятный workflow, а тут — оно как-то само вспомнилось и я возомнил, что я это сам придумал =) Я стремился сделать чтобы было похоже на GitHub, где есть один общедоступный репозиторий и много contributors. В итоге так и получилось, но со своей спецификой: это всё таки не для open source проектов.
  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    +1
    А может быть вы напишете тут, на хабре, про контейнер-с-прокси, про docker-flow и docker swarm?
  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0

    Да, непонятно. Мой образ — это alpine + bash + openssh-client + git + настройка ssh и git. Практически такой же как docker:git только без докер =)

  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0

    Это работает как нужно. И я скопировал это из документации на docs.gitlab.com

  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0
    Я исходил из имеющихся у меня инструментов. Например, я не знаю как сделать новый домен, выделить свободный IP в подсети docker, и плюс ещё настроить «внешний» nginx чтобы тот проксировал HTTP-запрос в нужный внутренний ip:port. Наверное поэтому у меня так и получилось: операции с настройкой внешнего nginx — вручную, а всё остальное — автоматом. А про «локально» я не понял.
  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0

    Локально используется файл Dockerfile-dev — это "базовый образ" плюс включение расширения xdebug.


    Но, видимо, тут какое-то недопонимание есть. Локально весь код находится на хосте. Внутри контейнера код доступен в директории /srv. Плюс локально нужно вручную запускать phing после запуска docker-compose up


    На удалённом сервере создаётся новый образ. Это "базовый образ" плюс копирование кода в внутрь контейнера, также в папку /srv; плюс запускается composer install; плюс запускается phing (для вызова cache:warmup и assets:install).


    Таким образом "базовый образ" — это основа для всех окружений. От проекта к проекту основа может отличаться. Расширениями, например.


    "Базовый образ" для скелета приложения — дефолтный covex/php7.1-fpm:1.0. Для другого проекта — он может быть другим, и я его сначала подготовлю, а потом буду использовать также как дефолтный.

  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0

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


    До docker у нас был один репозиторий, доступный для всех разработчиков, на проект. Для деплоя на тестовый сайт проекта, мы используем ещё один "служебный и скрытый ото всех" репозиторий, в который jenkins заливает изменения после push в ветку задачи разработчика. Вобщем, у нас Система. И эта система ломается, когда кто-то из добрых и хороших побуждений решает сделать git push --force — приходится чистить и приводить репозитории к работоспособному виду.


    А иногда разработчики правят один и тот же файл в одном и том же месте! Тут опять приходится вмешиваться, потому что и тут система оказывается сломаной =) И хорошо ещё, что репозитории находятся внутри GitLab (он у нас какой-то там совсем старой версии), так что ветки master и production у нас защищены от изменений.


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


    Сейчас же у разработчика есть и свобода действий с историей коммитов с одной стороны, и строгие рамки в виде ветки origin/stable — все изменения должны идти строго после неё.

  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0

    Расширения php для образа на основе alpine очень долго устанавливаются. Для создания образа я использую репозиторий на gitlab.com — там сборка образа занимает 3-4 минуты. Локально у меня на ноуте это длится в разы дольше. Если очень часто запускать docker-compose down -v и затем docker-compose up -d то, можно весь день только этим и заниматься =)

  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0

    Весь процесс будет работать и без кэширования этой директории. Но с кэшированием через gitlab ci runner оно просто быстрее работает. Но, вообще, я согласен про возможность "нечаянно сломать".

  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0

    Если вдруг будет нужно установить новое расширение или ещё какое-нибудь ПО внутрь образа с php, я сделаю новый образ на основе Dockerfile для образа covex/php7.1-fpm:1.0 и буду использовать новый образ как "базовый" для проекта на всех стадиях.

  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0

    Таким образом можно закэшировать только директории внутри рабочей директории.


    В Dockerfile образа для php домашняя директория composer установлена в /composer/home. Кэш composer находится в /composer/home/cache. Эта директория находится вне рабочей директории, с которой может работать GitLab Runner.


    И поэтому я сначала формирую кэш composer, чтобы много раз запускать composer install или composer require.

  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0

    На этапе test базы данных не существует — там только php. БД появляется в docker-compose после этапа build.


    Основной репозиторий "скелета приложения" хранится у нас внутри GitLab. Репозиторий на GitHub — это его копия. И для репозитория на GitHub я дополнительно подключил travis-ci для тестирования "как система будет запускаться с нуля". Вот файл .travis.yml, и вот задача внутри travis.


    И вот в Travis CI тесты запускатся внутри docker-compose! Таким же самым образом можно сделать "тестирование-с-базой-данных" на этапе между build и deploy. Но это сейчас не реализовано, да.

  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0

    Это не инсталирование зависимостей, а заполнение кэша composer, чтобы этот кэш использовали следущие задачи. Кэш composer хранится в volume у gitlab-ci-runner и доступен для всех задач, которые запускаются этим runner-ом.


    Окружение на этапе test, когда работает phpunit, совпадает с тем, что в production — там один и тот же образ. Но в production (да и везде внутри контейнеров, запущенных через docker-compose) — есть база данных, а на этапе test, для phpunit этой БД ещё нет.


    Для юнит-тестов этой группы подключение БД не нужно, а юнит-тестов, использующих БД ещё и не существует. Наверное, эту задачу нужно будет сделать вместе с "интеграционными тестами". Например: (1) запускаем docker-compose внутри docker (2) проверяем запущены ли все контейнеры (3) наполняем БД данными для тестирования (4) запускаем тесты, использующие БД.

  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0

    На самом деле в скелете приложения задача deps:php-composer не особо и нужна. Она заполняет кэш composer, а использует этот кэш только задача test:phpunit. Задача test:phpunit запускает composer require phpunit/phpunit:* --dev что, также как и в deps, заполняет кэш composer. Я оставил deps в шаблоне "на всякий пожарный", чтобы в случае, когда параллельно с phpunit будут выполнятся какие-то другие задачи, — этот кэш не надо было наполнять в конкурентной борьбе компоузеров.


    И если останется только одна задача на этапе test, то deps и test можно будет объединить. А если появится третья, например, phpcs — то весь кэш нужно будет загружать в deps так, чтобы он был доступен и для phpunit и для phpcs, т.е. объединять не нужно. Пусть пока будут разъединёнными — а потом либо надо будет удалить deps, либо на "потенциальном" этапе qa что-нибудь появится такое, что будет полезным всем.

  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0
    А сейчас так и есть: на всех этапах в качастве основы уже используется один и тот же образ для php: covex/php7.1-fpm:1.0. См. в репозитории файлы: Dockerfile (для образа приложения для удалённых серверах), Dockerfile-dev (для контейнера в локальном окружении), .gitlab-ci.yml — описание задач в pipeline. Для «скелета приложения» образ — именно такой. А для реальных задач мой образ всё равно будет не очень безопасно использовать — нужно будет делать свой, копируя и изменяя Dockerfile моего образа для контейнера с php.
  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0
    Мы используем, но у нас это не автоматизировано: есть свой coding style, основанный на PSR-2, всем «рекомендуется» настраивать свою IDE так чтобы оно подсвечвало неправильно оформленный код. Ну и на этом всё, да и не прижилась у нас такая проверка.

    Проверку на coding style можно было бы запускать до этапа build и после этапа deps. Параллельно с phpunit, например, было бы самое оно. Ну и этап можно было бы переименовать: вместо test сделать qa, например. Вообще ещё много чего можно добавить в pipeline! Например, этапа lint нет. Ещё нужно проверять а запустятся ли контейнеры после сборки до того, как их выложим на удалённый сервер и как они будут работать (вот тут я не знаю каким инструментом можно воспользоваться, кстати). Может быть ещё что-нибудь.

    Ещё я не согласен с тем, что непрошедший проверку на coding style код, не может быть запушен на сервер! Если такую проверку и вводить, то этот код таки будет запушен, но результат работы не дойдёт до тестового сайта разработчика (не говоря уже про staging и production), что не позволит сдать результат работы. И если такая проверка (как и phpunit-тестирование, кстати) не позволяет выкладывать код на удалённый сервер, разработчик должен будет исправить недочёты, объединить коммиты и запушить --force свой код ещё раз.
  • Непрерывная интеграция/внедрение приложения Symfony с помощью docker-compose и GitLab CI
    0
    Исправил. Спасибо
  • ООП в JavaScript
    +1
    Вот моя реализация: habrahabr.ru/blogs/javascript/40909/ =)
  • Полный запуск сервиса Пробки на Картах Google
    0
    У нас в НН есть ещё один мост через Оку. Там пробка всегда =)
    Этот мост не отмечен на карте, соответственно, и пробка тоже не отображается.
  • Мой первый день с Jabra BT3030
    0
    Уже года 2 (а может и больше) пользую Jabra BT320s в связке с наушниками Sony MDR-NX2: гарнитура цепляется на шнурок на шею от наушников, а сами наушники ни за что не зацепляются. Очень удобно.

    // А цепочка, кстати, не от тамогочи, а от пробки в ванную =))
  • Где эта улица, где этот дом… Или как определить район, в котором находится предприятие
    0
    нарисовать карты районов для всей России осилит не каждый
    Они все уже нарисованы и храняться в wikimapia. Можно подключить слой от WikiMapia в Google Earth и сохранять полигоны в kml-файлы.

    Я такое безобразие делал для сервиса частных объявлений о недвижимости. Способ, может быть и не совсем прямой, но для Нижнего его таки можно осилить =)
  • Smarty против XSLT
    +1
    Обращение к переменной $_smarty_tpl->getVariable('thing')->value['color'] явно медленнее, чем $this->_tpl_vars['color']
  • Smarty против XSLT
    –2
    В третьей версии смарти всё, что не касается инклюдов медленнее чем во второй.
    Надо было придумать пример без дерева — чтобы статья более разоблачительной казалась =)
  • Smarty против XSLT
    0
    // блин, текст статьи поменялся =) коммент отменяется
  • Smarty против XSLT
    +1
    А если до вывода поставить ob_start(); а после вывода — ob_end_clean(); то результаты будут совсем другими =)

    php test-xslt.php
    — total: 29.31005859375
    php test-smarty.php
    — total: 713.7099609375
    php test-php.php
    — total: 18.787841796875

    Фактически получается, что в твоих тестах XSLT борется с функцией _smarty_include класса Smarty (если что — я не в курсе часто ли она используется на практике)

    ЗЫЖ Смарти — зло! =)
  • Дайте мне работать-2
    0
    > всегда с интересом брал на себя работу менджмента
    Согласен. Это интересно!
    Но всё упирается в рамки. Ваши термины «художник» и «таджик» — это описание границ возможного поведения: «Художник» делает что хочет, а «Таджик» то, что ему говорят. «Менеджер среднего звена» — это «СуперТаджик», он отличается от обычного тем, что он начальник. И всё )
  • Дайте мне работать-2
    0
    Личный опыт.
    Сейчас я уверен, что мне лучше либо работать «на дядю» на должности «художника» либо работать на себя. Но уж никак не быть «начальником под управлением дяди».
    (сейчас я уже давно не «начальник» =)
  • Дайте мне работать-2
    +1
    > Став начальником, это чувство остается.
    Став начальником художник перестаёт быть художником ) А чувство может притупиться до нуля.
  • Друзья, нужна помощь в тестировании
    +3
    > не имею технической возможности протестировать на *nix
    Виртуальная машина спасёт отца русской демократии )
  • Правильность скобочной структуры, prolog
    0
    А ещё этот код — не рабочий =( С [{}{}] он работает неверно. Вот новый, рекурсивный:
    1. var check = (function(close) {
    2.  var bracket = { }, ch, end;
    3.  for (i in close)
    4.   bracket[close[i]] = (function(i) {
    5.    return function(pos) {
    6.     if (ch[pos+1] == i)
    7.      return pos+2;
    8.     else if (bracket[ch[end = pos+1]])
    9.      while (end = bracket[ch[end]](end))
    10.       if (ch[end] == i)
    11.        return end + 1;
    12.     throw { };
    13.    }
    14.   })(i);
    15.  
    16.  return function(str) {
    17.   try {
    18.    var pos = 0;
    19.    while (pos < str.length)
    20.     pos = bracket[(ch = str)[pos]](pos);
    21.    return true;
    22.   }
    23.   catch (e) {
    24.    return false;
    25.   }
    26.  };
    27. })({ ')':'(', '>':'<', '}':'{', ']':'[' });
    28.  
    29. alert(check("[<>{}]")); // true
    30. alert(check("")); // true
    31. alert(check("[[[]]][][[]][()]{}[]")); // true
    32. alert(check("[[[)]]][][[]][()]{}[]")); // false
    33. alert(check("]")); // false
    * This source code was highlighted with Source Code Highlighter.
  • Правильность скобочной структуры, prolog
    0
    А ещё мой вариант быстрее в 4 раза.
  • Правильность скобочной структуры, prolog
    0
    Понятный алгоритм со стэком уже 1602 выложил =)
  • Правильность скобочной структуры, prolog
    0
    JavaScript:
    var check = (function(close) {
     var open = { };
     for (i in close)
      open[close[i]] = i;

     return function(str) {
      var first=0, begin = 0, end = 1, len = str.length;
      while (first < len) {
       if (close[str[end]] == str[begin]) {
        if (begin == first)
         begin = first = ++end;
        else
         begin--;
       }
       else if (open[str[end]])
        begin++;
       else
        return false;
       end++;
      }
      return true;
     };
    })({ ')':'(', '>':'<', '}':'{', ']':'[' });

    alert(check("[[[]]][][[]][()]{}[]")); // true
    alert(check("[[[)]]][][[]][()]{}[]")); // false

    * This source code was highlighted with Source Code Highlighter.
    Без стэка =)
  • Для тех, кто печатает быстрее, чем думает
    0
    На конференции UserExpiriense 2007 Maria Stone рассказывала о том как менялся внешний вид блока «Возможно вы имели ввиду», и об эффекте от каждого изменения: количество кликов на уточнённую фразу увеличивалось каждый раз то ли в 2 раза, то ли на порядок.

    Было бы интересно узнать эффект от и этого улучшения =)
  • Типы HTTP-запросов и философия REST
    0
    Это труЪ, если шифровать только UserID.
  • Типы HTTP-запросов и философия REST
    0
    А не обязательно хранить пароль в куках =) Закриптованный UserID в куках, который можно расшифровать на сервере, уже можно считать подтверждённой аутентификацией!
  • Типы HTTP-запросов и философия REST
    0
    «Нужно ли» и «подходит ли» — зависит задачи и от её реализации. Но я всё же считаю, что экономия серверных ресурсов должна перевесить все остальные аргументы и домыслы.

    > как это не аргумент? :)
    Скоро будет готов «прототип» подобной системы (правда, пока без кэширования =). И как только придумаю «описание для людей» — можно будет обсудить =)
  • Типы HTTP-запросов и философия REST
    0
    Ни о каких справочниках и прочей статике речь не идёт. Речь об обычных динамических html-страницах. Фактически в куках нужно будет хранить только информацию об авторизации + какие-то другие некритичные данные.

    ЗЫЖ Геморрой — не аргумент! =)
  • Типы HTTP-запросов и философия REST
    0
    > А смысл?
    Смысл в «кэшировании всего» даже для авторизированных пользователей!
    Если получится сделать такое кэширование, то серверное приложение требовало бы намного меньше ресурсов. Сервер даже мог бы отдавать 304 Not Modified — а это очень контрастирует с вашим «гонять кучу информации».
  • Типы HTTP-запросов и философия REST
    +1
    На highload++ Марко Кевац в своём докладе привёл очень хороший (и главное — работающий) пример RESTful авторизации: highload.ru/papers2008/7166.html