首页/新闻资讯/正文详情

在 Docker 中以库(Library)方式运行 PostGraphile:从零搭建 PostgreSQL + GraphQL 容器化应用

发布时间:2026/9/23 19:53:47 来源:云帆数科 栏目:资讯中心
在 Docker 中以库(Library)方式运行 PostGraphile:从零搭建 PostgreSQL + GraphQL 容器化应用
后端API网关【免费下载链接】crystal Graphiles Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more!项目地址https://gitcode.com/gh_mirrors/cry/crystal点击查看免费下载本指南基于 PostGraphile v4 官方文档讲解如何在本地用 Docker Compose 编排一组容器——一个 PostgreSQL 数据库容器加一个以 Node.js 库形式运行 PostGraphile 的 GraphQL 容器。读完本文你将掌握把 PostGraphile 当作 Node 模块嵌入自有 HTTP 服务器、通过环境变量注入数据库连接、编写 Dockerfile 与 docker-compose.yml以及用docker-compose up一键拉起整套 API 服务。与 CLI 方式相比以库方式运行 PostGraphile 打开了更大的定制空间你可以在 PostGraphile 前后自由挂载自己的中间件、按需加载插件并把 GraphQL 服务无缝整合进已有的 Node.js 应用中。本文对应仓库中的 v4 文档 running-postgraphile-as-a-library-in-docker.md。文中代码以postgraphile^4.5.5为准。为什么选择库而不是 CLIPostGraphile 整体分为三层详见 v4 文档 usage.mdPostGraphile CLI最易上手负责接收命令行参数、启动 HTTP 服务器并挂载中间件多数用户从这里起步PostGraphile 库中间件本主题适合挂载到 Node.js HTTP、Connect、Express、Koa 等应用中文档指出约有 70% 的用户最终会使用这一层。理由包括可以在 PostGraphile 之前加入自己的 Express 中间件如限流、会话、自定义日志、自定义认证并对 PostGraphile 系统拥有更强的控制力GraphQL schemaschema-only最底层绝大多数用户不会用到。本教程与姊妹篇 Running PostGraphile in Docker 的场景完全一致唯一区别是CLI 方式在容器内全局安装postgraphile命令而本文用Node.js 应用以库方式引用 PostGraphile。前置条件先完成 PostgreSQL 容器部分本指南默认你已经按 running-postgraphile-in-docker.md 的步骤完成了以下工作仓库目前应呈现如下结构/ ├─ db/ │ ├─ init/ │ │ ├─ 00-database.sql │ │ └─ 01-data.sql │ └─ Dockerfile ├─ .env └─ docker-compose.yml其中.env已包含数据库相关变量# DB # Parameters used by db container POSTGRES_DBforum_example POSTGRES_USERpostgres POSTGRES_PASSWORDchange_medocker-compose.yml中已定义db服务、network网络与db卷。下面的步骤全部围绕新增graphql服务展开。更新环境变量为 GraphQL 容器补充连接参数编辑仓库根目录的.env文件追加PORT与DATABASE_URL[...] # GRAPHQL # Parameters used by graphql container DATABASE_URLpostgres://postgres:change_medb:5432/forum_example PORT5433两个关键点DATABASE_URL遵循postgres://user:passworddb:5432/db_name语法。注意主机名是db而不是localhost——这是 Docker Compose 网络内的服务名graphql容器正是通过它解析到数据库容器的地址PORT5433供 Node.js 应用监听与下文 docker-compose 中5433:5433的端口映射保持一致。创建 Node.js 应用把 PostGraphile 作为库使用package.json在仓库根目录新建graphql文件夹并在其中创建src子文件夹。首先在graphql/src中放入package.json{ name: postgraphile-as-library, version: 0.0.1, description: PostGraphile as a library in a dockerized Node.js application., author: Alexis ROLLAND, license: Apache-2.0, main: server.js, keywords: [nodejs, postgraphile], dependencies: { postgraphile: ^4.5.5, postgraphile-plugin-connection-filter: ^1.1.3 } }NPM 将依据此文件在容器内安装依赖其中postgraphile是核心包postgraphile-plugin-connection-filter是官方推荐的连接过滤插件用于给连接查询添加filter参数。插件也可以之后通过appendPlugins选项以代码方式加载这一点我们稍后说明。server.js在graphql/src中创建server.jsconst http require(http); const { postgraphile } require(postgraphile); http .createServer( postgraphile(process.env.DATABASE_URL, public, { watchPg: true, graphiql: true, enhanceGraphiql: true, }), ) .listen(process.env.PORT);这就是以库方式运行的核心。它使用 Node.js 内置http模块创建服务器将postgraphile(...)返回的中间件直接作为请求处理器并监听process.env.PORT即我们刚在.env中定义的5433。从 v4 的 API 签名看postgraphile(pgConfig, schemaName, options)三个参数均为可选pgConfigPostgreSQL 连接信息可以是连接字符串、传给pg.Pool的配置对象或一个pg.Pool实例。这里直接使用DATABASE_URL连接字符串schemaName要暴露的 PostgreSQL schema字符串或字符串数组默认public这里显式传入publicoptions其他杂项配置。本示例用到的三个选项watchPg: true监听数据库 schema 变化并自动更新 GraphQL API。该特性需要在数据库安装postgraphile_watchschemaPostGraphile 会尝试自动创建但需要超级用户权限失败时可手动安装移除时执行DROP SCHEMA postgraphile_watch CASCADE;graphiql: true启用 GraphiQL 交互式查询界面enhanceGraphiql: true为 GraphiQL 增加增强功能仅建议开发环境使用开启subscriptions与live时会自动启用。编写 PostGraphile Dockerfile在graphql文件夹注意不是src子文件夹中创建DockerfileFROM node:alpine LABEL descriptionInstant high-performance GraphQL API for your PostgreSQL database https://github.com/graphile/postgraphile # Set Node.js app folder RUN mkdir -p /home/node/app/node_modules WORKDIR /home/node/app # Copy dependencies COPY ./src/package*.json . RUN chown -R node:node /home/node/app # Install dependencies USER node RUN npm install # Copy application files COPY --chownnode:node ./src . EXPOSE 8080 CMD [ node, server.js ]要点拆解FROM node:alpine以官方 Node.js Alpine 镜像为基础镜像体积小适合生产WORKDIR /home/node/app设置应用工作目录USER node切换为非 root 用户运行避免以 root 身份启动 Node 服务COPY ./src/package*.json .先只复制清单文件再执行npm install这样当应用源码变化而依赖未变时Docker 可以复用依赖层缓存显著加快重复构建COPY --chownnode:node ./src .复制src下的server.js与package.json到工作目录并确保属主为node用户EXPOSE 8080声明容器监听端口仅为文档性声明实际端口映射由 docker-compose 控制CMD [ node, server.js ]容器启动时执行node server.js即启动我们上面用库方式编写的 HTTP 服务。更新 Docker Compose注册 graphql 服务编辑根目录的docker-compose.yml在services下追加graphql服务version: 3.3 services: db: [...] graphql: container_name: forum-example-graphql restart: always image: forum-example-graphql build: context: ./graphql env_file: - ./.env depends_on: - db networks: - network ports: - 5433:5433 [...]与db服务逐项对照各参数含义如下完整参数表见 running-postgraphile-in-docker.md参数说明container_name容器名称此处为forum-example-graphqlrestart: always容器退出如崩溃后自动重启image构建产物镜像名forum-example-graphqlbuild.context: ./graphql使用./graphql目录下的 Dockerfile 构建镜像env_file: ./.env将.env中的变量注入容器环境DATABASE_URL与PORT由此进入server.jsdepends_on: db声明依赖数据库服务db先启动networks: network加入与db相同的自定义网络从而可通过服务名db互访ports: 5433:5433将宿主机 5433 端口映射到容器 5433 端口此时仓库结构应为/ ├─ db/ │ ├─ init/ │ │ ├─ 00-database.sql │ │ └─ 01-data.sql │ └─ Dockerfile ├─ graphql/ │ ├─ src/ │ │ ├─ package.json │ │ └─ server.js │ └─ Dockerfile ├─ .env └─ docker-compose.yml构建镜像并启动容器构建镜像在仓库根目录执行# Build images for all services in docker-compose.yml docker-compose build # You can also build images one by one # For instance you can build the database image like this docker-compose build db # And build the graphql image like this docker-compose build graphql启动容器# Run containers for all services in docker-compose.yml docker-compose up # Run containers as daemon (in background) docker-compose up -d # Run only the database container as daemon docker-compose up -d db # Run only the GraphQL container as daemon docker-compose up -d graphql注意首次运行数据库容器时Docker 会自动创建用于持久化数据的卷卷名自动生成为your_repository_name_db。启动后各服务访问地址如下容器Docker on Linux / Windows ProDocker on Windows HomeGraphQL API Documentationhttp://localhost:5433/graphiqlhttp://your_docker_machine_ip:5433/graphiqlGraphQL APIhttp://localhost:5433/graphqlhttp://your_docker_machine_ip:5433/graphqlPostgreSQL Databasehost:localhost, port:5432host:your_docker_machine_ip, port:5432如果你在 Windows Home 上使用 Docker Toolbox可通过docker-machine ip default获取 Docker 机器的 IP 地址替换上面的your_docker_machine_ip。重新初始化数据库当修改/db/init下的 SQL 文件后需要删除卷与数据库镜像并重建才能让新 schema 生效# Stop running containers docker-compose down # List Docker volumes docker volume ls # Delete volume docker volume rm your_repository_name_db # Delete database image to force rebuild docker rmi db # Run containers (will automatically rebuild the image) docker-compose up因为db镜像已被删除docker-compose up会先自动重建镜像同时由于卷已删除/docker-entrypoint-initdb.d/中的初始化 SQL 会重新执行。在库方式下加载插件CLI 方式通过--append-plugins加载插件而库方式则把插件以数组形式传给appendPlugins选项见 v4 文档 extending.mdxconst ConnectionFilterPlugin require(postgraphile-plugin-connection-filter); //... app.use( postgraphile(process.env.DATABASE_URL, public, { appendPlugins: [ ConnectionFilterPlugin, /* add any more plugins you need here */ ], graphiql: true, }), );示例server.js中虽然没有显式加载postgraphile-plugin-connection-filter但package.json已经声明了该依赖你可以随时通过appendPlugins启用它。PostGraphile 的 schema 生成器由一系列 Graphile Engine 插件构成appendPlugins在默认插件之后加载、prependPlugins在默认插件之前加载、skipPlugins用于跳过指定插件。自定义插件实战包装 Mutation 解析器库方式最大的价值在于可以把 PostGraphile 生成的能力与自己的代码深度组合。v4 文档 running-postgraphile-in-docker.md 中的Add Custom Plugin章节给出了一个典型例子用graphile-utils提供的makeWrapResolversPlugin包装createUser变更解析器在解析器执行前后插入日志。const { makeWrapResolversPlugin } require(graphile-utils); // Create custom wrapper for resolver createUser const createUserResolverWrapper () { return async (resolve, source, args, context, resolveInfo) { // You can do something before the resolver executes console.info(Hello world!); console.info(args); // Let resolver execute against database const result await resolve(); // You can do something after the resolver executes console.info(Hello again!); console.info(result); return result; }; }; // Register custom resolvers module.exports makeWrapResolversPlugin({ Mutation: { createUser: createUserResolverWrapper(), }, });包装函数比普通 GraphQL resolver 多一个开头的resolve参数它用于委托给被包装的原始解析器不传参调用resolve()即原样透传也可传source, args, context, resolveInfo覆盖原值详见 make-wrap-resolvers-plugin.md。注意由于 PostGraphile 使用 Graphile Engine 的 look-ahead前瞻特性覆盖 resolver 不一定会影响生成的 SQL。若想影响系统执行方式应只对根级 resolver 使用包装而用包装来增强返回值如脱敏、规范化则对所有字段都安全。在库方式下将该插件文件通过require引入后放进appendPlugins数组即可无需像 CLI 方式那样在 Dockerfile 里npm pack打包插件再经--append-plugins指定。验证效果查询与变更示例数据库初始化脚本db/init创建了user与post两张表一对多关系post.author_id外键引用user.id并预置了三条用户与三条帖子。容器启动后即可在http://localhost:5433/graphiql中验证query { allPosts { nodes { id title body userByAuthorId { username } } } }mutation { createUser(input: { user: { username: Bob } }) { user { id username createdDate } } }执行createUser变更时如果你已按上文加载了makeWrapResolversPlugin包装插件终端会打印Hello world!/Hello again!及其前后的参数与结果日志。生产化建议v4 文档 usage-library.mdx 为库方式提供了生产环境选项集结合本主题可归纳为const postgraphileOptions { subscriptions: true, retryOnInitFail: true, // schema 构建失败时按指数退避重试100ms 起上限 30s dynamicJson: true, // JSON/JSONB 字段以原生 JSON 输入输出 setofFunctionsContainNulls: false, ignoreRBAC: false, extendedErrors: [errcode], graphiql: false, // 生产环境关闭 GraphiQL enableQueryBatching: true, disableQueryLog: true, // 关闭默认查询日志务必自行接入日志系统 legacyRelations: omit, };几点与 Docker 部署直接相关的提醒watchPg依赖数据库超级用户权限安装postgraphile_watchschema且会随 schema 变化重建 GraphQL schema适合开发环境生产环境更推荐在构建流程中导出 schemaexportGqlSchemaPath并关闭 watch生产环境建议关闭graphiql与enhanceGraphiql二者专为开发设计retryOnInitFail在容器化场景尤其有用数据库容器启动需要时间设为true可避免 GraphQL 容器因数据库尚未就绪而在初始化时直接退出。从源码看 PostGraphile 库的形态演进本仓库当前版本v5中postgraphile包的库接口已经从 v4 的postgraphile(pgConfig, schemaName, options)演进为预设preset驱动的工厂函数。在 postgraphile/src/index.ts 中可以看到export function postgraphile( preset: GraphileConfig.Preset, ): PostGraphileInstance { const resolvedPreset resolvePreset(preset); // 若启用 watch则通过 watchSchema 监听 schema 变化并热更新 // ... return { createServ(grafserv) { /* 创建 grafserv 服务器实例 */ }, async getSchemaResult() { /* 获取 schema 构建结果 */ }, async getSchema() { /* 获取 GraphQLSchema */ }, getResolvedPreset() { return resolvedPreset; }, async release() { /* 释放资源、停止 watch */ }, }; }从源码结构可以推断v5 的postgraphile()返回的不再是可直接app.use的中间件而是一个PostGraphileInstance对象需要通过createServ与底层 Grafserv 服务器结合使用连接串、schema、watchPg/graphiql等配置全部并入preset中。本文所讲的 v4 库方式 APIpostgraphile(connectionString, schemaName, options)三参签名与直接作为 HTTP 中间件挂载仍是理解 PostGraphile 库用法的基石v5 文档可参考仓库中 version-5 的对应教程 与 deploying-docker.md。小结至此你已经完成了一套完整的容器化 PostGraphile 库方式部署PostgreSQL 容器负责数据Node.js 容器内嵌postgraphile库提供 GraphQL API二者通过 Docker Compose 网络互联、通过.env共享配置。相比 CLI 方式库方式让你得以在 GraphQL 服务前后自由组合 Node.js 生态的中间件与自定义插件为认证、限流、日志与业务逻辑集成打开了更大的空间。动手修改db/init下的 SQL 并重建卷再在 GraphiQL 中跑一遍查询与变更即可直观感受这套架构的完整工作流。赞分享后端API网关【免费下载链接】crystal Graphiles Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more!项目地址https://gitcode.com/gh_mirrors/cry/crystal点击查看免费下载相关推荐在 Docker 中以 Library 模式运行 PostGraphile V5构建 Node.js 驱动的 GraphQL 容器在 Docker 中以 Library 模式运行 PostGraphile V5构建 Node.js 驱动的 GraphQL 容器 本指南基于 PostGra后端API网关WVP-GB28181-Pro一个开箱即用的 GB28181 国标视频监控平台WVP GB28181 Pro一个开箱即用的 GB28181 国标视频监控平台 当手里的摄像头有海康的、大华的还有早年 RTSP 拉流的老设备想统一纳管或后端音视频前端Squirrel中的容器化在Docker中运行Go数据库应用Squirrel中的容器化在Docker中运行Go数据库应用 为什么需要容器化Go数据库应用 传统Go数据库应用部署常面临环境依赖复杂、版本冲突、部署流程繁琐后端数据库上一篇EntityFramework6三种开发模式深度解析Code First vs Model First vs Database First下一篇WinFsp数据恢复文件系统故障恢复工具全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

