[英]Access host from within a docker container
我有一個 dockerized 應用程序,我使用以下 docker-compose.yml 來運行它:
version: '3.1'
services:
db:
image: mysql:5.7
ports:
- "3306:3306"
env_file:
- ./docker/db/.env
volumes:
- ./docker/db/data:/var/lib/mysql:rw
- ./docker/db/config:/etc/mysql/conf.d
command: mysqld --sql_mode="NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
php:
build: ./docker/php/7.4/
volumes:
- ./docker/php/app.ini:/usr/local/etc/php/conf.d/docker-php-ext-app.ini:ro
- ./docker/logs/app:/var/www/app/var/log:cached
- .:/var/www/app:cached
working_dir: /var/www/app
links:
- db
env_file:
- ./docker/php/.env
webserver:
image: nginx:1
depends_on:
- php
volumes:
- ./docker/webserver/app.conf:/etc/nginx/conf.d/default.conf:ro
- ./docker/logs/webserver/:/var/log/nginx:cached
- .:/var/www/app:ro
ports:
- "80:80"
我的機器上沒有運行 dockerized 的服務器,我可以通過localhost:3000
訪問它。 我希望我的php
服務能夠訪問它。
我發現有人建議在我的php
服務配置中添加以下內容:
extra_hosts:
- "host.docker.internal:host-gateway"
But when I add this, then docker-compose up -d
and try docker exec -ti php_1 curl http://localhost:3000
, I get curl: (7) Failed to connect to localhost port 3000 after 0 ms: Connection refused
. 當我嘗試curl http://host.docker.internal:3000
時,我遇到了同樣的錯誤。
我拼命嘗試將端口映射添加到php
容器:
ports:
- 3000:3000
但是當我啟動服務時,出現以下錯誤:
ERROR: for php_1 Cannot start service php: driver failed programming external connectivity on endpoint php_1 (9dacd567ee97b9a46699969f9704899b04ed0b61b32ff55c67c27cb6867b7cef): Error starting userland proxy: listen tcp4 0.0.0.0:3000: bind: address already in use
ERROR: for php Cannot start service php: driver failed programming external connectivity on endpoint php_1 (9dacd567ee97b9a46699969f9704899b04ed0b61b32ff55c67c27cb6867b7cef): Error starting userland proxy: listen tcp4 0.0.0.0:3000: bind: address already in use
這很明顯,因為我的服務器在3000
端口上運行。
我也嘗試添加
network_mode: host
但它失敗了,因為我已經有一個links
。 我收到以下錯誤:
Cannot create container for service php: conflicting options: host type networking can't be used with links.
我在 Ubuntu 21.10 上運行 docker v20.10.6。
任何幫助表示贊賞,在此先感謝!
確保您使用的 docker 版本支持 host.docker.internal。 如果您使用的是 linux 版本,則 20.10+ 支持。 對於其他系統,您可能應該查閱有關 docker-for-linux / 其他項目操作系統相關的 github 的文檔和一些問題。
在那之后...
確保 extra_hosts 是 php 服務的直接子節點:
php:
extra_hosts:
host.docker.internal: host-gateway
build: ./docker/php/7.4/
首先嘗試使用ping host.docker.internal
來檢查您的主機是否正確響應。
確保端口 3000 上的服務正常工作並且沒有防火牆問題。
請記住,從當前容器的角度來看, localhost
始終意味着本地 ip。 這意味着容器內的localhost
映射到本地容器 IP 而不是您的主機 IP。 這是發送 extra_hosts 部分的原因。
docker.host.internal 也不是您的主機環回接口。 如果您嘗試訪問的服務僅在 localhost 接口上偵聽,那么如果不使用 iptables / 防火牆做一些魔術,就沒有機會訪問它。
您可以檢查哪個服務正在偵聽哪個接口/ip 地址在您的主機上運行以下命令: netstat -tulpn
這應該返回類似於 output 的內容:
$ netstat -tulpn
(Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:39195 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 ::1:631 :::* LISTEN -
從 docker 容器中,我可以訪問在 0.0.0.0(所有接口)上偵聽的服務,但無法訪問 631 端口,因為它僅在 127.0.0.1 上
$ docker run --rm -it --add-host="host.docker.internal:host-gateway" busybox
/ # ping host.docker.internal
PING host.docker.internal (172.17.0.1): 56 data bytes
64 bytes from 172.17.0.1: seq=0 ttl=64 time=0.124 ms
64 bytes from 172.17.0.1: seq=1 ttl=64 time=0.060 ms
^C
--- host.docker.internal ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.060/0.092/0.124 ms
/ # telnet host.docker.internal 631
telnet: can't connect to remote host (172.17.0.1): Connection refused
/ # telnet host.docker.internal 22
Connected to host.docker.internal
SSH-2.0-OpenSSH_8.6
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.