One of the biggest benefits of using docker for me has been the fact that it makes developing code with databases much simpler.
每当我想构建一个项目的时,倾向于使用postgres
作为数据库。在Docker
还没出现前,需要手动安装postgres
到我本地机器,拉起服务,创建数据库表,创建指定的用户和对应的权限,最后在本地拉起项目来测试和开发。整个流程下来几个小时就过去了。
Docker
出现后,事情变得异常简单。特别是在配合docker-compose
使用后,我能快速地在5-10
分钟内拉起postgres
服务并完成配置,而且再也不用操心安装运行在我本机的postgres
服务的升级维护。简直不要太爽!这样一来我就能把节省下来时间用在更重要的事情上,例如看小猫咪的gifs
~
然而,今天除外:(
在网上找到了一份比较靠谱docker-compose
的postgres
配置,经过部分修改后的docker-compose.yml
文件如下:
1 | version: "3" |
其中.env
文件用于配置postgres
用户密码信息:
1 | TZ=Asia/Shanghai |
通过adminer
连接postgres
时,遇到了意想不到的错误:
1 | SQLSTATE[08006] [7] connection to server at "127.0.0.1", port 5432 failed: Connection refused Is the server running on that host and accepting TCP/IP connections? |
WTF!怎么忽然蹦出来个这错误!?
Debug time
第一步:检查拼写错误
第一反应就是检查是不是哪里拼写错误了,经过反复检查,最后并没有发现有什么地方写错了。
第二步:暴力重试
并不是什么高明的处理,只是试着把127.0.0.1
替换成localhost
,但错误依旧。虽然我知道错误是在连接,但是不清楚为什么连接不上…
第三步:手动处理
这办法我经常用。为了排查问题,到命令行下执行以下处理:
- 安装
psql client
- 尝试使用
psql
手动连接(失败) - 使用
netsta
检查端口是否已经被占用(然而并没有) - 不然意识到这可能是网络问题!(啊哈~)
Docker Compose 网络
容器网络实质上也是由Docker为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作系统的网络环境中独立出来,形成容器自有的网络设备、IP协议栈、端口套接字、IP路由表、防火墙等等与网络相关的模块。
在我们这个例子中,postgres
和adminer
服务之间可以直接使用服务名称相互访问的,这样可以避免以ip
方式导致的容器重启动态改变的无法连接情况。
解决办法
在已经知道真正的原因的情况下,剩下的我们只需将连接postgres
的连接字符串中的host
由127.0.01
替换成postgres
就可以了。
1 | postgres@postgres:5432 |
另一种解决办法
Run the containers in default bridge network with docker-compose.yml
设置网络模式为 bridge
(网桥模式)。
引用
docker-compose, postgres and connection refused!
以上。