Node.js rakenduse paigaldamise juhend Veebimajutuse jagatud serverisse
Enne alustamist
Selle juhendi lõpuks töötab sinu esimene Node.js rakendus „Ülesanded" aadressil https://sinudomeen.ee ja jääb tööle ka siis, kui sa arvuti kinni paned.
Mida sul vaja on
- Veebimajutuse veebiserveri teenus ja ligipääs iseteenindusele.
- Domeen, mis on sellele teenusele seotud.
- Terminal: macOS-is ja Linuxis programm Terminal, Windowsis PowerShell.
- Tekstiredaktor (nt VS Code). Node.js oma arvutis ei ole kohustuslik.
Tähelepanu: Kui sinu domeenil on juba sait (nt WordPress), asendab selle juhendi samm 5 selle rakendusega. Katseta uue domeeni või alamdomeeniga või vaata lõpus osa „Rakendus alamteel".
Asenda oma väärtustega
Näidetes kasutame alltoodud väärtusi. Leia enda omad iseteeninduse lehelt Veebiserver → SSH kasutajad ja asenda kõikjal.
| Mis | Näites | Kust leiad |
| Domeen | sinudomeen.ee | Sinu domeen |
| SSH-kasutaja | vhost123456ssh | Iseteenindus → Veebiserver → SSH kasutajad |
| Serveri aadress | sinu-server.ee | Samalt lehelt |
| SSH port | 1022 | Samalt lehelt |
| SSH-võtme fail | ~/.ssh/minuvoti | Teed ise (samm 1) |
Sõnastik: mis on mis?
| Mõiste | Lihtsalt öeldes |
| Node.js | Programm, mis laseb JavaScripti käivitada väljaspool brauserit, nt serveris. |
| Express | Node.js teek, mis teeb veebiserveri kirjutamise lihtsaks. |
| SSH | Turvaline viis serveri käsureaga ühenduda. |
| Port | Number, mille kaudu rakendus „kuulab" päringuid, nt 3000. |
| Reverse proxy (suunamine) | Veebimajutuse veebiserver võtab vastu brauseri päringu (ja tegeleb HTTPS-iga) ning edastab selle sinu rakendusele. |
| PM2 | Programm, mis hoiab sinu rakenduse taustal töös ja käivitab selle vea korral uuesti. |
| .env fail | Seadete fail (nt port, paroolid). Ei lähe kunagi Giti. |
Kuidas see kõik kokku käib
Brauser → Veebimajutuse veebiserver (HTTPS) → sisevõrgus HTTP → sinu rakendus (aadressil ELKDATA_APP_IP, pordil 3000) → vastus tagasi brauserisse.
Sinu ülesanne on kolm asja: (1) rakendus kuulab õigel IP-l, (2) port on lisatud portide suunamisse, (3) PM2 hoiab rakenduse töös.
Samm 1. Ühendu serveriga SSH kaudu
1.1 Loo SSH-võti (üks kord)
Võti on turvalisem kui parool. See koosneb kahest failist: privaatne (jääb sulle) ja avalik (läheb serverisse). Käivita oma arvutis:
ssh-keygen -t ed25519
Lisa avalik võti (minuvoti.pub sisu) iseteeninduses Veebiserver → SSH kasutajad. Täpsem juhend: SSH võtme loomine ja selle abil serverisse sisselogimine
Sagedane viga: Ära kunagi saada ega postita faili ilma .pub lõputa. See on sinu privaatne võti.
1.2 Ühendu
ssh -i ~/.ssh/minuvoti -p 1022 vhost123456ssh@sinu-server.ee
Mida see tähendab: -i näitab võtmefaili, -p serveri SSH-porti. Esimesel korral küsib terminal, kas usaldad serveri võtit. Vasta yes.
1.3 Kontrolli, et oled õiges kohas
pwd
node --version
npm --version
echo $ELKDATA_APP_IP
Oodatav tulemus: kodukataloog (nt /home/vhost123456ssh), Node.js 22 või uuem (meie testserveris v24), npm-i versioon ja IP-aadress (meie testis 10.0.10.128).
Näpunäide: Kui echo $ELKDATA_APP_IP jääb tühjaks, oled ühendunud ilma täieliku sisselogimiseta (näiteks käivitasid käsu kujul ssh … "käsk"). Logi sisse tavaliselt (ilma lisakäsuta) või käivita käsk kujul bash -lc "käsk".
Sulge ühendus käsuga exit. Järgmises sammus töötad oma arvutis.
Samm 2. Loo rakendus oma arvutis
Loo kaust ulesanded ja sinna kaheksa faili. Kopeeri sisu täpselt, kaasa arvatud kommentaarid.
ulesanded/
├── package.json
├── server.js
├── ecosystem.config.js
├── .env
├── .gitignore
└── public/
├── index.html
├── style.css
└── app.js
package.json
{
"name": "ulesanded",
"version": "1.0.0",
"private": true,
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"engines": {
"node": ">=22"
},
"dependencies": {
"express": "^5.1.0"
}
}
server.js
Rakenduse süda. Pööra tähelepanu kolmele kohale: trust proxy, API-marsruudid ja viimased read, kus valitakse IP ja port.
// Loe seaded .env failist (sisseehitatud alates Node.js 22-st).
try {
process.loadEnvFile();
} catch {
// .env puudub – pole hullu
}
const path = require('node:path');
const express = require('express');
const app = express();
// Veebimajutuse veebiserver on rakenduse ees vahendaja (reverse proxy).
app.set('trust proxy', 1);
app.use(express.json());
app.use(express.static(path.join(__dirname, 'public')));
// Andmed hoitakse mälus. Pärast taaskäivitust algab nimekiri otsast.
const todos = [{ id: 1, text: 'Paigalda rakendus serverisse', done: false }];
let nextId = 2;
app.get('/api/todos', (req, res) => {
res.json(todos);
});
app.post('/api/todos', (req, res) => {
const text = String(req.body?.text ?? '').trim();
if (!text) {
return res.status(400).json({ error: 'Ülesande tekst puudub' });
}
const todo = { id: nextId++, text, done: false };
todos.push(todo);
res.status(201).json(todo);
});
app.get('/api/health', (req, res) => {
res.json({ status: 'ok', clientIp: req.ip, node: process.version });
});
const host = process.env.ELKDATA_APP_IP;
const port = Number(process.env.PORT) || 3000;
app.listen(port, host, () => {
console.log(`Server listening on ${host ?? 'localhost'}:${port}`);
});
Sagedane viga: Ära kirjuta serveri aadressiks localhost ega 127.0.0.1. Siis veebiserver rakendust ei leia ja brauser näitab 502 Bad Gateway. Kasuta alati process.env.ELKDATA_APP_IP.
public/index.html
<!doctype html>
<html lang="et">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Ülesanded</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<main>
<h1>Ülesanded</h1>
<form id="vorm">
<input id="tekst" placeholder="Uus ülesanne" required>
<button>Lisa</button>
</form>
<ul id="nimekiri"></ul>
</main>
<script src="app.js"></script>
</body>
</html>
public/app.js
const nimekiri = document.getElementById('nimekiri');
const vorm = document.getElementById('vorm');
const tekst = document.getElementById('tekst');
async function laadi() {
const vastus = await fetch('api/todos');
const ulesanded = await vastus.json();
nimekiri.innerHTML = '';
for (const u of ulesanded) {
const li = document.createElement('li');
li.textContent = u.text; // textContent, mitte innerHTML – kaitseb XSS-i eest
nimekiri.append(li);
}
}
vorm.addEventListener('submit', async (e) => {
e.preventDefault();
await fetch('api/todos', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: tekst.value }),
});
tekst.value = '';
laadi();
});
laadi();
public/style.css
body { font-family: system-ui, sans-serif; max-width: 32rem; margin: 3rem auto; padding: 0 1rem; }
form { display: flex; gap: .5rem; }
input { flex: 1; padding: .5rem; }
li { padding: .25rem 0; }
.env
PORT=3000
NODE_ENV=production
.gitignore
node_modules/
.env
.env ei tohiks Giti lisada, sest päris rakendustes hoitakse seal sageli paroole, API võtmeid ja muid salajasi seadistusi. node_modules paigaldatakse serveris uuesti.
ecosystem.config.js
Ütleb PM2-le, mida ja kust käivitada.
module.exports = {
apps: [
{
name: 'ulesanded',
cwd: __dirname,
script: 'server.js',
},
],
};
Soovi korral: proovi oma arvutis
cd ulesanded
npm install
npm start
Ava brauseris http://localhost:3000. Peatamiseks vajuta Ctrl+C. npm install loob faili package-lock.json. Jäta see kausta, siis saad serveris kasutada käsku npm ci.
Samm 3. Laadi kood serverisse
Hoia rakenduse kood väljaspool htdocs kataloogi. htdocs on vaikimisi domeeni avalik documentroot ning rakenduse lähtekoodi, .env faili ja muid serveripoolseid faile pole sinna vaja paigutada.
Variant A. scp (kõige lihtsam)
Kui sa oled rakendust oma arvutis käivitanud, kustuta kõigepealt kaust node_modules. Seejärel loo serveris apps kaust ja lae kood üles. Käivita oma arvutis, kaustas, kus ulesanded asub:
ssh -i ~/.ssh/minuvoti -p 1022 vhost123456ssh@sinu-server.ee "mkdir -p ~/apps"
scp -i ~/.ssh/minuvoti -P 1022 -r ./ulesanded vhost123456ssh@sinu-server.ee:~/apps/
Näpunäide: SSH-s on port väiketähega (-p), scp-s suurtähega (-P). Jälgi seda, et vältida viga.
Kuna scp kopeerib kõik kausta failid, jõuab ka .env serverisse. See sobib, kuna selles on ainult port ja keskkond.
Variant B. Git
cd ~/apps
git clone https://github.com/kasutaja/ulesanded.git
Git-i puhul .env serverisse ei jõua. Loo see serveris:
cd ~/apps/ulesanded
nano .env
kirjuta PORT=3000 ja NODE_ENV=production, salvesta (Ctrl+O, Enter) ja välju (Ctrl+X).
Variant C. SFTP-programm
FileZilla, Cyberduck või WinSCP. Kasuta samu SSH-andmeid ja laadi kaust ulesanded kausta apps.
Kaitse .env faili
Logi serverisse sisse ja piira faili õigusi, et seda saaks lugeda ainult sinu kasutaja:
chmod 600 ~/apps/ulesanded/.env
Samm 4. Paigalda sõltuvused ja testi
Logi serverisse (samm 1.2) ja käivita:
cd ~/apps/ulesanded
npm ci --omit=dev
Kui kausta ei jõudnud package-lock.json, kasuta npm install --omit=dev. --omit=dev jätab arendustööriistad paigaldamata. Käsk peab lõppema veata. npm võib lisaks kuvada sõltuvuste turvahoiatusi; need ei tähenda tingimata, et paigaldamine ebaõnnestus.
Käivita käsitsi, et näha, kas töötab
node server.js
Oodatav väljund (IP võib erineda):
Server listening on 10.0.10.128:3000
Peatamiseks vajuta Ctrl+C. Kui näed localhost, vaata veaotsingut.
Samm 5. Lisa portide suunamine
Nüüd ütled veebiserverile, et domeeni päringud tuleb saata sinu rakendusele.
- Ava iseteeninduses oma domeeni haldus → Veebiserver → Portide suunamine.
-
Vali Domeen: sinudomeen.ee.
-
Jäta Aadressi teekond, Lisa aadressi lõppu kaldkriips ja Rakenduse tee tühjaks.
- Sisesta Port: 3000 (sama, mis failis .env). IP on välja ees juba olemas.
- Kontrolli jaotist Proovi suunamist. Peab olema: https://sinudomeen.ee/ → http://10.0.10.128:3000/.
- Klõpsa Lisa suunamine. Peab tulema roheline teade „Suunamine lisatud".

