例如,是否有一种方法将主机的端口发布到容器中(相当于 docker run -p 的反向操作)?
从 18.03 的文档中:
我想从容器连接到主机上的服务
主机具有不断变化的 IP 地址(如果您没有网络访问,则为无)。从 18.03 开始,我们建议使用特殊的 DNS 名称
host.docker.internal
连接,该名称解析为主机使用的内部 IP 地址。网关也可以通过
gateway.docker.internal
访问。
例如: 这是我在容器中使用的 MySQL 连接字符串,用于访问我的主机上的 MySQL 实例:
mysql://host.docker.internal:3306/my_awesome_database
关于如何以一致、易懂和可移植的方式完成这个任务,有几个长期的讨论。虽然没有完全解决方案,但我会在下面链接到这些讨论。
无论如何,您可以尝试使用 --add-host 选项将主机的 IP 地址添加到容器的 /etc/hosts 文件中。从那里,连接到所需端口的主机就非常简单了:
向容器的 hosts 文件添加条目
您可以使用一个或多个 --add-host 标志将其他主机添加到容器的 /etc/hosts 文件中。此示例为名为 docker 的主机添加了一个静态地址:
$ docker run --add-host=docker:10.180.0.1 --rm -it debian $$ ping docker PING docker (10.180.0.1): 48 data bytes 56 bytes from 10.180.0.1: icmp_seq=0 ttl=254 time=7.600 ms 56 bytes from 10.180.0.1: icmp_seq=1 ttl=254 time=30.705 ms ^C--- docker ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max/stddev = 7.600/19.152/30.705/11.553 ms
注意:有时您需要连接到Docker主机,这意味着获取主机的IP地址。您可以使用以下shell命令简化此过程:
$ alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print $2 }'" $ docker run --add-host=docker:$(hostip) --rm -it debian
文档:
https://docs.docker.com/engine/reference/commandline/run/
有关从容器访问主机的讨论:
从Docker 18.03起,请使用host.docker.internal。
Docker version 18.03.0-ce, build 0520e24
上无法工作。 - scythargon18.03.1-ce-mac65
上对我有效。 - cdignam从Docker 17.06版本开始,在Docker容器中可用一个特殊的仅限Mac的DNS名称,该名称能够解析为主机的IP地址。 它是:
docker.for.mac.localhost
相关文档请参见: https://docs.docker.com/docker-for-mac/networking/#httphttps-proxy-support
docker.for.mac.host.internal
可用。详见 https://docs.docker.com/docker-for-mac/release-notes/#docker-community-edition-17120-ce-mac46-2018-01-09-stable。 - Zangetsudocker.for.mac.localhost
works on 18.03.1-ce-mac65
- cdignam其他答案对我没有很好的帮助。我的容器无法使用host.docker.internal解析主机IP。有两种方法:
共享主机网络 --net=host:
docker run -it --net=host myimage
使用 Docker 的 IP 地址,通常为172.17.0.1。您可以通过调用 ifconfig 命令并获取 Docker 接口的 inet addr 来检查它。 user@ubuntu:~$ ifconfig
docker0 Link encap:Ethernet HWaddr 02:42:a4:a2:b2:f1
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::42:a4ff:fea2:b2f1/64 Scope:Link
一旦你获得了这个IP地址,你可以将它作为参数传递给docker run,然后再传递给应用程序,或者像我一样,通过卷将jdbc.properties的位置映射到主机上的目录中,这样你就可以在外部管理该文件。
一旦你获得了这个IP地址,你可以将它作为参数传递给docker run,然后再传递给应用程序,或者像我一样,通过卷将jdbc.properties的位置映射到主机上的目录中,这样你就可以在外部管理该文件。
docker run -it -v /host_dir/docker_jdbc_config:${jetty_base}/var/config myimage
注意:您的数据库可能不允许外部连接。对于postgresql,您需要编辑2个文件,如下所述这里和这里:
编辑postgresql.conf,使其监听所有地址。默认情况下,它将指向localhost。
listen_addresses = '*'
编辑pg_hba.conf文件以允许来自所有地址的连接。在最后一行添加:
host all all 0.0.0.0/0 md5
host all all 0.0.0.0/0 md5
重要提示:更新数据库访问的最后一步不建议在生产环境中使用,除非您确实知道自己在做什么。
仅适用于Linux
情况1:Mysqldb在本地主机上运行,而不是在Docker上
您可以将主机IP地址固定为连接,并连接到该IP地址,而不是localhost。
对于Linux dockerhost,它是固定的,即172.17.0.1。因此,请连接到172.17.0.1而不是localhost。
情况2:如果mysqldb也在Docker上运行,则最佳做法是使用Docker容器名称连接,而不是IP地址。
因此,docker-compose文件应如下所示
version: '3.8'
services:
mysqldb:
image: mysql:5.7
restart: unless-stopped
env_file: ./.env
environment:
- MYSQL_ROOT_PASSWORD=$MYSQLDB_ROOT_PASSWORD
- MYSQL_DATABASE=$MYSQLDB_DATABASE
ports:
- $MYSQLDB_LOCAL_PORT:$MYSQLDB_DOCKER_PORT
volumes:
- db:/var/lib/mysql
producer:
build: .
ports:
- '$LOCAL_PORT:$DOCKER_PORT'
depends_on:
- mysqlsb
volumes:
- ./:/usr/src/app
var mysql = require('mysql');
var con = mysql.createConnection({
host: mysqldb,
user: "yourusername",
password: "yourpassword"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});