Я ищу невозможное, потому что возможное исключат другие.
Местоположение
Россия, Воронежская обл., Воронеж

Наибольший вклад в теги

Все теги (5)

Лучшие ответы пользователя

Все ответы (5)
  • Есть ли какие-то best practices как организовывать файлы веб-проекта с докером?

    Уж не так все и просто, комрад ;)

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

    Итого, у вас в группе проектов на GitLab (или в организации на GitHub) должно выйти примерно следующее:

    /project-group (organization):
        /api - сюда можно вынести api вашего проекта.
        /desktop - здесь ваш web-проект для desktop на php, например.
        /mobile - здесь ваш web-проект для мобильной версии сайта, на той-же node.js.
        /admin - здесь ваша админка.
        /infrastructure - ну, или назовите проще, "server". Здесь ваши Dockerfile, docker-compose, ci/cd скрипты и т.п.


    Чтобы моч варировать вашу инфраструктуру в зависимости от окружения, вы должны разделить репозиторий инфраструктуры на отдельные сервисы. Например, не все сервисы проекта должны запускаться в test окружении или на сервере тестовых веток на поддоменах, когда вы делаете домены вида "feature-1.test.project.com", чтобы ваши тестировщики могли тестировать фичи параллельно и независимо друг от друга. Так же, на dev и/или test окружениях может потребоваться сделать сервисы-заглушки на внешние api которые вы используете. Ну, например, на сервисы онлайн оплаты товаров на вашем сайте, которые будут отвечать всегда "OK" или не "OK".

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

    Таким образом, в репозитории infrastructure должно получиться примерно следующее:

    /infrastructure
       /api
           service.yml
           build.yml
           deploy.yml
       /mobile
           service.yml
           build.yml
           deploy.yml
       /desktop
           service.yml
           build.yml
           deploy.yml
       /admin
           service.yml
           build.yml
           deploy.yml
       /mysql
           mysql.cnf
           service.yml
       /redis
           redis.conf
           service.yml
       /php-fpm
           Dockerfile
           www-conf
           php.ini
           service.yml
       /nginx
           nginx.conf
           /prod
                site.conf
           /test
                site.conf
           /dev
                site.conf
       /cron
           Dockerfile
           crontab
           service.yml
    mobile-dev.sh
    desktop-dev.sh
    prod.sh
    test.sh


    В этих самых *.sh файлах, что указаны выше, вы производите запуск нужного состава сервисов. К примеру, разработчику мобильной версии на react не обязательно покупать мощный ПК, чтобы на его машине запускать вообще весь проект, с mysql, redis, admin и другими сервисами. Вам будет достаточно собрать образ мобильного приложения, и написать в mobile-dev.sh примерно следующее:

    docker-compose -f mobile/service.yml pull;
    docker-compose -f mobile/service.yml down;
    docker-compose -f mobile/service.yml up --detach;


    Ну а в mobile/service.yml может быть что-то следующее:

    version: "3.7"
    
    services:
      mobile:
        image: keymetrics/pm2:10-alpine
        environment:
          APP_ENV: ${APP_ENV}
          APP_LANG: ${APP_LANG}
          API_URL: ${API_URL}
          BASIC_TOKEN: ${BASIC_TOKEN}
        working_dir: /app
        command: pm2-runtime start config.js --env $APP_ENV
        volumes:
          - /etc/timezone:/etc/timezone:ro
          - /etc/localtime:/etc/localtime:ro
          - ${APP_DIR}:/app
        restart: always
        container_name: mobile


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

    Ваш сайт - так же, должен запускаться отдельным service.yml файлом. Service.yml - можно поменять на docker-compose.yml в директории каждого сервиса, но, service здесь смотрится красивее.

    Если требуется поднять все сервисы, необходимо передать последовательно все service.yml файлы через -f флаг вашему docker-compose. Это будет громоздкая команда, поэтому и делаются отдельные *.sh файлы для запуска.

    Требуется понимать, что не следует хранить Dockerfile в репозитории каждого проекта, если наличие образа потребуется для этого проекта. Не каждый разработчик умеет делать Dockerfile и, например, устанавилвать расширения для PHP в рамках этих Dockerfile. Делегировав ответственность по сборке Dockerfile разработчикам проекта, вы рискуете получить неработающий сервис. Лучшее место для Dockerfile - в нашем примере, это репозиторий infrastructure, находящийся в распоряжении ваших DevOps-инженеров.

    Та же история и с описанием build-процессов и процессов CI/CD. Не следует доаверять разработчику сборку его приложения в рамках целой огромной инфраструктуры проекта. Для этого в примере репозитория infrastructure - есть файлы build.yml/deploy.yml, в которых описана сборка и доставка сервисов. Любые CI/CD средства могут подключать фрагменты pipeline с внешних репозиториев, поэтому, когда у вас возникнет потребность сделать автобилд и автодеплой - проблем не будет, вы ведь уже учли все подводные камни совместной работы специалистов в вашей компании.

    Прошу учесть следующее.

    Выше описано, как правильно реализовать ваш проект на docker + docker-compose. Здесь не учтено наличие swarm-mode или kubernetes, тем не менее, данную структуру будет гораздо проще использовать в режиме swarm или c использованием kubernetes.

    ЗЫ. Конечно, есть и другие рабочие практики на эту тему ;) Эта нравится мне больше всего, и работает универсальней остальных.
    Ответ написан
    3 комментария
  • Как организовывывать структуру каталогов внутри docker-контейнера "правильно"?

    Уж не знаю, поможет ли ответ вашему холивару с коллегами.

    Любая best practice в первую очередь опирается на строгое соблюдение стандартов в той области, о которой идет речь.

    Для Linux - есть стандарт FHS (Filesystem Hierarchy Standard), который описывает что, где, куда. Не соблюдать этот стандарт - можно, но нужно ли? Тем более, упомянутый образ Tomcat четко соответствует этому стандарту.

    Я, например, заменил бы /app на /jaba-code. Ну а почему нет то? Ведь мы можем :)
    Ответ написан
    Комментировать
  • Почему в докере долго импортируется дамп базы?

    Вообще, docker дает немного специфичную нагрузку на хост. Я имею ввиду, что без docker большинство процессов являются предками своих чилдренов, в случае же docker - те самые предки есть тоже дети процессов, таких как containerd.

    При этом ваша ОС - не совсем понимает, что происходит. Раньше (без docker) пользователь запускал демонов, каждый из которых был чадом от init.d процесса, а сейчас - пользователь порешил запустить некоторую странную службу (типа /usr/bin/containerd) и начал активно ветвить с ее помощью детей на детей, тех детей еще на детей :)

    "Так как же мне распределять нагрузку, генерируемую со стороны всего этого детского сада в сторону ваших винчестеров, уважаемый пользователь?" - спросила ваша ОС.

    Подскажем ей. И подскажем примерно следующее: "Уважаемая ОС! Распределяй, пожалуйста, ресурсы винчестеров (особенно SSD) по принципу "кто первый встал, того и тапки!".

    Подсказать довольно просто:

    sudo nano /etc/default/grub

    Указываем в параметре GRUB_CMD_LINE_LINUX (а можно и через пробел в GRUB_CMDLINE_LINUX_DEFAULT) следующее:

    GRUB_CMD_LINE_LINUX="elevator=noop transparent_hugepage=never"


    Сохраняем файл. Записываем изменения в загрузчике:

    sudo update-grub

    Перезагружаем хост.

    Собственно elevator=noop - устанавливает noop в качестве I/O scheduler ядра по умолчанию. Noop - формирует весь стек комманд в сторону вашего HDD в виде FIFO-очереди, которая работает тем самым нужным нам способом - "кто первый встал, того и тапки". Прирост по OLTP операциям в БД заметите тут же.

    transparent_hugepage=never - можете и не ставить, данный параметр выключает штатный механизм THP, который на облачных хостингах формирует в целом бОльшую нагрузку на хост, чем хотелось бы видеть. Сильно на запись в БД он влиять не будет, если нет мощных нагрузок. Если же нагрузка крутая, есть смысл выключать данный механизм.

    "А что же за гадость такая этот ваш docker? Что же мне - теперь каждую виртуалку конфигурировать при создании вот в таких интимных местах?" - спросите вы.

    Отвечу.

    Linux - бесплатная ОС для самого широкого спектра задач. Она не windows, она не будет хардкодить за вас все параметры ядра, которые могут отличаться в рамках этих самых задач, решаемых на вашем хосте. А потом - колосально глючить без вариантов. Linux - ставится даже на стиральные машины, холодильники, и черт знает куда еще. Ваша задача - подсказать ОС, что вы делаете. ОС - не подведет. В свою очередь - разработчики служб dockerd и containerd не могут нести ответственность за поведение их продукта на хостах, работающих на коробочных настройках. Docker - дает вам экосистему, которая позволяет решать очень крутые задачи быстрее, чем это сделает матерый старообрядский сис-админ руками в консоли.

    Можно документировать нужные настройки хоста в confluence, написать подробные инструкции по шагам - что нужно сделать с ОС после установки, чтобы на ней все летало. Удобно, советую. Можно обратить внимание на продукт Teraform, который может помочь вам автоматизировать создание хостов в промышленных количествах с заданными параметрами.

    Как-то так. Пробуйте :)
    Ответ написан
    Комментировать