crystal icon indicating copy to clipboard operation
crystal copied to clipboard

How to run postgraphile with https

Open duncangroenewald opened this issue 7 months ago • 3 comments

What is the easiest way to set up a local hosted postgraphile server running with https ?

duncangroenewald avatar Apr 17 '25 00:04 duncangroenewald

It seems running with a simple https server isn't simple.

 // server.js
  import app  from 'express';
  import https from 'https';
  import fs from 'fs';

import {postgraphile} from 'postgraphile';

import {PostGraphileAmberPreset} from "postgraphile/presets/amber";
import {makePgService, PgSubscriber} from "postgraphile/adaptors/pg";

/** @type {GraphileConfig.Preset} */
const preset = {
  extends: [PostGraphileAmberPreset],
  pgServices: [makePgService({ connectionString: "postgresql://xxxxxxxxxxx:5432/appname",
                               schemas: "healthkiosk",
                               port: 5679
   })],
  grafserv: { watch: false }
  // ,
  // schema: {
  //   /* options for the schema build phase, e.g.: */
  //   retryOnInitFail: true,
  //   exportSchemaSDLPath: `${process.cwd()}/latestSchema.graphql`,
  //   exportSchemaIntrospectionResultPath: `${process.cwd()}/latestSchema.json`,
  //   sortExport: true,
  // }
};

const options = {
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem')
}

https.createServer(options, postgraphile(preset))
.listen(443);

And this is the resulting output

The GRAPHILE_ENV environmental variable is not set; Grafast will run in production mode. In your development environments, it's recommended that you set GRAPHILE_ENV=development to opt in to additional checks that will provide guidance and help you to catch issues in your code earlier, and other changes such as formatting to improve your development experience. node:internal/errors:496 ErrorCaptureStackTrace(err); ^

TypeError [ERR_INVALID_ARG_TYPE]: The "listener" argument must be of type function. Received an instance of Object at checkListener (node:events:267:3) at _addListener (node:events:547:3) at Server.addListener (node:events:606:10) at new Server (node:https:79:10) at Object.createServer (node:https:112:10) at file:///Users/XXXXXXXXXXXXXXXXX/postgraphile/https-server.js:34:7 at ModuleJob.run (node:internal/modules/esm/module_job:194:25) { code: 'ERR_INVALID_ARG_TYPE' }

Node 18.17.1

duncangroenewald avatar Apr 17 '25 04:04 duncangroenewald

Well that proved to be ridiculous but I eventually found this which worked and was super easy. // On a Mac sudo npm install -g local-ssl-proxy local-ssl-proxy --source 5677 --target 5678 --cert cert.pem --key key.pem

copy cert.pem into keychain Login certificates and set trust to always.

now run npx postrgraphile on port 5678.

too easy

duncangroenewald avatar Apr 17 '25 05:04 duncangroenewald

// ⚠️ THIS WILL NOT WORK WITH V5!
https.createServer(options, postgraphile(preset)).listen(443);

This would not work because postgraphile(preset) doesn't return a middleware, so it can't be mounted in this way. You're likely looking at the documentation for an older version of PostGraphile.

Instead; I would take the example from the documentation for node:http as a starting point, and then adjust it for HTTPS, something like:

-import { createServer } from "node:http";
+import { createServer } from "node:https";
+import { readFile } from "node:fs/promises";
 import { grafserv } from "postgraphile/grafserv/node";
 import { pgl } from "./pgl.js";
 
+const key = await readFile('key.pem');
+const cert = await readFile('cert.pem');
 const serv = pgl.createServ(grafserv);
 
-const server = createServer();
+const server = createServer({ key, cert });
 server.on("error", (e) => {
   console.error(e);
 });
 
 serv.addTo(server).catch((e) => {
   console.error(e);
   process.exit(1);
 });
 
 server.listen(5678);
 
-console.log("Server listening at http://localhost:5678");
+console.log("Server listening at https://localhost:5678");

I've not tried this though, would be good to have a tested example 👍

benjie avatar Apr 17 '25 08:04 benjie