Задать вопрос
Ответы пользователя по тегу Docker
  • Как организовать локальные домены при разработке?

    @MadridianFox
    Web-программист, многостаночник
    Я обычно поднимаю ещё один контейнер с nginx, который слушает порты 80 и 443 на хосте и раскидывает запросы в разные контейнеры по доменам или по локейшенам.
    Чтобы не прописывать вручную в hosts домены, когда сервисов много, использую nip.io
    Такие же домены назначаю как hostname контейнерам, для единообразия.
    А чтобы не писать однотипные конфиги nginx - https://hub.docker.com/r/jwilder/nginx-proxy/

    Для управления самоподписанными сертификатами для разработки есть https://github.com/FiloSottile/mkcert
    Ответ написан
    Комментировать
  • Как узнать реальный IP адрес клиента в подсети Docker?

    @MadridianFox
    Web-программист, многостаночник
    Нужно чтобы "снаружи" относительно сети докера был L7 прокси, который видит ip клиента, и который добавит этот ip в заголовки запроса.
    Ответ написан
    Комментировать
  • Надо ли ставить на саму машину или можно в 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 комментариев