You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Docker DNS解析问题?无法通过主机名连接PostgreSQL

问题:Docker容器间DNS解析失败及外部工具无法通过容器名连接数据库

1. Docker Compose环境下的问题

我的docker-compose.yml配置如下:

version: '3.8'

services:
  postgres:
    image: postgres:14-alpine
    ports:
      - '5432:5432'
    volumes:
      - ~/apps/postgres:/var/lib/postgresql/data
    env_file:
      - .env

  main:
    container_name: tm_main
    build:
      context: .
    env_file:
      - .env
    volumes:
      - .:/app
      - /app/node_modules
    ports:
      - '3000:3000'
    command: npm run start:dev
    depends_on:
      - postgres
    restart: always

volumes:
  pgdata:

.env文件内容:

PORT=3000

DATABASE_HOST=postgres
DATABASE_USER=user
DATABASE_PASSWORD=root
DATABASE_NAME=docker_problem_db
DATABASE_PORT=5432
JWT_REFRESH_SECRET="refreshVeryHardSecret"
JWT_REFRESH_EXPIRE=86000

运行时出现错误getaddrinfo ENOTFOUND postgres,用Beekeeper Studio连接时,用postgres作为主机名会报错,换成localhost就能正常连接。我希望通过主机名实现连接,试过很多DNS相关方法都没解决。

2. 单独PostgreSQL容器的问题

执行以下命令启动单独容器:

docker run --name acid -d -e POSTGRES_PASSWORD=postgres postgres:13

用以下凭据通过Beekeeper连接失败:

hostname=acid
user=postgres
password=postgres

但执行docker exec -it acid psql -U postgres可以正常连接。

3. 相关网络信息

docker inspect返回的acid容器网络信息:

"Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "0166c61f6a5aea83490fc8c598af04e55df71f9009e336684542f922b4c042cd",
                    "EndpointID": "8c11cc65305666dee3786ad23453b981230adc2bd654aee4b8312fe5f54c074b",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }

当前Docker网络列表:

NETWORK ID     NAME                   DRIVER    SCOPE
0166c61f6a5a   bridge                 bridge    local
491c2f61e8d2   host                   host      local
33ac66fb767c   mynetwork              bridge    local
8233fba80fe2   nest-backend_default   bridge    local
6cc450ff3353   none                   null      local

解决方案

针对Docker Compose的容器间连接问题

  1. 确保服务在同一自定义网络
    Docker Compose默认会创建项目名前缀的网络,但显式指定网络更稳妥。修改docker-compose.yml,添加自定义网络并让两个服务加入:
    version: '3.8'
    
    networks:
      app-network:
        driver: bridge
    
    services:
      postgres:
        image: postgres:14-alpine
        ports:
          - '5432:5432'
        volumes:
          - ~/apps/postgres:/var/lib/postgresql/data
        env_file:
          - .env
        networks:
          - app-network
    
      main:
        container_name: tm_main
        build:
          context: .
        env_file:
          - .env
        volumes:
          - .:/app
          - /app/node_modules
        ports:
          - '3000:3000'
        command: npm run start:dev
        depends_on:
          - postgres
        restart: always
        networks:
          - app-network
    
    volumes:
      pgdata:
    
  2. 验证postgres容器是否就绪
    depends_on只保证启动顺序,不保证数据库初始化完成。用docker-compose logs postgres查看日志,确认出现database system is ready to accept connections后再启动main服务。或者在main服务中加入健康检查脚本(比如wait-for-it.sh)延迟启动。
  3. 测试容器间DNS解析
    进入main容器执行nslookup postgres,如果能返回postgres的IP,说明DNS正常;如果不行,检查网络是否正确关联。

针对外部工具通过容器名连接的问题

Docker默认的bridge网络不支持宿主机直接解析容器名,外部工具(比如Beekeeper)运行在宿主机,无法直接用postgres或acid作为主机名连接,解决方法:

  1. 使用宿主机IP+端口访问
    保持端口映射(比如5432:5432),外部工具用localhost:5432或宿主机IP连接,这是最稳定的方式。
  2. 手动修改宿主机hosts文件
    找到容器的IP(比如172.17.0.2),在宿主机hosts文件中添加172.17.0.2 postgres,但容器重启后IP可能变化,需要重新修改。
  3. 使用host网络模式
    启动容器时添加--network host参数,容器直接使用宿主机网络,外部工具可以用localhost连接,但会失去容器的网络隔离性,不推荐生产环境使用。

单独acid容器连接失败的问题

这个容器在默认bridge网络中,外部工具无法解析acid主机名。先添加端口映射重新启动:

docker stop acid && docker rm acid
docker run --name acid -d -p 5432:5432 -e POSTGRES_PASSWORD=postgres postgres:13

然后用localhost:5432连接即可,或者用容器IP连接。


内容的提问来源于stack exchange,提问作者Shaxa Nematov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 14:36:13