Language and Framework

Deploy Next.js based apps

This page takes you through setting up instellar for a Next.js application. You will learn how to configure your application to run on your PaaS.

Example Application

We’ve created an example application in case you wish to skip right to the source code.

A note on INSTELLAR_ENDPOINT

The examples in the codebase we referenced the .github/workflows/deployment.yml file will contain a value for INSTELLAR_ENDPOINT this is only necessary in those repositories since they’re deploying to our staging environment. For our customers we recommend omitting this value.

In this example we build a Next.js using the standalone option. In this configuration next/image is also fully working as intended.

A note on next 13.3.0

The example uses next 13.2.4 because later version has a bug that causes the next/image module to not work properly. We recommend sticking with 13.2.4 until the bug is resolved.

next.config.js

You will need to add the configuration to tell next to build a standalone production build. Your next config file should look something like this.

const withNextra = require('nextra')({
  theme: 'nextra-theme-blog',
  themeConfig: './theme.config.js',
})

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'standalone'
}

module.exports = withNextra(nextConfig)

instellar.yml

This file is used to describe to PAKman how to build your application. The following is taken from a Next.js based application. This configuration will change depending on your application. This file will work with a freshly generated Next.js app.

Dependencies

Let’s begin with the dependencies. You will also notice we’re enabling trace: true in our dependencies. This will enable dependency tracing, which means even if we miss some dependency in our runtime the build tool will trace the dependency and automatically include it in our package. That’s cool!

dependencies:
  trace: true
  build:
    - nodejs
    - npm
    - vips-dev
  runtime:
    - nodejs
    - npm
    - bash
    - curl
    - s6
    - jq
    - ca-certificates
    - icu-data-full
    - nimbus-openrc

Choosing a Stack

We’re using alpine as the base image for all the containers that run the applications. We recommend using alpine/3.17 for all applications. However please check the alpine packages listing to see compatibility for your language and framework. In this case alpine/3.17 will run node 18.14.2.

You can choose from the following:

  • alpine/edge
  • alpine/3.17
  • alpine/3.16
  • alpine/3.15
stack: alpine/3.17

Build

The below section tells PAKman how to build your application. We’re simply installing the dependencies by running npm install. Then we’re running the build.

Since we’re building a standalone version of Next.js we will also need to copy the static files over to be served by the next server. This is based on the official documentation.

build:
  destinations: 
    - '.next/standalone'
  command: |
    npm install
    npm run build

    cp -r .next/static .next/standalone/.next/
    cp -r public .next/standalone/

Run

The below section explains how your application is run.

The services section enables you to define how your application runs. In this case we also have to define the path setting. Since we’re not using a binary built inside of our app. We’re using the OS level nodejs to run our server.

run: 
  name: nimbus
  services:
  - name: web
    binary: node
    path: /usr/bin
    start:
      call: 'standalone/server.js'

Hooks

Hooks

These are the lifecycle of the alpine packages. You can define their behaviour. Generally we don’t expect this to change from app to app. However feel free to adjust as required.

In this case rc-update add nimbus will add our nimbus app to the default run. This will ensure our app automatically starts when the container is restarted (incase it needs to restart).

The rc-service nimbus migrate will run the migration. In this case it will run after the package is installed and after the upgrade.

  • rc-service nimbus start will start the application
  • rc-service nimbus stop will simply stop the application

Your application will be built into openrc and supervised by the s6 supervisor suite.

hook:
  post-install: |
    rc-update add nimbus

  pre-upgrade: |
    rc-service nimbus stop

  post-upgrade: |
    rc-service nimbus start

  post-deinstall: |
    rc-service nimbus stop
    rc-update del rdio

Putting it together

The final file looks like the following:

dependencies:
  trace: true
  build:
    - nodejs
    - npm
    - vips-dev
  runtime:
    - nodejs
    - npm
    - bash
    - curl
    - s6
    - jq
    - ca-certificates
    - icu-data-full
    - nimbus-openrc

stack: alpine/3.17

build:
  destinations: 
    - '.next/standalone'
  command: |
    npm install
    npm run build

    cp -r .next/static .next/standalone/.next/
    cp -r public .next/standalone/

run: 
  name: nimbus
  services:
  - name: web
    binary: node
    path: /usr/bin
    start:
      call: 'standalone/server.js'

hook:
  post-install: |
    rc-update add nimbus

  pre-upgrade: |
    rc-service nimbus stop

  post-upgrade: |
    rc-service nimbus start

  post-deinstall: |
    rc-service nimbus stop
    rc-update del rdio

If you have further suggestions on how we can make this better please don't hesitate to open an issue. Or reach out to us via one of our support channels. If you need a quick support and would like to chat you can join our slack group.