database 将 docker-compose 连接到外部数据库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43762537/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Connect docker-compose to external database
提问by Siscia
I have a set up of 4 containers that need to talk to each other and two of those need to connect to an external database.
我设置了 4 个需要相互通信的容器,其中两个需要连接到外部数据库。
I started working with composer and link everything together.
我开始与作曲家合作并将所有内容链接在一起。
The containers are able to talk with each other without many issues, however they can't connect to the external database.
容器可以毫无问题地相互通信,但是它们无法连接到外部数据库。
The external DB is up and running and I can easily connect to it via shell.
外部数据库已启动并正在运行,我可以通过 shell 轻松连接到它。
The docker-compose file looks like this:
docker-compose 文件如下所示:
version: "3"
services:
bridge:
# version => 2.1.4
build: ./lora-gateway-bridge
ports:
- "1680/udp:1700/udp"
links:
- emqtt
- redis
environment:
- MQTT_SERVER=tcp://emqtt:1883
networks:
- external
restart: unless-stopped
loraserver:
# version => 0.16.1
build: ./loraserver
links:
- redis
- emqtt
- lora-app-server
environment:
- NET_ID=010203
- REDIS_URL=redis://redis:6379
- DB_AUTOMIGRATE=true
- POSTGRES_DSN=${SQL_STRING} ###<- connection string
- BAND=EU_863_870
ports:
- "8000:8000"
restart: unless-stopped
lora-app-server:
build: ./lora-app-server
# version => 0.8.0
links:
- emqtt
- redis
volumes:
- "/opt/lora-app-server/certs:/opt/lora-app-server/certs"
environment:
- POSTGRES_DSN=${SQL_STRING} ### <- connection string
- REDIS_URL=redis://redis:6379
- NS_SERVER=loraserver:8000
- MQTT_SERVER=tcp://emqtt:1883
ports:
- "8001:8001"
- "443:8080"
restart: unless-stopped
redis:
image: redis:3.0.7-alpine
restart: unless-stopped
emqtt:
image: erlio/docker-vernemq:latest
volumes:
- ./emqttd/usernames/vmq.passwd:/etc/vernemq/vmq.passwd
ports:
- "1883:1883"
- "18083:18083"
restart: unless-stopped
It seems like they are unable to find the host where the database is running.
他们似乎无法找到运行数据库的主机。
All the example that I see talk about a database inside the docker-compose, but I haven't quite grasp how to connect the container to an external service.
我看到的所有示例都在谈论 docker-compose 中的数据库,但我还没有完全掌握如何将容器连接到外部服务。
回答by andreim
From your code I see that you need to connect to an external PostgreSQL server.
从您的代码中,我看到您需要连接到外部 PostgreSQL 服务器。
Networks
网络
Being able to discover some resource in the network is related to which network is being used.
能够发现网络中的某些资源与正在使用的网络有关。
There is a set of network types that can be used, which simplify the setup, and there is also the option to create your own networks and add containers to them.
有一组可以使用的网络类型,可以简化设置,还可以选择创建自己的网络并向其中添加容器。
You have a number of types that you can choose from, the top has the most isolation possible:
您有多种类型可供选择,顶部的隔离度最高:
- closed containers= you have only the loopback inside the container but no interactions with the container virtual network and neither with the host network
- bridged containers= your containers are connected through a default bridge network which is connected finally to the host network
- joined containers= your containers network is the same and no isolation is present at that level (), also has connection to the host network
- open containers= full access to the host network
- 封闭容器= 您在容器内只有环回,但与容器虚拟网络没有交互,也没有与主机网络交互
- 桥接容器= 您的容器通过默认桥接网络连接,该桥接网络最终连接到主机网络
- 加入的容器= 您的容器网络是相同的,并且该级别没有隔离(),也连接到主机网络
- 打开容器= 完全访问主机网络
The default type is bridgeso you will have all containers using one default bridge network.
默认类型是桥接,因此您将拥有使用一个默认桥接网络的所有容器。
In docker-compose.ymlyou can choose a network type from network_mode
在docker-compose.yml你可以选择从网络型network_mode
Because you haven't defined any network and haven't changed the network_mode, you get to use the default - bridge.
因为您还没有定义任何网络并且没有更改network_mode,所以您可以使用默认的 - bridge。
This means that your containers will join the default bridge network and every container will have access to each other and to the host network.
这意味着您的容器将加入默认的桥接网络,并且每个容器都可以相互访问并访问主机网络。
Therefore your problem does not reside with the container network. And you should check if PostgreSQL is accessible for remote connections. For example you can access PostgreSQL from localhost by default but you need to configure any other remote connection access rules.
因此,您的问题不在于容器网络。您应该检查远程连接是否可以访问 PostgreSQL。例如,默认情况下您可以从 localhost 访问 PostgreSQL,但您需要配置任何其他远程连接访问规则。
You can configure your PostgreSQL instance by following this answeror this blog post.
您可以按照此答案或此博客文章配置您的 PostgreSQL 实例。
Inspect networks
检查网络
Following are some commands that might be useful in your scenario:
以下是一些可能在您的场景中有用的命令:
- list your available networks with:
docker network ls - inspect which container uses
bridgenetwork:docker network inspect --format "{{ json .Containers }}" bridge - inspect container networks:
docker inspect --format "{{ json .NetworkSettings.Networks }}" myContainer
- 列出您的可用网络:
docker network ls - 检查哪个容器使用
bridge网络:docker network inspect --format "{{ json .Containers }}" bridge - 检查容器网络:
docker inspect --format "{{ json .NetworkSettings.Networks }}" myContainer
Testing connection
测试连接
In order to test the connection you can create a container that runs psqland tries to connect to your remote PostgreSQL server, thus isolating to a minimum environment to test your case.
为了测试连接,您可以创建一个运行psql并尝试连接到远程 PostgreSQL 服务器的容器,从而隔离到最小环境来测试您的案例。
Dockerfile can be:
Dockerfile 可以是:
FROM ubuntu
RUN apt-get update
RUN apt-get install -y postgresql-client
ENV PGPASSWORD myPassword
CMD psql --host=10.100.100.123 --port=5432 --username=postgres -c "SELECT 'SUCCESS !!!';"
Then you can build the image with: docker build -t test-connection .
然后您可以使用以下命令构建图像: docker build -t test-connection .
And finally you can run the container with: docker run --rm test-connection:latest
最后,您可以使用以下命令运行容器: docker run --rm test-connection:latest
If your connection succeeds then SUCCESS !!! will be printed.
如果您的连接成功,那么 SUCCESS !!! 将被打印。
Note:connecting with localhostas in CMD psql --host=localhost --port=5432 --username=postgres -c "SELECT 'SUCCESS !!!';"will not work as the localhost from within the container is the container itself and will be different than the main host. Therefore the address needs to be one that is discoverable.
注意:使用localhostas in连接CMD psql --host=localhost --port=5432 --username=postgres -c "SELECT 'SUCCESS !!!';"将不起作用,因为容器内的 localhost 是容器本身,并且与主主机不同。因此,地址必须是可发现的。
Note:if you would start your container as a closed container using docker run --rm --net none test-connection:latest, there will be no other network interface than loopback and the connection will fail. Just to show how choosing a network may influence the outcome.
注意:如果您使用 将容器作为封闭容器启动docker run --rm --net none test-connection:latest,则除了环回没有其他网络接口,连接将失败。只是为了说明选择网络如何影响结果。

