We offer you a grace period for 3 days to use VDS to check your projects.
A small Express app that:
Ideal for rapid prototyping, testing, and lightweight landing pages or mini-apps
my-express-app/ |-- package.json |-- app.js |-- .env (optional, for local development) |-- public/ | `-- style.css `-- views/ `-- index.html
The public and views folders can be renamed; this is configurable in the code.
{ "name": "my-express-app", "version": "1.0.0", "description": "Simple Express server for shared hosting (ISPmanager).", "main": "app.js", "scripts": { "start": "node app.js", "start:prod": "NODE_ENV=production node app.js" }, "engines": { "node": ">=18.x" }, "dependencies": { "express": "^4.19.2", "morgan": "^1.10.0" } }
// app.js const express = require('express'); const path = require('path'); const morgan = require('morgan'); const app = express(); // 1) Port: on shared hosting it’s set by the panel (PORT environment variable)) const PORT = process.env.PORT || 3000; // 2) Request logging (useful for debugging) app.use(morgan(process.env.NODE_ENV === 'production' ? 'combined' : 'dev')); // 3) Serve static files from /public app.use(express.static(path.join(__dirname, 'public'))); // 4) Home page (simple HTML from /views/index.html) app.get('/', (req, res) => { res.sendFile(path.join(__dirname, 'views', 'index.html')); }); // 5) Health check for monitoring app.get('/health', (req, res) => { res.status(200).json({ status: 'ok', uptime: process.uptime() }); }); // 6) 404 — not found (no matching route) app.use((req, res, next) => { res.status(404).send('404 Not Found'); }); // 7) 500 — basic error handler app.use((err, req, res, next) => { console.error('Unhandled error:', err); res.status(500).send('500 Internal Server Error'); }); // 8) Start the server app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });
<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Express on shared hosting</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link href="/style.css" rel="stylesheet" /> </head> <body> <main> <h1>Express is running</h1> <p>A minimal Node.js (Express) server for shared hosting.</p> <ul> <li>Home: <code>/</code></li> <li>Health: <code>/health</code></li> <li>Static: <code>/public</code> (mounted at <code>/style.css</code>)</li> </ul> </main> </body> </html>
html, body { margin: 0; padding: 0; font: 16px/1.5 system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; background: #0f172a; color: #e2e8f0; } main { max-width: 720px; margin: 12vh auto; padding: 24px; background: #111827; border-radius: 16px; box-shadow: 0 10px 30px rgba(0,0,0,.25); } h1 { margin-top: 0; font-size: 28px; } code { background: #1f2937; padding: 2px 6px; border-radius: 6px; }
In production the port is set by the panel; locally, do this:
PORT=3000 NODE_ENV=development
In ISPmanager, .env is usually not required. Make sure you don’t commit secrets.
If the panel asks you to specify the port manually, set e.g. 8080, but your code should listen on process.env.PORT (the panel proxies to that port).
The app listens on process.env.PORT Static files are served from public/. A /health endpoint is available for status checks. Handles 404 and 500 errors. HTTPS is enabled (Let’s Encrypt).