Heroku

Deploy Nitro apps to Heroku.

Preset: heroku

Read more in heroku.com.

Using the Heroku CLI

Create a new Heroku app.
heroku create myapp

Configure Heroku to use the nodejs buildpack.
heroku buildpacks:set heroku/nodejs

Configure your app.
heroku config:set NITRO_PRESET=heroku

Ensure you have start and build commands in your package.json file.
"scripts": {
  "build": "nitro build", // or `nuxt build` if using nuxt
  "start": "node .output/server/index.mjs"
}

With nginx

Add the Heroku nginx buildpack

Change to the node_middleware preset in your Nitro config
nitro.config.ts
import { defineConfig } from "nitro";

export default defineConfig({
  preset: "node_middleware",
})

Or if you are using Nuxt:
nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    preset: "node_middleware",
  },
})

As described in the Existing app section of the buildpack docs, two key steps are required to get things running:
  • Listen on a socket at /tmp/nginx.socket
  • Create a file /tmp/app-initialized when your app is ready to accept connections

Create a custom app runner (e.g. apprunner.mjs at the root of the project). In this file, create a server using the middleware generated by the node_middleware preset, then listen on the socket as detailed in the buildpack docs:
import { createServer } from 'node:http'
import { middleware } from './.output/server/index.mjs'

const server = createServer(middleware)

server.listen('/tmp/nginx.socket') //following the buildpack doc

To create the /tmp/app-initialized file, use a Nitro plugin (e.g. initServer.ts at the root of the project):
import fs from "node:fs"
import { definePlugin } from "nitro"

export default definePlugin((nitroApp) => {
   if((process.env.NODE_ENV || 'development') != 'development') {
      fs.openSync('/tmp/app-initialized', 'w')
   }
})

Finally, create a Procfile at the root of the project. It tells Heroku to start nginx and use the custom apprunner.mjs to start the server:
Procfile
web: bin/start-nginx node apprunner.mjs

Bonus: create a config/nginx.conf.erb file to customize your nginx config. By default, the node_middleware preset does not generate static file handlers, so you can use nginx to serve static files by adding the right location rule to the server block(s). Alternatively, force the preset to generate static file handlers by setting serveStatic to true.