Deploy a Hono App

This guide explains how to deploy a basic Hono (opens in a new tab) application to Koyeb using:

  1. Git-driven deployment to automatically build and deploy a new version of your application each time a change is detected on your branch.
  2. Pre-built containers you can deploy from any public or private registry.

To successfully follow this documentation, you will need to have a Koyeb account (opens in a new tab). You can optionally install the Koyeb CLI if you prefer to follow this guide without leaving the terminal.

You can deploy and preview the Express application from this guide by clicking the Deploy to Koyeb button below.

Deploy to Koyeb (opens in a new tab)

You can consult the repository on GitHub (opens in a new tab) to find out more about the example application that this guide uses.

Create the Hono app

Get started by creating a minimalistic Hono application. You will need a recent version of Node.js (opens in a new tab) and npm (or another package manager) installed on your local machine. Additionally, you may wish to install Docker (opens in a new tab) if you are planning on building and testing a container image for the application locally.

Generate the project files

To get started, generate a new project directory with the npm create command. In our example, we provide example-hono as the directory name for the new project:

npm create hono@latest example-hono

During the initial project configuration, Hono will prompt you for what type of template you'd like to use. For this example, we'll use Node.js. Select the template with the arrow keys and press ENTER to continue:

create-hono version 0.3.2
✔ Using target directory … example-hono
? Which template do you want to use? › - Use arrow-keys. Return to submit.
    aws-lambda
    bun
    cloudflare-pages
    cloudflare-workers
    deno
    fastly
    lambda-edge
    netlify
    nextjs
❯   nodejs
    vercel

Once the project configuration is complete, navigate into the new directory:

cd example-hono

The directory will contain the following directories and files:

  • .gitignore: A basic .gitignore file to tell Git to ignore the node_modules directory when committing.
  • package.json: The project management file to list dependencies and metadata.
  • README.md: A basic usage document that contains the instructions to install dependencies and run the development server.
  • src/index.ts: The main application file, written in TypeScript.
  • tsconfig.json: The TypeScript configuration file.

Install the dependencies

Next, install the project's dependencies using npm. The basic dependencies we need are already listed in the package.json file, so we only need to execute the following:

npm install

Test the application

Next, start up the development server by typing:

npm run dev

If you visit http://localhost:3000 in your web browser or with curl, you will see a "Hello Hono!" message. This indicates that the server started correctly and is able to respond to requests.

When you are finished, stop the development server by pressing CTRL-C.

Make the port number configurable

Currently, the example application always listens on port 3000. Let's make this dynamically configurable so that the application automatically listens to the port specified by the PORT environment variable.

To do so, open the src/index.ts file in your text editor. Inside, change the port configuration to look at the PORT environment variable, leaving 3000 as the fallback value:

src/index.ts
import { serve } from '@hono/node-server'
import { Hono } from 'hono'
 
const app = new Hono()
 
app.get('/', (c) => {
  return c.text('Hello Hono!')
})
 
const port = process.env.PORT || 3000
console.log(`Server is running on port ${port}`)
 
serve({
  fetch: app.fetch,
  port,
})

Next, start up the development server again with the PORT variable configured:

PORT=8888 npm run dev

Now, the development server should be running on port 8888 instead of port 3000, confirming that our new change works as expected.

Define a start script

The last thing we should do is define a start script for the project. Koyeb's Node.js buildpack automatically executes the start script defined in the package.json to start the application. Hono currently does not set a start script automatically, so we'll define one ourselves.

Open the package.json file in your editor and define a start command in the scripts section of the file:

package.json
{
  "scripts": {
    "start": "tsx src/index.ts",
    "dev": "tsx watch src/index.ts"
  },
  "dependencies": {
    "@hono/node-server": "^1.4.1",
    "hono": "^3.12.7"
  },
  "devDependencies": {
    "tsx": "^3.12.2"
  }
}

Here, we've used the included tsx command to run the src/index.ts file (similar to the dev script, but without the watch). This is enough to start the application. You can test by running:

npm run start

The server should start up and serve the file on port 3000, as per usual.

