初级 Docker 的问题,
我有一个运行模块化应用程序的开发环境,它使用Docker Compose运行3个容器:服务器、客户端、数据库。docker-compose.yml
看起来像这样:
#############################
# Server
#############################
server:
container_name: server
domainname: server.dev
hostname: server
build: ./server
working_dir: /app
ports:
- "3000:3000"
volumes:
- ./server:/app
links:
- database
#############################
# Client
#############################
client:
container_name: client
domainname: client.dev
hostname: client
image: php:5.6-apache
ports:
- "80:80"
volumes:
- ./client:/var/www/html
#############################
# Database
#############################
database:
container_name: database
domainname: database.dev
hostname: database
image: postgres:9.4
restart: always
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=root
- POSTGRES_DB=dbdev
- PG_TRUST_LOCALNET=true
ports:
- "5432:5432"
volumes:
- ./database/scripts:/docker-entrypoint-initdb.d # init scripts
您可以看到,我为每台计算机分配了一个. dev域名,这可以很好地从另一台计算机(Docker内部网络)查看一台计算机,例如,我在这里从client.dev
的CLI ping server.dev
:
root@client:/var/www/html# ping server.dev
PING server.dev (127.0.53.53): 56 data bytes
64 bytes from 127.0.53.53: icmp_seq=0 ttl=64 time=0.036 ms
- 这在内部运行良好,但在我的主机操作系统网络上无法运行。**
为方便起见,我希望在我的本地网络中分配域,而不是Docker容器网络,以便我可以键入以下内容:www.example.com在我的浏览器URL上并加载Docker容器。client.dev on my browsers URL and load the Docker container.
现在,我只能访问如果我使用Docker IP,这是动态的:
client: 192.168.99.100:80
server: 192.168.99.100:3000
database: 192.168.99.100:5432
有没有一种自动/方便的方法来完成这项工作,而不需要我手动将IP添加到我的/etc/hosts文件?
顺便说一句,我在OSX上,如果这有任何相关性。
谢谢!
- 编辑:**我发现这个Github问题似乎与以下问题有关:https://github.com/docker/docker/issues/2335
据我所知,他们似乎说,这是不可用的东西以外的框,他们建议外部工具,如:
- https://github.com/jpetazzo/pipework
- https://github.com/bnfinet/docker-dns
- https://github.com/gliderlabs/resolvable
是这样吗?如果是这样,在我的特定场景中,我应该选择哪一个?
5条答案
按热度按时间vdgimpew1#
由于似乎没有原生的方法来使用Docker完成此操作,我最终选择了Ryan Armstrong的alternate solution,它包括动态更新
/etc/hosts
文件。我选择这个是因为它对我来说很方便,因为它是一个脚本,而且我已经有了一个启动脚本,所以我可以把这个函数附加到它上面。
以下示例创建一个名为docker.local的主机条目,该条目将解析为您的docker-machine IP:
当我通过启动脚本启动Docker机器时,这将自动添加或更新主机操作系统上的
/etc/hosts
行。无论如何,正如我在研究过程中发现的,除了编辑hosts文件之外,您还可以通过setting up a custom DNS server解决此问题:
我还在Github上找到了几个显然旨在解决这个问题的项目,尽管我没有尝试它们:
pvcm50d12#
扩展@eduwass自己的答案,下面是我手动做的(没有脚本)。
1.如问题中所述,在
docker-compose.yml
文件中定义domainname: myapp.dev
和hostname: www
1.把你们的码头集装箱正常带上来
1.运行
docker-compose exec client cat /etc/hosts
以获取容器的hosts文件的输出(其中client
是您的服务名称)(输出示例:172.18.0.6 www.myapp.dev
)1.打开本地(主机)
/etc/hosts
文件并添加以下行:172.18.0.6 server.server.dev
如果您的Docker服务容器更改了IP或做了任何花哨的事情,您会想要一个更复杂的解决方案,但目前这只是为我的简单需求工作。
eivgtgni3#
另一种解决方案是使用带有代理扩展的浏览器,通过代理容器发送请求,代理容器知道将域解析到哪里。如果您考虑将jwilder/nginx-proxy用于生产模式,那么您的问题可以通过mitm-nginx-proxy-companion轻松解决。
以下是基于原始堆栈的示例:
docker-compose up
127.0.0.1:8080
http://client.dev
请求将遵循以下路径:
mitm-nginx-proxy-companion
,而不是"真正的" Internetmitm-nginx-proxy-companion
尝试通过同一容器中的dns服务器解析域名nginx-proxy
nginx-proxy
依次将请求转发到包含我们要访问的服务的适当容器旁注:
links
,因为它已过时,并已被Docker Networks取代server
和database
容器。client
将能够在server
和database
域上访问它们,因为它们都在同一个网络中(类似于link
以前所做的)server
和database
容器上使用ports
,因为它只转发要通过127.0.0.1
使用的端口。client
容器中的PHP只会对其他容器执行"后端"请求,并且因为这些容器在同一个网络中,您已经可以使用database:5432
和server:3000
访问它们。server <-> database
连接也是如此。mitm-nginx-proxy-companion
的作者9w11ddsr4#
为了使整个域为localhost,您可以使用dnsmasq。在这种情况下,如果您选择域**.dev**,则任何子域都将指向您的容器。但您必须了解具有**.dev**区域的problems
或者,您可以使用bash脚本来启动您的docker-compose,它在启动时会向/etc/hosts添加一行,在您终止此进程后,该行将被删除
0dxa2lsx5#
基于http://cavaliercoder.com/blog/update-etc-hosts-for-docker-machine.html的Bash脚本WITH ALIAS而不使用docker-machine