深入解析 AWS SDK for Go v2 SigV4a 签名模块(internal/v4a):变更历史、实现原理与在 Substrate 中的实践
深入解析 AWS SDK for Go v2 SigV4a 签名模块(internal/v4a):变更历史、实现原理与在 Substrate 中的实践

深入解析 AWS SDK for Go v2 SigV4a 签名模块(internal/v4a):变更历史、实现原理与在 Substrate 中的实践 【免费下载链接】substrate Agent Substrate: the core system 项目地址: https://gitcode.com/GitHub_Trending/substrate7/substr… · 2026/9/23 19:53:47

Phoenix 中的 OpenInference Span 属性规范:必选与强烈推荐属性完整指南
Phoenix 中的 OpenInference Span 属性规范:必选与强烈推荐属性完整指南

Phoenix 中的 OpenInference Span 属性规范:必选与强烈推荐属性完整指南 【免费下载链接】phoenix AI Observability & Evaluation 项目地址: https://gitcode.com/gh_mirrors/phoenix13/phoenix OpenInference 是一套基于 OpenTelemetry 的 AI/LLM 应用… · 2026/9/23 19:53:46

5分钟搞定uu改肤底层逻辑的速查手册
5分钟搞定uu改肤底层逻辑的速查手册

5分钟搞定uu改肤底层逻辑的速查手册 复制来的代码跑不通,报错信息满屏飞,你是改配置还是查日志?这种抓瞎的状态,90%的开发者都经历过。与其在CSDN或StackOverflow上盲目搜索,不如直接看透底层逻辑。今天这份关于 uu改肤… · 2026/9/23 19:53:40

