Deploy an Express App

This guide explains how to deploy an Express (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 Express app

Get started by creating a minimalistic Express application. You will need Node.js (opens in a new tab) 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.

In your terminal, run the following commands to create and navigate into the directory that will hold the application code:

mkdir example-expressjs
cd example-expressjs

Next, initialize a new Node project by typing:

npm init

You'll be prompted for the project details. For the most part, you can press ENTER to accept the suggested defaults. When prompted for the entry point, type in app.js instead.

Next, install Express by typing:

npm install express

Once Express is downloaded and installed as a project dependency, create a new app.js file to define the application. Inside, paste the following:

app.js
const express = require('express')
const app = express()
const port = process.env.PORT || 3000
 
app.get('/', (req, res) => {
  res.json({
    message: 'Hello, world!',
  })
})
 
app.listen(port, () => {
  console.log(`App is listening on port ${port}`)
})

This simple application starts up a basic web server listening on a configurable port that defaults to port 3000. It responds to requests for / with a JSON "hello world" response.

Test the Express application locally

Test that you can run the application locally by typing:

node app.js

If you visit http://localhost:3000 in your browser, you should see the following response:

{ "message": "Hello, world!" }

Stop the server when you are finished by pressing CTRL-C.

Next, confirm that you can alter the listening port by passing a PORT environment variable set to 8000:

PORT=8000 node app.js

This time, the server should listen on port 8000 instead of the default 3000.

Add a start script

Next, open the package.json file in your editor. In the scripts object, add a start script:

package.json
{
  "name": "example-expressjs",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.2"
  }
}

This script let's us run the application using npm run start, which is what Koyeb's Node.js buildpack executes when attempting to run Node.js applications.

Confirm that the application starts as expected with the npm run start command by typing:

npm run start

You can test alternative ports by typing:

PORT=8000 npm run start

The application should work as expected using the new run command.

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 Express 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.

Start by defining the .dockerignore file in your main project directory. Inside, paste the following contents:

.dockerignore
.git
.gitignore
Dockerfile
.dockerignore
node_modules
.env
README.md

This file tells Docker to not include Git files, the Docker files themselves, dependency directories, built artifacts, or environment files unless explicitly called out within the Dockerfile. 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:slim
 
WORKDIR /app
COPY . .
RUN npm ci
 
ARG PORT
EXPOSE ${PORT:-3000}
 
CMD ["npm", "run", "start"]

This Dockerfile uses a is based on a minimal Node container image (opens in a new tab). It copies the project files to the image and installs the dependencies listed in the package.json file.

By default, containers using this image will execute the npm run start script that we defined within the package.json file. It includes dynamic port configuration to allow you to pass an alternative port to the image.

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

We will use this repository to version the application code and push the changes to a GitHub repository.

Next, download a generic Node.js .gitignore file from GitHub. This will help avoid accidentally committing unnecessary or sensitive files to the repository:

curl -L https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore -o .gitignore

If you don't have an existing GitHub repository to push the code to, create a new one now (opens in a new tab) and then run the following commands to commit and push changes to your GitHub repository:

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

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

Deploy to Koyeb using git-driven deployment

To deploy the Express 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 Express example repository (opens in a new tab) into the Public GitHub repository at the bottom of the page: https://github.com/koyeb/example-expressjs.
  4. For the Builder, select either the buildpack or Dockefile. The application can be built and run using either method.
  5. Name your App and Service, for example express-service.
  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 using a pre-built container

As an alternative to using git-driven deployment, you can deploy a pre-built container from any public or private registry. This can be useful if you need more control over how the build is performed.

To build and push the Docker image to a registry and deploy it on Koyeb, refer to the page on deploying pre-built container images.