Prisma 和 Postgres FetchError:对 http://localhost:4466/management 的请求失败

Posted

技术标签:

【中文标题】Prisma 和 Postgres FetchError:对 http://localhost:4466/management 的请求失败【英文标题】:Prisma and Postgres FetchError: request to http://localhost:4466/management failed 【发布时间】:2019-12-04 12:48:12 【问题描述】:

我正在尝试与 Prisma 合作。我也尝试过有关 GitHub 问题和 *** 的可用解决方案。

我已经使用以下命令安装了 Prisma

npm install -g prisma

我在系统中安装了 docker 和 docker-compose。

以下是我的 docker-compose 文件

version: '3'
services:
 prisma:
   image: prismagraphql/prisma:1.34
   restart: always
   ports:
    - "4466:4466"
   environment:
      PRISMA_CONFIG: |
       port: 4466
       # uncomment the next line and provide the env var PRISMA_MANAGEMENT_API_SECRET=my-secret to activate cluster security
       # managementApiSecret: my-secret
       databases:
         default:
           connector: postgres
           host: host.docker.internal
           database: db
           schema: public
           user: prisma
           password: prisma
           ssl: false
           rawAccess: true
           port: '5432'
           migrations: true
  postgres:
   image: postgres:11
   restart: always
   environment:
     POSTGRES_USER: prisma
      POSTGRES_PASSWORD: prisma
   volumes:
     - postgres:/var/lib/postgresql/data
volumes:
  postgres: ~

所以,现在我尝试使用以下命令启动我的容器

docker-compose up -d

现在,我使用以下命令检查容器是否运行良好。

docker-compose ps

以下是输出

Name                        Command                         State   Ports         
------------------------------------------------------------------------------------------
graphql-prisma_postgres_1   docker-entrypoint.sh postgres   Up      5432/tcp              
graphql-prisma_prisma_1     /bin/sh -c /app/start.sh        Up      0.0.0.0:4466->4466/tcp

现在,如果我尝试执行以下操作

prisma deploy
docker-compose ps

以下是输出

environment FetchError: request to http://localhost:4466/management failed, reason: connect ECONNREFUSED 127.0.0.1:4466
environment     at ClientRequest.<anonymous> (/home/tomonso/.nvm/versions/node/v12.4.0/lib/node_modules/prisma/node_modules/node-fetch/lib/index.js:1393:11)
environment     at ClientRequest.emit (events.js:200:13)
environment     at ClientRequest.EventEmitter.emit (domain.js:471:20)
environment     at Socket.socketErrorListener (_http_client.js:402:9)
environment     at Socket.emit (events.js:200:13)
environment     at Socket.EventEmitter.emit (domain.js:471:20)
environment     at emitErrorNT (internal/streams/destroy.js:91:8)
environment     at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
environment     at processTicksAndRejections (internal/process/task_queues.js:84:9) +0ms
environment FetchError: request to http://localhost:4466/management failed, reason: connect ECONNREFUSED 127.0.0.1:4466
environment     at ClientRequest.<anonymous> (/home/tomonso/.nvm/versions/node/v12.4.0/lib/node_modules/prisma/node_modules/node-fetch/lib/index.js:1393:11)
environment     at ClientRequest.emit (events.js:200:13)
environment     at ClientRequest.EventEmitter.emit (domain.js:471:20)
environment     at Socket.socketErrorListener (_http_client.js:402:9)
environment     at Socket.emit (events.js:200:13)
environment     at Socket.EventEmitter.emit (domain.js:471:20)
environment     at emitErrorNT (internal/streams/destroy.js:91:8)
environment     at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
environment     at processTicksAndRejections (internal/process/task_queues.js:84:9) +3ms
command Failed to fetch server version +0ms
command TypeError: Cannot read property 'replace' of null +0ms
environment FetchError: request to http://localhost:4466/management failed, reason: connect ECONNREFUSED 127.0.0.1:4466
environment     at ClientRequest.<anonymous> (/home/tomonso/.nvm/versions/node/v12.4.0/lib/node_modules/prisma/node_modules/node-fetch/lib/index.js:1393:11)
environment     at ClientRequest.emit (events.js:200:13)
environment     at ClientRequest.EventEmitter.emit (domain.js:471:20)
environment     at Socket.socketErrorListener (_http_client.js:402:9)
environment     at Socket.emit (events.js:200:13)
environment     at Socket.EventEmitter.emit (domain.js:471:20)
environment     at emitErrorNT (internal/streams/destroy.js:91:8)
environment     at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
environment     at processTicksAndRejections (internal/process/task_queues.js:84:9) +4ms
environment FetchError: request to http://localhost:4466/management failed, reason: connect ECONNREFUSED 127.0.0.1:4466
environment     at ClientRequest.<anonymous> (/home/tomonso/.nvm/versions/node/v12.4.0/lib/node_modules/prisma/node_modules/node-fetch/lib/index.js:1393:11)
environment     at ClientRequest.emit (events.js:200:13)
environment     at ClientRequest.EventEmitter.emit (domain.js:471:20)
environment     at Socket.socketErrorListener (_http_client.js:402:9)
environment     at Socket.emit (events.js:200:13)
environment     at Socket.EventEmitter.emit (domain.js:471:20)
environment     at emitErrorNT (internal/streams/destroy.js:91:8)
environment     at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
environment     at processTicksAndRejections (internal/process/task_queues.js:84:9) +1ms
Error: Could not connect to server at http://localhost:4466. Please check if your server is running.
at Deploy.<anonymous> (/home/tomonso/.nvm/versions/node/v12.4.0/lib/node_modules/prisma/node_mod 
ules/prisma-cli-core/src/commands/deploy/deploy.ts:137:13)
at step (/home/tomonso/.nvm/versions/node/v12.4.0/lib/node_modules/prisma/node_modules/prisma-cli-core/dist/commands/deploy/deploy.js:45:23)
at Object.next (/home/tomonso/.nvm/versions/node/v12.4.0/lib/node_modules/prisma/node_modules/prisma-cli-core/dist/commands/deploy/deploy.js:26:53)
at fulfilled (/home/tomonso/.nvm/versions/node/v12.4.0/lib/node_modules/prisma/node_mod 
ules/prisma-cli-core/dist/commands/deploy/deploy.js:17:58)
   at processTicksAndRejections (internal/process/task_queues.js:89:5)
