How to deploy a Node.js Express app for free
Your Express server runs on localhost:3000. To put it online you need three small changes: the port, the start script, and where secrets live. This guide covers all three, plus MongoDB.
- Listen on
process.env.PORT. - Add
"start": "node server.js"topackage.json, and commitpackage-lock.json. - Move database URLs and keys into environment variables.
- Push to GitHub and deploy on Shipzo. Tests run first if you have them.
Step 1: Listen on the right port
server.js
const express = require('express');
const app = express();
app.use(express.json());
app.get('/', (req, res) => res.send('API is running'));
app.get('/health', (req, res) => res.json({ status: 'ok' }));
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Listening on ${PORT}`));
Hosting platforms assign the port through the PORT variable. Hard-coding app.listen(5000) is the number one reason Express deploys fail their health check.
Step 2: Fix package.json
package.json
{
"name": "my-api",
"version": "1.0.0",
"main": "server.js",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"test": "node --test"
},
"engines": { "node": ">=20" },
"dependencies": {
"express": "^4.21.0",
"mongoose": "^8.7.0"
},
"devDependencies": {
"nodemon": "^3.1.0"
}
}
startusesnode, notnodemon. Nodemon is for development, where it restarts on file changes.- Commit
package-lock.jsonso the server installs exactly the versions you tested. - Every
require()must be listed in dependencies. A package installed globally on your laptop doesn't exist on the server. - Add
node_modules/and.envto.gitignore.
Step 3: Connect MongoDB the right way
mongodb://localhost:27017 only works on your laptop. Create a free cluster on MongoDB Atlas and read the URL from an environment variable:
const mongoose = require('mongoose');
mongoose.connect(process.env.MONGODB_URI)
.then(() => console.log('MongoDB connected'))
.catch((err) => { console.error(err); process.exit(1); });
- In Atlas, under Network Access, allow your host's IP address (or
0.0.0.0/0for testing). Otherwise the connection times out. - In Shipzo, add
MONGODB_URI=mongodb+srv://...under your project's Settings → Environment variables. Values are masked in every log.
Step 4 (optional): Add a test
Node has a built-in test runner. With a test script in place, Shipzo runs it before every deploy and blocks the release if it fails:
test/app.test.js
const test = require('node:test');
const assert = require('node:assert');
test('adds numbers', () => {
assert.strictEqual(1 + 1, 2);
});
Step 5: Push and deploy
git add .
git commit -m "Production ready"
git push
- Create a free Shipzo account → New deployment.
- Paste the repo link, add your environment variables in step 5 of the form, and press Deploy.
Shipzo detects Express from package.json, installs with npm ci, runs npm test, builds a Node 20 container, starts it with npm start, waits for GET / to answer, then switches traffic. Your API is live at https://your-api.shipzo.tech.
Common errors and fixes
| Error | Fix |
|---|---|
| Health check timed out | Use process.env.PORT, or set App port in Settings to the port your app uses. |
Error: Cannot find module 'x' | Add it to dependencies (npm install x) and commit package.json and the lock file. |
MongooseServerSelectionError | Atlas is blocking the server's IP. Update Network Access. |
MONGODB_URI is undefined | Add the variable in Settings and redeploy. |
| Works locally, crashes on the server | Check the runtime logs tab. It's usually a missing environment variable or a file path with different capital letters. |
Deploy it in one click
Paste your GitHub repo into Shipzo. Tests, Docker build, HTTPS and monitoring are handled for you. Free during the beta, no card needed.
Create a free accountFrequently asked questions
Does my API sleep when idle?
No. It keeps running, so the first request after a quiet period is fast.
Can I use Socket.io or WebSockets?
Yes. WebSocket connections are passed through to your app.
Is there a free tier?
Yes. Shipzo is free during the beta, with up to 3 projects per account.
Can I deploy NestJS or Fastify?
Yes. Any Node server with a start script or a server.js/index.js entry file works.