Ответы пользователя по тегу Docker
  • Надо ли ставить на саму машину или можно в Docker?

    @MadridianFox
    Web-программист, многостаночник
    Важно понимать, что докер демон - это сервер, и он работает по сети, т.е. может быть доступен с другой машины или из контейнера.
    Самому дженкинсу докер не нужен (если не используется docker plugin для динамисеского создания агентов в контейнерах). Докер нужен агенту, потому что скорее всего вы хотите в итоге собрать докер образ.
    Однако, и агенту сам докер не нужен, нужен только клиент докера, а докер-демон может быть в другом месте.
    Кроме того, использовать мастер-ноду дженкинса это моветон. Это может помешать работе дженкинса. Лучше выделять отдельных агентов.
    В вашем случае нужно сделать следующее: собрать докер образ агента, в котором помимо самого агента будет докер(клиент) и необходимые вам инструменты.
    Далее запускаете этот образ с монтирования в него сокета докера, тогда докер-клиент внутри контейнера будет работать с докер-демоном на хосте.
    Ну и далее подключаете этот агент к дженкинсу. Сам дженкинс тут может быть вообще без дополнительных инструментов, без докера и даже на другой машине, хотя проще его поднять тут же в докере.
    Это не самая безопасная схема, есть недостатки.

    Другой вариант - собрать образ можно через podman. Это "докер" без демона. Его легче запустить в контейнере. Опять же его надо установить в образ агента.

    Ну или полноценный dind, да. Опять же в агенте.

    Если не хотите а отдельный агент, то да, вам нужно сделать всё это с образом дженкинса и использовать мастер-ноду.
    Ответ написан
    3 комментария
  • Как запустить php и nginx в одном контейнере?

    @MadridianFox
    Web-программист, многостаночник
    1) Запуск нескольких процессов в одном контейнере противоречит концепции докера. Докер сделан так, чтобы запускать один процесс (не считая дочерних процессов)

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

    Проще всего с загружаемыми файлами. Они в любом случае не должны храниться в контейнере и скорее всего это будет volume, который монтируется в оба контейнера.
    Взаимодействие между контейнерами по сети тоже штука не сложная, но зависит от способа запуска контейнера.
    Если контейнеры запущены через docker run в одной сети (поведение по умолчанию), то они видят друг друга по сети и могут использовать имя контейнера как dns имя.
    Если два контейнера запущены в рамках одного docker-compose.yml файла (это ещё называется docker compose project), то они тоже друг друга видят, но уже не по имени контейнера, а по имени сервиса (ключ под которым контейнер указан в секции services).
    Если приложение запускается в kubernetes, то там по умолчанию все контейнера pod'a имеют общий локалхост и могут обращаться к друг другу через 127.0.0.1.

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

    Важно: nginx работает с dns в обход стандартных инструментов операционной системы. Если вы используете в директивах proxy_pass, fastcgi_pass доменное имя, а не ip адрес, вам нужно дополнительно указать в конфиге директиву resolver <dns-ip>;, где в качестве нужно указать ip адрес dns сервера.
    Для докера это обычно 127.0.0.11, для кубера это адрес внутреннего dns сервера.

    Раздавать статику можно по разному. Два концептуально разных способа:
    - собрать образ nginx в котором есть статика, тут можно либо наследовать образ как сделали это вы, либо копировать статику в чистый образ nginx, что несколько чище и красивее
    - убрать статику из образа вообще, выделив её в volume или cdn, но тут придётся при отгрузке сервиса актуализировать статику во внешнем хранилище

    2) если очень хочется запустить несколько процессов в контейнере, то нужно запустить один процесс, который запустит остальные. Есть такие программы - менеджеры процессов. Это может быть supervosord, pm2, runit и т.п.
    Это такая программа, основной задачей которой является запуск других программ. Обычно у неё есть свой файл конфигурации, в котором вы описываете какие программы запустить и как это сделать.
    Ещё раз повторю - докер придуман не для этого. Не стоит делать этот приём основным при работе с докером.
    Это костыль. Он иногда нужен, но очень редко.

    3) То что nginx отдаёт код index.php, это проблема не настройки контейнеров, а конфигурации nginx. Если бы проблема была только в контейнерах, то вы бы получили не код скрипта, а 502.
    Первое что бросается в глаза в вашем конфиге - это регулярка в локейшене для обработки php скриптов.
    Попробуйте сделать как здесь.
    Ответ написан
    Комментировать
  • Как максимально ограничить права приложения в контейнере?

    @MadridianFox
    Web-программист, многостаночник
    Попробуйте использовать distorless образ - в нем нет ничего кроме рантайма необходимого вам ЯП. Этот вариант более универсальный.

    Другой вариант - использовать AppArmor. Здесь уже образ не совсем самодостаточный и надо ещё запустить контейнер с особыми флагами. Зато получается именно то что вам нужно - явный запрет на конкретные действия.
    Ответ написан
    Комментировать
  • Как сделать так, что бы Jenkis (в docker) запускал jenkins-agent (в docker)?

    @MadridianFox
    Web-программист, многостаночник
    Есть плагин Docker plugin. Он добавляет в дженкинс cloud типа docker. Cloud - это как раз способ запускать и останавливать агенты по требованию.

    При настройке клауда вам потребуется указать адрес докер-демона. Это может быть как tcp host:port, так и unix socket, если вы примонтировали его в контейнер дженкинса.

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

    Далее уже можно в пайплайне как напрямую через bash вызывать docker run/build, так и с помощью плагина Docker pipeline plugin
    Ответ написан
    Комментировать
  • Почему возникает ошибка?

    @MadridianFox
    Web-программист, многостаночник
    Как уже было отмечено в комментарии ку вопросу, этот пакет использует установленный в системе dig.
    В контейнере dig не установлен.
    Добавьте установку соответствующего пакета в Dockerfile и код будет работать и внутри контейнера.
    Ответ написан
    Комментировать
  • Как организовать связь между контейнерами?

    @MadridianFox
    Web-программист, многостаночник
    Если контейнеры запущены через docker run без указания сети, то они уже в одной сети и могут обращаться друг к другу используя имя контейнера в качестве имени хоста.

    Если контейнеры запускаются через docker-compose, то, по умолчанию, на каждый docker-compose.yml файл создаётся отдельная сеть. Это надо учитывать если сервисы запускаются через разные файлы. В этом случае сеть стоит создать вручную и прописать её использование во всех docker-compose.yml файлах.

    При запуске через docker-compose в качестве имени хоста контейнера используется не имя контейнера, а имя сервиса.

    В обоих случаях имя хоста можно переопределить через опцию hostname. В обоих случаях порты пробрасывать не надо.
    Ответ написан
    Комментировать
  • Как ограничить доступ к порту на докер контейнере?

    @MadridianFox
    Web-программист, многостаночник
    Чтобы не было доступа к контейнеру можно изначально его не открывать.
    Например не публиковать порт, если это приложение нужно другому контейнеру. Или публиковать порт на локалхост, а не на все интерфейсы.
    Ответ написан
    Комментировать
  • Как автоматически выдавать регион и id?

    @MadridianFox
    Web-программист, многостаночник
    Кубернетис нужен как раз для того чтобы приложения не знали ничего о машинах. Это платформа, которая скрывает детали реализации и даёт вам абстрактные рычаги управления.
    Если вам важно запускать приложение на особенных машинах, то надо пометить машины тэгом и настроить правила выбора машины через affinity/tolerations/nodeSelector.
    Например так можно настроить чтобы приложение запускалось только на машинах с gpu, или только на машинах в конкретном ДЦ.
    Здесь важно что вы не выясняете подходит ли вам текущая машина, а требуете чтобы приложение было запущено на подходящей.

    Есть, однако, и возможность передать в под информацию о нем самом в виде env переменных. Это называется downward api - при объявлении env переменной в манифесте пода можно указать что значением будет характеристика самого пода, например значение указанного лейбла, название неймспейса, или, как вариант, название ноды, на которой запущен под.
    Ответ написан
    Комментировать
  • Почему при старте docker контейнера sh скрипт запускается как node приложение?

    @MadridianFox
    Web-программист, многостаночник
    Скорее всего в базовом образе, который вы используете, настроен ENTRYPOINT, который превращает вашe src/start.sh в node src/start.sh или типа того.

    Посмотрите что именно прописано в ENTRYPOIN и подстройтесь или замените его.
    Ответ написан
  • Как сделать readinessProbe по тексту файла?

    @MadridianFox
    Web-программист, многостаночник
    Как уже написали в соседнем ответе вы можете обойтись одним только grep, однако ваша ошибка в другом.
    Во-первых, вы используете возможности shell, там где его нет. Пайп это специальная команда, которая есть в sh и bash. А хелсчек exec вызывает программы напрямую.
    Во-вторых, command это массив аргументов запуска. Каждая опция, каждый аргумент должен быть отдельным элементом массива, а вы просто дописали всё во второй элемент и оно распознаётся как один большой аргумент cat.

    Делайте греп и помещайте каждую опцию в отдельный элемент списка.
    Ответ написан
    Комментировать
  • Как отдавать docker container с сервера по адресу домена?

    @MadridianFox
    Web-программист, многостаночник
    Домен привязывается не к контейнеру, а к ip адресу.
    Вы не уточнили где именно поднята эта виртуальная машина и с какой целью.

    Если у вас на компьютере для личного использования, то проще всего использовать nip.io или прописать соотвествие домена и ip адреса виртуальной машины в файле hosts.

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

    UPD:

    чтобы по разным доменам открывались разные веб-приложения, вам необходим http прокси, который на основании домена, указанного в http запросе, будет проксировать этот запрос на тот или иной внутренний адрес.
    Обычно для этого устанавливают nginx, который сам слушает 80 и 443 порты.
    Все домены настраивают так, чтобы вели на адрес этого сервера.
    В конфиге nginx описывают какое приложение должно отвечать по определённому домену, примерно вот так:

    server {
        listen 80;
        server_name site-1.domain.com;
        location / {
            proxy_pass http://127.0.0.1:27073;
        }
    }
    server {
        listen 80;
        server_name site-2.domain.com;
        location / {
            proxy_pass http://127.0.0.1:12345;
        }
    }
    Ответ написан
    8 комментариев
  • Как выполнить http-запрос между двумя сайтами в laradock?

    @MadridianFox
    Web-программист, многостаночник
    Конкретно про ларадок не скажу, но объясню как оно вообще работает.

    Когда контейнеры запускаются в одной сети, они доступны друг другу по доменам, которые равны названию контейнера. При запуске через docker-compose немного не так. Контейнеры видят друг друга по именам сервисов.
    Т.е. если у вас вот такой docker-compose.yml
    services:
       front:
          image: ....
       back:
           image: ....

    то фронт сможет обратиться к бэку по домену back, примерно вот так:
    file_get_contents("http://back:8080/path/to/file.txt");

    Ещё, если вы хотите чтобы сервисы обращались друг к другу по публичным доменам, а не по внутренним, можете задать в docker-compose.yml у контейнеров hostname.
    но в docker-compose.yml у контейнера можно задать его hostname,
    вот так:
    services:
       front:
          hostname: site1.ru
          image: ....
       back:
           hostname: site2.ru
           image: ....
    Ответ написан
    Комментировать
  • Как решить проблему nginx при сборке docker-compose?

    @MadridianFox
    Web-программист, многостаночник
    Попробуйте использовать директиву upstream. Она более лояльна к отсутствию целевого хоста на момент страта nginx.
    Ответ написан
    Комментировать
  • Нужен совет: корректна ли связка Nginx - Docker - Nginx (proxy)?

    @MadridianFox
    Web-программист, многостаночник
    В этом нет ничего криминального. Если вам надо именно так - делайте. Если видите способ упростить систему - упрощайте.
    Главное не забыть прокинуть реальный ip и схему в заголовке.

    Кстати, k8s например примерно так и работает. Там 80,443 порт слушает т.н. ингрес - обычно тот же nginx, конфиг которого задаётся через yml файл. И вот он принимает все запросы и в зависимости от настроек проксирует их на бэкэнды, в том числе и на внутренние nginx'ы.
    Ответ написан
    Комментировать
  • Как подружить Windows 10 + Docker + PhpStorm + Xdebug?

    @MadridianFox
    Web-программист, многостаночник
    Я для себя определил универсальный подход для отладки в любом сетевом окружении.
    В простейшем случае, когда разработчик один, а сервер за NAT, надо на сервер прокинуть порт через ssh.
    ssh user@host -R 9000 localhost:9000
    При этом в php.ini xdebug надо настроить чтобы он коннектился на localhost:9000.

    Когда разработчиков много, я использую модифицированный dbgp прокси.
    https://github.com/MadridianFox/php-xdebug-proxy
    Если он стоит на том же сервере что и php, настройки xdebug те же. Прокси слушает 9000 порт. Каждый разработчик выбирает себе уникальный порт и прокидывает его по ssh на сервер. Так же надо обратно прокинуть 9001 порт чтобы зарегистрировать свой idekey в прокси.
    ssh user@host -R 9002 localhost:9002 -L 9001 localhost:9001

    И самое главное - при регистрации своего idekey через шторм в поле idekey надо написать myidekey:9002
    В этом же окне порт прокси - 9001, хост прокси - localhost.

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

    В браузере, не важно, используете вы расширение или прописываете XDEBUG_SESSION_START, надо указать myidekey без порта!

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

    Если разработчиков больше одного - выделяете контейнер с ssh + dbgp прокси и каждый разработчик прокидывает туда свой порт.
    Ответ написан
    Комментировать
  • Как вы используете docker при разработке и поставке?

    @MadridianFox
    Web-программист, многостаночник
    Можно.
    Копирование кода в контейнер используется при деплое на боевые сервера, а во время разработки обычно пробрасывается volume.
    Ответ написан
    8 комментариев
  • Как правильно отключить синхронизацию каталога в Docker?

    @MadridianFox
    Web-программист, многостаночник
    Не знаю точно, но возможно в Symfony можно как-то изменить расположение папки var. Тогда вы сможете вынести её из volume и она будет внутри контейнера. Хотя там логи... логи удобно иметь снаружи.
    Настраивать volume так чтобы часть его была... не volume.. это как-то противоестественно. Думаю это невозможно.
    И вообще. Если это прод, то нужно при каждом релизе пересобирать образ так, чтобы наружу торчали только данные, а код был частью образа.
    Если это dev, то в чём вообще проблема? Пусть себе тормозит. Кстати, если это dev и вы работаете под windows и docker крутится в виртуалке, то причина тормозов может быть не в volume, а в расшаренно папке виртуалки.
    Ответ написан
  • Как правильно запустить сервис внутри docker контейнера?

    @MadridianFox
    Web-программист, многостаночник
    В runserver выполняется команда
    "${YT_DIST}/bin/youtrack.sh" start &
    Амперсанд в конце указывает на то что это надо запустить и отправить в бэкграунд.
    При этом тот факт что в /bin/youtrack.sh передаётся аргумент start говорит о том что это ещё один стартер. Надо посмотреть на его код.
    Ответ написан
    6 комментариев
  • Простой вопрос по Docker-у?

    @MadridianFox
    Web-программист, многостаночник
    Сам по себе Docker работает под Linux (есть какие-то мутки с запуском на нём вёнд, но я туда не лезу, религия не позволяет).
    Под Windows доккер запускается в виртуалке. Раньше для этого использовался Docker Toolbox, который работает с Virtualbox, ну и с другими гипервизорами, если настроите. Сейчас это считается legacy, хоть его и можно скачать и всё работает.
    Docker for Windows - актуальный на данный момент способ запуска контейнеров, работает только в Windows 10 Pro. И не просто так он работает только там, ведь ему нужен HyperV, который, ой как неожиданно - гипервизор, в котором запускается такой же Linux как и в Docker Toolbox.

    Я пользуюсь Docker Toolbox. Работает нормально. Один только нюанс - проброс папок. Хотите делать volume который подтягиваться с винды - убедитесь что папка винды расшарена в виртуалку, и монтируя volume в контейнер указывайте путь до папки в виртуалке. Естественно, такой двойной проброс влияет на производительность, но мы же не прод тут хостить собрались, для редактирования кода норм.

    По поводу статей вот тут есть чутка инфы для начала. Рядом же есть и пример.
    Ответ написан
    3 комментария
  • Как использовать docker и gulp?

    @MadridianFox
    Web-программист, многостаночник
    Как-то вопрос про docker, но до последнего момента не понятно зачем вам docker.
    Конечно gulp вы используете только на этапе разработки, он у вас должен стоять локально, так чтобы phpstorm его видел. Если собираете контейнер в продакшен - то вы должны просто взять весь результирующий код, скопировать его в контейнер и запускать его. Если в контейнере запускается окружение для разработки - то прокидываете локальную папку в контейнер. Не понимаю как вам вообще пришло в голову засовывать гульп в контейнер)
    Ответ написан
    2 комментария