У меня есть PHP-приложение, работающее в Docker, и большинство запросов из контейнера завершаются с ошибкой таймаута. Это касается, например, запросов через Symfony HTTP Client и команды composer install. Похоже, что контейнер не может выполнять HTTPS-запросы – по крайней мере, в большинстве случаев. Запросы к Google, Facebook и Yandex обрабатываются нормально, что создает впечатление, что все в порядке. Единственный способ, с помощью которого я смог заставить эти запросы работать, – это использование режима network_mode: host, но я не хочу использовать этот режим из соображений безопасности. Кроме того, при этом PHP перестает получать запросы от Nginx. Что ещё интереснее, тот же контейнер без проблем выполняет эти запросы локально, что заставляет меня думать, что проблема может быть связана с фаерволом. При настройке я следовал рекомендациям из этого руководства <a href="https://github.com/chaifeng/ufw-docker?tab=readme-ov-file#how-to-do" rel="nofollow">ufw-docker</a>. <b>Кратко:</b> У меня есть PHP и Nginx в Docker, они могут успешно взаимодействовать друг с другом, и я могу получить ответ от приложения, но исходящие HTTPS-соединения блокируются (по крайней мере, те, которые мне необходимы). <b>Большинство запросов через curl завершаются следующим образом:</b> <pre><code>$ curl https://raw.githubusercontent.com/ -v -4 * Host raw.githubusercontent.com:443 was resolved. * IPv6: (none) * IPv4: 185.199.109.133, 185.199.108.133, 185.199.111.133, 185.199.110.133 * Trying 185.199.109.133:443... * ALPN: curl offers h2,http/1.1 * TLSv1.3 (OUT), TLS handshake, Client hello (1): * CAfile: /etc/ssl/cert.pem * CApath: none * Connection timed out after 300004 milliseconds * closing connection #0 curl: (28) </code></pre>
Проблема с тайм-аутами при выполнении HTTPS-запросов из контейнера Docker может быть связана с несколькими факторами. Рассмотрим основные из них и способы их устранения: 1. **Настройки DNS**: - Убедитесь, что контейнер имеет доступ к DNS-серверам. Проверьте, что в контейнере правильно настроены адреса DNS. Вы можете попробовать добавить запись в `docker-compose.yml`: ```yaml dns: - 8.8.8.8 - 8.8.4.4 ``` - Также проверьте, что файлы `/etc/resolv.conf` внутри контейнера содержат корректные адреса DNS-серверов. 2. **Сетевые настройки Docker**: - Попробуйте проверить, нормально ли работает сеть Docker. Для этого выполните команду внутри контейнера: ```bash ping google.com ``` - Если пинг проходит, это означает, что контейнер в состоянии отправлять пакеты. 3. **Firewall**: - Поскольку вы упомянули использование `ufw`, возможная проблема может заключаться в настройках фаервола, блокирующих исходящие соединения из контейнеров. Убедитесь, что политика фаервола позволяет исходящие соединения. - Вы можете временно отключить `ufw` (для тестирования) с помощью команды: ```bash sudo ufw disable ``` 4. **Обработка IP-адресов и маршрутизация**: - Проверьте, как настроены маршруты в контейнере: выполните команду `ip route` и убедитесь, что маршруты настроены корректно. - Если вы используете пользовательскую сеть для Docker, убедитесь, что она настроена правильно и контейнер может выходить в интернет. 5. **TLS и CA сертификаты**: - Убедитесь, что в контейнере установлены необходимые корневые сертификаты для TLS. Это можно сделать, установив пакет `ca-certificates`: ```bash apt-get update && apt-get install -y ca-certificates ``` 6. **Использование других протоколов**: - Попробуйте протестировать другие HTTPS-ресурсы, чтобы проверить, работает ли проблема с конкретными адресами или с HTTPS в целом. Вы можете попробовать выполнить запрос с помощью `curl` к другим адресам и портам. 7. **Существующие ограничения вашего хост-системы**: - Если ваш хост использует дополнительные ограничения для Docker (например, SELinux или AppArmor), убедитесь, что они не блокируют вашу сетевую активность. Если ни одно из приведенных решений не помогло, вы можете попытаться запустить контейнер с включенным интерактивным терминалом и провести тесты по сети и DNS в ручном режиме для дальнейшего устранения неполадок.
Мне помогла установкаDOCKER_OPTS="--mtu 1400"
в/etc/default/docker
. Я не понимаю, почему это решило проблему, но, может, кому-то также будет полезно.
Либо можно отредактировать docker-compose.yml
version: '3.8' services: php: image: php:8.3-fpm container_name: php_app volumes: - .:/var/www/html ports: - "9000:9000" networks: - my_network networks: my_network: driver: bridge driver_opts: com.docker.network.driver.mtu: 1400