nestjs / nest

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
https://nestjs.com
MIT License
67.79k stars 7.64k forks source link

Use of greenlock-express with NestJS? #6309

Closed JotFX closed 3 years ago

JotFX commented 3 years ago

Hi folks!

To get free SSL certificates, I would like to use greenlock-express with NestJS. I thought, this must be easy, as NestJS uses Express in the background. But no luck for me. I tried something like the following with the boilerplate NestJS app, but no success:

async function bootstrap() { const app = await NestFactory.create(AppModule); require('greenlock-express').init({ packageRoot: __dirname + "/..", configDir: "./greenlock.d", maintainerEmail: "john@forge.com", cluster: false }) .serve(app); } bootstrap();

I am just getting the error

(node:5972) UnhandledPromiseRejectionWarning: Error: glx.serveApp(app) expects a node/express app in the format function (req, res) { ... }

The example (with express) suggests, to provide the app to serve like this:

var express = require("express"); var app = express(); app.use("/", function(req, res) { res.setHeader("Content-Type", "text/html; charset=utf-8"); res.end("Hello, World!\n\n💚 🔒.js"); }); module.exports = app;

Can you tell me, what the difference is and how I can get greenlock-express to work with NestJS? Having free SSL-certificates without the need of managing the certificates yourself, would be big plus. I couldn't find anything regarding greenlock and nestjs.

Any help appreciated!

jmcdo29 commented 3 years ago

Instead of passing app it looks like you need to pass the http engine instance. Something like this should do

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  greenlock
    .init({
      packageRoot: __dirname + '/..',
      configDir: './greenlock.d',
      cluster: false,
      maintainerEmail: 'johndoe@example.com',
    })
    .serve(app.getHttpAdapter().getInstance());
}
bootstrap();
JotFX commented 3 years ago

Hi again! Unfortunately it took me some time to test and answer back. NestJS seems to start normal with this, but when I open the site in the browser, i just get 404 "Cannot GET /" as a plain text answer in the browser. Do you have any idea, whats happening or how to debug this? Kind regards

JotFX commented 3 years ago

I found another way. First create the application like this

const server = express();
  const app = await NestFactory.create<NestExpressApplication>(
      AppModule,
      new ExpressAdapter(server),
  );

then init it

await app.init();

and then start greenlock like this

const greenInit = greenlock
        .init({
          packageRoot: __dirname + '/../../../..',
          configDir: './greenlock.d',
          cluster: false,
          maintainerEmail: '****',
        }).serve(server);

Works so far, but I am having trouble getting websockets working. I guess they are initialized before with HTTP, before the app gets wrapped by greenlock-express. Dont exactly know how to fix it.

kieranongh commented 3 years ago

@JotFX Where is the server variable set?

Is it the output of await app.init()?

const server = await app.init()

Thanks for posting your findings btw, I was looking greenlock literally thinking similar to you: this should work with NestJS right?

EDIT Just saw it - const server = express() I'll be giving it a crack tonight I hope

JotFX commented 3 years ago

I am happy to help. By the way: my problems with websockets originated in the additional integration of a PeerJs server into the NestJs server. As soon I made a separate PeerJs server, everything worked with websockets.

JotFX commented 3 years ago

@kieranongh The result of await app.init(); is indeed omitted.