Підготуйте невелике контрольоване середовище
Ця процедура орієнтована на систему Linux із systemd, адміністративним обліковим записом, уже встановленим середовищем виконання Node.js 24 LTS, curl і пакетною системною службою Caddy. Спершу підтвердьте встановлені версії та шляхи пакетів; сторінка релізів Node визначає підтримувані лінії релізів. Встановлення та підготовка постачальником — це окремі завдання. Використовуйте машину, яку ви контролюєте, і тримайте напоготові перевірену сесію SSH та шлях відновлення. Назви first-api та /opt/first-api мають бути невикористаними перед створенням цього прикладу.
Для HTTPS вам також потрібен домен, який ви контролюєте, правильні записи A/AAAA та дозвіл на відкриття веб-трафіку. api.example.com нижче — зарезервований приклад: замініть його на власне ім'я хоста. Цей API навмисно не містить бази даних, автентифікації чи даних клієнтів. Він демонструє повторюваний процес, а не повний продукт чи перевірене розгортання OffVPS.
Перевірте середовище виконання та створіть один реліз
command -v node &&
readlink -f "$(command -v node)" &&
node --version
Решта прикладу припускає, що перевірений спільний виконуваний файл — це /usr/bin/node. Якщо у вас інший, замініть цей шлях у кожній перевірці та в ExecStart. Середовище виконання в приватному домашньому каталозі вашого користувача входу не стає автоматично доступним для системної служби. Створіть обліковий запис служби та каталог релізів, що належить root, зупинившись, якщо виявлено неочікуваний наявний обліковий запис або шлях.
sudo useradd --system --user-group --home-dir /opt/first-api \
--shell /usr/sbin/nologin first-api &&
sudo install -d -o root -g root -m 0755 /opt/first-api/releases/001
Використовуючи свій редактор з адміністративним доступом, збережіть наступне як /opt/first-api/releases/001/server.mjs, що належить root і читається користувачем служби. Реліз містить лише цей файл; немає залежностей пакетів чи секретів.
import http from 'node:http';
const port = Number(process.env.PORT || 3000);
if (!Number.isInteger(port) || port < 1024 || port > 65535) {
throw new Error('PORT must be an integer from 1024 to 65535');
}
const server = http.createServer((req, res) => {
res.setHeader('Content-Type', 'application/json; charset=utf-8');
res.setHeader('Cache-Control', 'no-store');
if (req.method !== 'GET') {
res.writeHead(405, { Allow: 'GET' });
res.end(JSON.stringify({ error: 'method_not_allowed' }));
return;
}
if (req.url === '/healthz') {
res.writeHead(200);
res.end(JSON.stringify({ status: 'ok', release: '001' }));
} else if (req.url === '/api/message') {
res.writeHead(200);
res.end(JSON.stringify({ message: 'A small app, running clearly.' }));
} else {
res.writeHead(404);
res.end(JSON.stringify({ error: 'not_found' }));
}
});
server.requestTimeout = 10000;
server.headersTimeout = 10000;
server.keepAliveTimeout = 5000;
server.listen(port, '127.0.0.1');
process.on('SIGTERM', () => {
server.close(() => process.exit(0));
setTimeout(() => process.exit(1), 10000).unref();
});
Явна адреса loopback утримує слухач API на самому сервері. Caddy буде його публічною точкою входу. HTTP API Node документує обробку запитів, тайм-аути та завершення роботи сервера. Перевірте файл від імені облікового запису, який фактично його виконуватиме:
sudo -u first-api /usr/bin/node --check /opt/first-api/releases/001/server.mjs
Надайте процесу визначення служби
Збережіть /etc/systemd/system/first-api.service з таким вмістом:
[Unit]
Description=First API learning release
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=5
[Service]
Type=simple
User=first-api
Group=first-api
WorkingDirectory=/opt/first-api/releases/001
ExecStart=/usr/bin/node /opt/first-api/releases/001/server.mjs
Environment=NODE_ENV=production
Environment=PORT=3000
Restart=on-failure
RestartSec=5
TimeoutStopSec=15
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
[Install]
WantedBy=multi-user.target
Модуль використовує одного виділеного користувача, явний виконуваний файл і версіонований робочий каталог. Автоматичне відновлення обмежене за частотою; навмисна зупинка служби не запускає Restart=on-failure. Див. systemd.service. Обмеження файлової системи підходять для цього API лише для читання; застосунок, який записує дані, потребує навмисно обмеженого доступного для запису сховища. Секрети не належать до цих рядків середовища. Див. налаштування виконання systemd.
sudo systemd-analyze verify /etc/systemd/system/first-api.service &&
sudo systemctl daemon-reload &&
sudo systemctl start first-api.service &&
sudo systemctl status first-api.service --no-pager &&
curl --fail --show-error http://127.0.0.1:3000/healthz
The && запобіжники зупиняють вставлену послідовність, коли команда зазнає збою. Розв'яжіть попередження перевірки перед запуском і не переходьте до наступного блоку після невдалої перевірки. Перевірка модуля може виявити синтаксичні проблеми та проблеми з виконуваним файлом, але успішна перевірка не є доказом працюючого застосунку. Очікувана відповідь перевірки стану — {"status":"ok","release":"001"}. Якщо вона не проходить, огляньте sudo journalctl -u first-api.service -n 50 --no-pager перш ніж повторно перезапускати.
Додайте маршрут HTTPS після локальної перевірки
Створіть резервну копію наявної конфігурації Caddy під невикористаним ім'ям файлу. Додайте цей блок до /etc/caddy/Caddyfile не замінюючи непов'язані сайти:
api.example.com {
reverse_proxy 127.0.0.1:3000
}
Для стандартного потоку з публічним доменом ім'я хоста має розв'язуватися на сервер, порти 80/443 мають досягати Caddy, а сховище сертифікатів Caddy має залишатися доступним для запису та постійним. Перевірте кожен опублікований маршрут A/AAAA. Залиште доступ SSH незмінним і тримайте порт 3000 приватним. Ці вимоги походять з Автоматичний HTTPS Caddy; синтаксис upstream задокументовано в reverse_proxy.
sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile &&
sudo systemctl reload caddy.service
Перезавантажуйте лише після успішної перевірки; caddy validate перевіряє адаптовану конфігурацію. Робочий процес пакетної служби описано в посібнику зі служби Caddy. З окремого клієнта запитайте https://api.example.com/healthz використовуючи ваше справжнє ім'я хоста. Очікуйте довірене TLS-з'єднання та ту саму відповідь релізу, не обходячи перевірки сертифіката. Потім перевірте, що /api/message повертає своє повідомлення, а невідомий шлях повертає 404.
Збережіть відомий реліз і безпечну точку зупинки
Після того як обидві перевірки працюють, увімкніть API для майбутніх завантажень за допомогою sudo systemctl enable first-api.service. Запишіть версію середовища виконання, вихідний файл, модуль і конфігурацію Caddy. Для наступного релізу створіть новий пронумерований каталог, перевірте його синтаксис від імені користувача служби, оновіть обидва шляхи модуля, перезавантажте systemd і перезапустіть API. Тримайте попередній каталог, доки новий реліз не буде прийнято.
Щоб зупинити цей приклад, використайте sudo systemctl stop first-api.service. Caddy повідомлятиме про збій upstream, поки цей маршрут залишається налаштованим; видаліть лише цей маршрут і перевірте/перезавантажте Caddy, коли виводите його з експлуатації. Відкатіть невдалий реліз коду, вибравши попередні шляхи модуля та повторивши перевірки. Пізніша міграція бази даних потребує власного плану відновлення. Продовжте з шлях запиту від DNS до застосунку або з'ясування, чому застосунок зупинився.
Використана документація
Основні посилання для цієї сторінки. Перевірте документацію для версії, встановленої у вашому середовищі.