(node:25136) [DEP0066] DeprecationWarning: 
OutgoingMessage.prototype._headers is deprecated
 util timed out +0ms
  output Exiting with code: 0 +0ms

【问题讨论】:

你是如何设置postgresql的? 【参考方案1】:

首先如果你使用docker logs查看prisma日志,你会发现很多错误。这里有几个问题:

    host.docker.internal 仅适用于 docker for mac/docker for windows。

    如果以上是你的真相,那么你想使用host machine's 5432 port 访问postgres's 5342 port。如果是这样,则需要在postgres service中指定端口映射- "5432:5432"

    如果你只是在 linux 上工作,那么host.docker.internal 甚至无法识别。

    其实不管你用windows/mac/linux,只要把host: host.docker.internal换成host: postgresprisma container就可以直接访问postgres container,不需要宿主机干预,可以参考this,搜索 User-defined bridges provide automatic DNS resolution between containers 在该页面中获取更多帮助。

    prisma service要设置db数据库时,postgres service甚至还没有启动,你需要定义启动顺序保证postgres serviceprisma service之前准备好,可以参考@987654322 @:

    但是,如果你查看它的入口点,你可以看到下一个:

    bash-4.4# cat start.sh
    #!/bin/bash
    set -e
    /app/prerun_hook.sh
    /app/bin/prisma-local
    

    这里,/app/prerun_hook.sh 是一个钩子,供使用此映像做一些准备工作的用户使用,因此您可以在此文件中添加一些服务启动保证代码,以确保 db 服务已经启动。

最后,下一个可行的解决方案是:

docker-compose.yaml:

version: '3'
services:
  prisma:
    build: .
    restart: always
    ports:
      - "4466:4466"
    environment:
      PRISMA_CONFIG: |
        port: 4466
        databases:
          default:
            connector: postgres
            host: postgres
            database: db
            schema: public
            user: prisma
            password: prisma
            ssl: false
            rawAccess: true
            port: '5432'
            migrations: true
    depends_on:
      - "postgres"
  postgres:
    image: postgres:11
    restart: always
     environment:
      POSTGRES_USER: prisma
      POSTGRES_PASSWORD: prisma
    volumes:
      - postgres:/var/lib/postgresql/data
volumes:
   postgres: ~

Dockerfile:

FROM prismagraphql/prisma:1.34
COPY ./prerun_hook.sh /app/prerun_hook.sh
RUN chmod +x /app/prerun_hook.sh && \
    apk add postgresql-client

prerun_hook.sh:

#!/bin/sh
set -e

until PGPASSWORD="prisma" psql -h postgres -U "prisma" -c '\q'; do
  >&2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

>&2 echo "Postgres is up - executing command"

然后,如果检查 docker logs 你会看到下一个,这意味着现在可以了:

Postgres is up - executing command
No log level set, defaulting to INFO.
[INFO]  - Starting...
[INFO]  - Start completed.
[INFO] Initializing workers...
[INFO] Obtaining exclusive agent lock...
[INFO] Obtaining exclusive agent lock... Successful.
[INFO] Successfully started 1 workers.
[INFO] Deployment worker initialization complete.
Server running on :4466

【讨论】:

以上是关于Prisma 和 Postgres FetchError:对 http://localhost:4466/management 的请求失败的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Dockerized GraphQL + Postgres 设置中运行 Prisma 迁移?

如何使用 Prisma 为 Postgres 进行 SQL 插入,条件是行数?

Prisma 无法验证数据库服务器

Docker 中的 NestJS 无法在另一个 Docker 容器中的 Postgres 上执行 Prisma Migrate

NestJS Postgres Prisma - 错误类型'字符串'不可分配给参数类型'TemplateStringsArray | Sql'

访问 postgres docker 容器时出现连接错误