Tähelepanu: Oota kuni 5 minutit. Muudatus ei jõua kohe kõikjale. Selle ajal võid näha vana saiti või 404 viga. See on normaalne.
HTTPS ja SSL-sertifikaadi eest hoolitseb Veebimajutuse veebiserver. Rakendus ise räägib sisevõrgus tavalist HTTP-d.
Näpunäide: Mitu rakendust samal kontol? Iga rakendus vajab oma porti (3000, 3001, 3002…) vahemikust 1025–65535.
Samm 6. Käivita rakendus PM2-ga
Ilma PM2-ta peatub rakendus, kui SSH-ühendus katkeb.
6.1 Aktiveeri PM2
Iseteenindus → Veebiserver → PM2 ja Node.JS → aktiveeri PM2 (testserveris oli see juba aktiivne).
6.2 Käivita ja salvesta
cd ~/apps/ulesanded
pm2 start ecosystem.config.js
pm2 save
Näpunäide: Esimesel PM2 käivitusel prinditakse suur ASCII-logo ja teade „Spawning PM2 daemon". See on normaalne.
Sagedane viga: pm2 save unustamine. Rakenduse töö ei taastu ilma selleta pärast serveri hooldust.
6.3 Kontrolli
pm2 status
pm2 logs ulesanded --lines 20 --nostream
Rakenduse ulesanded olek peab olema online ja logis peab olema „Server listening on …:3000". PM2 lehel iseteeninduses näed rakendust olekuga „Aktiivne" ning nuppe taaskäivitamiseks, peatamiseks ja kustutamiseks.
Kui muudad rakenduste nimekirja iseteeninduses (start, stop, delete), logi pärast SSH-ga sisse ja tee pm2 save.
Näpunäide: Sa ei pea käivitama pm2 startup. See küsib sudo õigust, mida sul pole. pm2 save on piisav.
Samm 7. Kontrolli internetist
- Ava brauseris https://sinudomeen.ee. Näed lehte „Ülesanded". Lisa ülesanne.
- Ava https://sinudomeen.ee/api/health. Vastus on umbes selline:
{"status":"ok","clientIp":"203.0.113.5","node":"v24.19.0"} - Soovi korral testi API-d käsurealt:
curl https://sinudomeen.ee/api/todos curl -X POST -H "Content-Type: application/json" -d '{"text":"Test"}' https://sinudomeen.ee/api/todos - Vajuta brauseris F12 → Network. Punaseid ebaõnnestunud päringuid ei tohi olla.
Teadmiseks: req.secure jääb Veebimajutuse keskkonnas alati false, sest veebiserver ei edasta rakendusele päist X-Forwarded-Proto. Ära seetõttu kontrolli HTTPS-i koodis (nt secure küpsiste puhul tuleb seda arvestada) ja ära ehita sellele turvareegleid.
7.1 SSL-sertifikaat ja HTTPS
Rakenduse HTTPS-i eest hoolitseb veebiserver. Kui sul pole domeenile veel SSL-sertifikaati või HTTP ei suuna HTTPS-ile, järgi Veebimajutuse abikeskuse juhendeid SSL-sertifikaadi tellimise ja HTTPS-ile suunamise kohta. Mõlemad seadistused asuvad iseteeninduses (Veebiserver → SSL sertifikaat ja Domeen → Domeeni suunamine).
Samm 8. Uuenda rakendust
Pärast koodi muutmist oma arvutis:
-
Laadi muudetud failid serverisse (scp või git pull kaustas ~/apps/ulesanded).
-
Kui muutus package.json või package-lock.json, käivita serveris npm ci --omit=dev.
-
Taaskäivita rakendus ja salvesta:
pm2 restart ulesanded pm2 save
Tähelepanu: Taaskäivitus katkestab rakenduse lühikeseks ajaks. Meie näites on ülesanded mälus, seega kõik lisatud ülesanded kaovad iga taaskäivitusega. Päris rakenduses kasuta andmebaasi.
Näpunäide: pm2 reload ei anna ühe instantsi puhul katkestuseta uuendust. Katkestuseta reload vajab exec_mode: "cluster" seadistust.
Rakendus alamteel (edasijõudnule)
Kui domeenil töötab juba WordPress ja tahad rakenduse aadressile https://sinudomeen.ee/ulesanded/, lisa suunamine teise seadistusega. Koodi muutma ei pea ja kõik muu (sammud 4–8) toimib samamoodi nagu domeeni juure puhul.
| Väli | Väärtus |
| Aadressi teekond | /ulesanded |
| Lisa aadressi lõppu kaldkriips | märgitud |
| Port | 3000 |
| Rakenduse tee | tühi (meie marsruudid algavad juurest) |
Kaldkriips on vajalik, sest leht kasutab suhtelisi linke (style.css). Aadressilt /ulesanded/ laaditakse /ulesanded/style.css, aadressilt /ulesanded aga vale /style.css. Kui valid vale „Rakenduse tee", vastab rakendus 404-ga. Kontrolli alati jaotist „Proovi suunamist".
Veaotsing
Alusta alati kahest käsust: pm2 status näitab, kas rakendus töötab, ja pm2 logs ulesanded --lines 100 näitab, miks mitte.
| Mida näed | Põhjus | Mida teha |
| 502 Bad Gateway | Rakendus ei tööta või kuulab vales kohas | Kontrolli pm2 status ja et logis on Server listening on 10.0.10.128:3000. Port peab olema sama, mis portide suunamises. |
| 404 või vana sait kohe pärast suunamise lisamist | Muudatus pole veel jõudnud levida | Oota kuni 5 minutit. |
| 404 alamtee puhul | Vale „Aadressi teekond" või „Rakenduse tee" | Vaata osa „Rakendus alamteel". |
| pm2 status näitab errored | Rakendus jookseb käivitamisel kokku | Vaata logi. Sageli Cannot find module 'express': tee npm install. |
| Logis localhost:3000 | ELKDATA_APP_IP on tühi | Käivita käsk login-shellis (bash -lc) või logi SSH-ga tavapäraselt. Kui PM2 all on ikka tühi, võta ühendust klienditoega. |
| EADDRINUSE | Port on juba kasutusel (sageli rakenduse vana koopia) | pm2 status, siis pm2 delete <vana> ja pm2 save. Või vali teine port. |
| EADDRNOTAVAIL | Rakendus kuulab IP-l, mis ei ole sinu oma | Kasuta process.env.ELKDATA_APP_IP, ära kirjuta IP-d koodi. |
| Leht ilma stiilideta | Valed suhtelised lingid | Vaata „Rakendus alamteel". |
| Rakendus kadus pärast serveri hooldust | pm2 save jäi tegemata | pm2 start ecosystem.config.js ja pm2 save. |
| Ülesanded kadusid | Andmed on mälus | Normaalne taaskäivituse järel. Kasuta andmebaasi |
| Ketas täis | PM2 logid kasvavad | pm2 flush ulesanded. Pikemas plaanis pm2 install pm2-logrotate. |
Kontroll-loend
☐ SSH-ühendus töötab ja echo $ELKDATA_APP_IP näitab IP-d
☐ Kood on kaustas ~/apps/ulesanded, mitte htdocs
☐ .env on serveris olemas, õigused 600, Gitis seda ei ole
☐ npm ci --omit=dev (või npm install) lõppes veata
☐ Käsitsi käivitades on logis Server listening on 10.0.10.128:3000
☐ Portide suunamine on lisatud ja „Proovi suunamist" näitab õiget sihtkohta
☐ Ootasid kuni 5 minutit
☐ pm2 status näitab online ja pm2 save on tehtud
☐ SSL sertifikaat on paigaldatud ja HTTP suunab HTTPS-ile (vt SSL-i ja HTTPS-i juhendeid)
☐ https://sinudomeen.ee avaneb ja /api/health näitab sinu clientIp-d
PM2 käskude spikker
| Käsk | Mida teeb | Pärast pm2 save? |
| pm2 start ecosystem.config.js | Käivitab rakenduse | Jah |
| pm2 status | Näitab rakendusi ja olekut | - |
| pm2 logs ulesanded --lines 100 | Näitab viimast 100 logirida | - |
| pm2 restart ulesanded | Taaskäivitab (lühike katkestus) | Soovitatav |
| pm2 reload ulesanded | Sama, mis restart fork-režiimis | Soovitatav |
| pm2 stop ulesanded | Peatab rakenduse | Jah |
| pm2 delete ulesanded | Eemaldab PM2-st | Jah |
| pm2 flush ulesanded | Tühjendab logid | - |
| pm2 save | Salvestab töötavate protsesside nimekirja | - |
Vaata ka
➪ SSH võtme loomine ja selle abil serverisse sisselogimine
➪ SSH konto abil vealogi jälgimine
➪ SSH konto abil andmete varundamine
➪ PM2 protsessihaldur Veebimajutuse serveris
➪ Portide suunamine Veebimajutuse serveris