电影评论情感分析Python实战:从数据预处理到CNN/LSTM模型部署
电影评论情感分析Python实战:从数据预处理到CNN/LSTM模型部署

简介:一套完整的基于深度学习框架的电影评论情感分析项目,面向自然语言处理初学者、数据挖掘课程设计或毕业设计场景,可帮助快速掌握文本情感分类系统的构建方法。系统覆盖数据清洗、分词、去停用词、词性标注、词向量表示、CNN/RNN/LSTM模型… · 2026/9/23 20:25:42

WorkBuddy 智能体实战:从零搭建每日自动化工作流
WorkBuddy 智能体实战:从零搭建每日自动化工作流

1. 为什么我最终把每日重复工作交给了 WorkBuddy每天早上九点坐到工位,打开电脑的第一件事不是写代码,而是打开七八个网页挨个签到、把昨天的订单数据从三个平台导出来合并、再手动整理成日报发到群里。这套动作我做了快两年,熟练到闭着眼睛都… · 2026/9/23 20:25:42

Cytoscape.js 集合邻域 API 详解:neighborhood、openNeighborhood 与 closedNeighborhood 的图遍历实战
Cytoscape.js 集合邻域 API 详解:neighborhood、openNeighborhood 与 closedNeighborhood 的图遍历实战