This example application should run on any modern version of Node.js. If your application requires a specific Node.js version, add or set the engines section in your package.json file. Consult the build with Node.js page to learn more.

Create a Dockerfile for the project (Optional)

We can build and run our Hono project on Koyeb using the native Node.js buildpack, but we can also optionally build from a Dockerfile for more control. To make it possible to build a container image for our application, we just need to create the Dockerfile. We'll also define a .dockerignore file to tell the builder what files to skip when creating the image.

First, define a .dockerignore file in your main project directory. Inside, paste the following contents:

.dockerignore
.git
.gitignore
Dockerfile
.dockerignore
node_modules

This file tells Docker to not include Git files, the Docker files themselves, and any dependencies downloaded to the node_modules directory. This helps ensure that the image we build is not bloated and that the build completes faster.

Next, create a new file called Dockerfile within the main project directory. Inside, paste the following contents:

Dockerfile
FROM node:lts-alpine
 
USER node
WORKDIR /home/node
 
COPY . .
RUN npm ci
 
ARG PORT
EXPOSE ${PORT:-3000}
 
CMD ["npm", "run", "start"]

This Dockerfile is based on the Alpine LTS (long term support) version of the node image (opens in a new tab). The Dockerfile copies all of the project files to the image's filesystem and then installs the dependencies with npm ci. It is configured to allow optionally passing PORT as a build argument and it runs the start script we defined earlier when the container starts.

If you have Docker installed locally, you can build and test the image on your computer and optionally upload it to a registry. You can deploy container images from any container registry to Koyeb.

We can also build the Dockerfile directly from the repository when we deploy, which is useful as a way of automatically deploying when changes occur. We will demonstrate this method as one of the options in this guide.

Push the project to GitHub

In the project directory, initialize a new git repository by running the following command:

git init

Next, add the project files to the staging area and commit them. If you don't have an existing GitHub repository to push the code to, you can create a new one and run the following commands to commit and push changes to your GitHub repository:

git add :/
git commit -m "Initial commit"
git remote add origin git@github.com:<YOUR_GITHUB_USERNAME>/<YOUR_REPOSITORY_NAME>.git
git branch -M main
git push -u origin main

Make sure to replace <YOUR_GITHUB_USERNAME>/<YOUR_REPOSITORY_NAME> with your GitHub username and repository name.

Deploy to Koyeb using git-driven deployment

Once the repository is pushed to GitHub, you can deploy the Hono application to Koyeb. Any changes in the deployed branch of your codebase will automatically trigger a redeploy on Koyeb, ensuring that your application is always up-to-date.

To deploy the Hono app on Koyeb using the control panel (opens in a new tab), follow the steps below:

  1. Click Create Web Service on the Overview tab of the Koyeb control panel.
  2. Select GitHub as the deployment option.
  3. Choose the GitHub repository and branch containing your application code. Alternatively, you can enter our public Hono example repository (opens in a new tab) into the Public GitHub repository at the bottom of the page: https://github.com/koyeb/example-hono.
  4. Choose the Builder for your project. We can use either a Dockerfile or buildpack for this repository.
  5. Name the App and Service, for example example-hono.
  6. Click the Deploy button.

A Koyeb App and Service will be created. Your application will be built and deployed to Koyeb. Once the build has finished, you will be able to access your application running on Koyeb by clicking the URL ending with .koyeb.app.

Deploy to Koyeb from a container registry

If you chose to build a container image for the Hono application, you can optionally deploy the application from a container registry instead of from GitHub.

To deploy a pre-built Hono container image on Koyeb using the control panel (opens in a new tab), follow the steps below:

  1. Click Create Web Service on the Overview tab of the Koyeb control panel.
  2. Select Docker as the deployment option.
  3. Choose the container image and tag from your registry and click Next to continue.
  4. Name the App and Service, for example example-hono.
  5. Click the Deploy button.

A Koyeb App and Service will be created. The container image will be pulled from the container registry and a container will be deployed from it. Once the initialization is complete, you will be able to access your application running on Koyeb by clicking the URL ending with .koyeb.app.