Deploy an Express App
This guide explains how to deploy an Express (opens in a new tab) application to Koyeb using:
- Git-driven deployment to automatically build and deploy a new version of your application each time a change is detected on your branch.
- Pre-built containers you can deploy from any public or private registry.
You will need:
- A Koyeb account (opens in a new tab) - it's free to get started!
- Node.js (opens in a new tab) installed on your local machine
- (Optional) Docker (opens in a new tab) if you are planning on building and testing a container image for the application locally
- (Optional) The Koyeb CLI for deployment from the terminal
You can deploy and preview the Express application from this guide by clicking the Deploy to Koyeb button:
Consult the repository on GitHub (opens in a new tab) to view this example application.
Create the Express app
Get started by creating a basic Express application.
Alternatively, you can fork the repository on GitHub (opens in a new tab) to get a complete copy of the code. If you fork the repository, then you can skip to section on git-driven deployment on Koyeb.
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
Initialize a new Node.js project:
npm init
When prompted for project details, can press ENTER to accept the suggested defaults, with the exception of the entry point. When prompted for the entry point, type in app.js
.
Install Express to your project:
npm install express
Create a new file called app.js
at the root of the project. Add the following code to the file:
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 application code 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 the application locally using the following command:
node app.js
Visit http://localhost:3000
in your browser to see the following response:
{ "message": "Hello, world!" }
Stop the server when you are finished by pressing CTRL-C.
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 listen on port 8000 (http://localhost:8000
) instead of the default 3000.
Add a start script
Open the package.json
file in your editor. In the scripts
object, add a start
script:
{
"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 runs the application using npm run start
, which is what Koyeb's Node.js buildpack executes by default when running Node.js applications.
Try out the npm run start
command:
npm run start
This runs the application at http://localhost:3000
just like our node app.js
command.
Stop the app and run an alternative port by typing:
PORT=8000 npm run start
This runs the application at http://localhost:8000
just like our PORT=8000 node app.js
command.
This example application runs 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:
.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:
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 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.
You can also build the Dockerfile (directly from the repository when deploying)[#deploy-to-koyeb-using-git-driven-deployment], which is useful as a way of automatically deploying when changes occur.
Push the project to GitHub
In the project directory, initialize a new git repository by running the following command:
git init
You will use this repository to version the application code and push the changes to a GitHub repository.
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
Run the following commands to commit and push changes to your GitHub repository, replacing the GitHub username and repository name with values from your account and the GitHub repo 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
Replace <YOUR_GITHUB_USERNAME>/<YOUR_REPOSITORY_NAME>
with your GitHub username and repository name.
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:
- Click Create Web Service on the Overview tab of the Koyeb control panel, and select Web Service.
- Select GitHub as the deployment option.
- 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:
https://github.com/koyeb/example-expressjs
. - From the Build options, select either the buildpack or Dockerfile. Choose buildpack if you did not create a Dockerfile for your project.
- Choose a CPU for your Service. The default Nano works well for this project.
- Click the Deploy button.
This creates a Koyeb App and Service which builds and deploys your application on Koyeb. You can 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.
What's next
For more examples of Express applications deployed on Koyeb, check out these tutorials:
- Build and Run a Web App using Turso, Drizzle ORM, and Express on Koyeb (opens in a new tab)
- Using WebSockets with Socket.io and Node.js on Koyeb (opens in a new tab)
- Deploy a Web Scraper using Puppeteer, Node.js and Docker on Koyeb (opens in a new tab)
To learn more about the features available for your apps, check out the following documentation:
- Autoscaling (opens in a new tab) - Dynamically adjust the number of Instances within a Service to meet the demand of your applications.
- Scale-to-Zero (opens in a new tab) - Configure your Instances to automatically scale down to zero when there is no incoming traffic, reducing usage.
- Metrics (opens in a new tab) - Learn how to monitor your Services usage.