数据可视化 【免费下载链接】cytoscape.js Graph theory (network) library for visualisation and analysis 项目地址: https://gitcode.com/gh_mirrors/cy/cytoscape.js 点击查看 免费下载 导读 eles.neighborhood() 是 Cytoscape.js 图遍历体系中用于获取"… · 2026/9/23 20:25:42

opencodex Claude Code 入站代理生产级加固:错误分类、EOF 熔断、空闲心跳与可观测性闭环(WP1–WP4)
opencodex Claude Code 入站代理生产级加固:错误分类、EOF 熔断、空闲心跳与可观测性闭环(WP1–WP4)

【免费下载链接】opencodex Universal provider proxy for OpenAI Codex & Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code 项目地址: https://gitcode.com/gh_mirrors/ope/opencodex 点击… · 2026/9/23 20:25:42

Dopamine 连续控制域实验运行器 ContinuousRunner 完全指南:JAX/Flax Agent 的训练调度、参数配置与源码剖析
Dopamine 连续控制域实验运行器 ContinuousRunner 完全指南:JAX/Flax Agent 的训练调度、参数配置与源码剖析

机器学习深度学习 【免费下载链接】dopamine Dopamine is a research framework for fast prototyping of reinforcement learning algorithms. 项目地址: https://gitcode.com/gh_mirrors/do/dopamine 点击查看 免费下载 导读 dopamine.continuous_domains.run_… · 2026/9/23 20:25:35

2026最新 ps钢笔工具怎么描边 避坑指南
2026最新 ps钢笔工具怎么描边 避坑指南

2026最新 ps钢笔工具怎么描边 避坑指南 刚更新完 Photoshop 2026 版本,你是不是也发现原本熟悉的“描边”按钮位置变了,或者参数完全对不上?很多老手都吐槽,版本升级后 API… · 2026/9/23 20:25:28

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码