OffVPSOFFSHORE VPSWsparcie

Wdrażanie aplikacji

Zapewnij pierwszemu API powtarzalne wydanie.

Spraw, aby jedno małe API działało lokalnie, aby jego proces był odtwarzalny, a dopiero potem połącz jego nazwę hosta i HTTPS. Utrzymuj jawną ścieżkę wydania i drogę powrotu.

Przewodnik terenowy OffVPS · Zweryfikowano · 5 min czytania

Przygotuj małe, kontrolowane środowisko

Ta procedura dotyczy systemu Linux z systemd, konta administratora, już zainstalowanego środowiska uruchomieniowego Node.js 24 LTS, curl oraz usługi systemowej Caddy'ego z pakietu. Najpierw potwierdź zainstalowane wersje i ścieżki pakietów; strona wydań Node'a wskazuje obsługiwane linie wydań. Instalacja i udostępnianie u dostawcy to osobne zadania. Użyj maszyny, którą kontrolujesz, i utrzymuj przetestowaną sesję SSH oraz ścieżkę odzyskiwania. Nazwy first-api oraz /opt/first-api muszą być nieużywane przed utworzeniem tego przykładu.

Dla HTTPS potrzebujesz także domeny, którą kontrolujesz, poprawnych rekordów A/AAAA i uprawnień do wystawienia ruchu webowego. api.example.com poniżej jest zarezerwowanym przykładem: zastąp go własną nazwą hosta. To API celowo nie zawiera bazy danych, uwierzytelniania ani danych klientów. Demonstruje powtarzalny proces, a nie kompletny produkt ani przetestowane wdrożenie OffVPS.

Zweryfikuj środowisko uruchomieniowe i utwórz jedno wydanie

command -v node &&
readlink -f "$(command -v node)" &&
node --version

Reszta przykładu zakłada, że zweryfikowany wspólny plik wykonywalny to /usr/bin/node. Jeśli Twój się różni, zastąp tę ścieżkę w każdej kontroli oraz w ExecStart. Środowisko uruchomieniowe wewnątrz prywatnego katalogu domowego Twojego użytkownika logowania nie jest automatycznie dostępne dla usługi systemowej. Utwórz konto usługi i katalog wydania należący do roota, zatrzymując się, jeśli zostanie znalezione nieoczekiwane istniejące konto lub ścieżka.

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

Używając swojego edytora z dostępem administracyjnym, zapisz poniższą treść jako /opt/first-api/releases/001/server.mjs, należący do roota i czytelny dla użytkownika usługi. Wydanie zawiera tylko ten plik; nie ma zależności pakietów ani sekretów.

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();
});

Jawny adres loopback utrzymuje nasłuch API na samym serwerze. Caddy będzie jego publicznym punktem wejścia. API HTTP Node'a dokumentuje obsługę żądań, przekroczenia czasu i zamykanie serwera. Sprawdź plik jako konto, które faktycznie go uruchomi:

sudo -u first-api /usr/bin/node --check /opt/first-api/releases/001/server.mjs

Nadaj procesowi definicję usługi

Zapisz /etc/systemd/system/first-api.service z tą treścią:

[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

Jednostka używa jednego dedykowanego użytkownika, jawnego pliku wykonywalnego i wersjonowanego katalogu roboczego. Automatyczne odtwarzanie jest ograniczane szybkościowo; celowe zatrzymanie usługi nie wyzwala Restart=on-failure. Zobacz systemd.service. Ograniczenia systemu plików pasują do tego API tylko do odczytu; aplikacja, która zapisuje dane, wymaga celowo ograniczonego zapisywalnego magazynu. Sekrety nie należą do tych linii środowiskowych. Zobacz ustawienia wykonawcze 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

Ten && zabezpieczenia zatrzymują wklejoną sekwencję, gdy polecenie zawiedzie. Rozwiąż ostrzeżenia walidacji przed uruchomieniem i nie przechodź do następnego bloku po nieudanej kontroli. Weryfikacja jednostki może wychwycić problemy ze składnią i plikiem wykonywalnym, ale pomyślna kontrola nie jest dowodem działającej aplikacji. Oczekiwana odpowiedź zdrowia to {"status":"ok","release":"001"}. Jeśli zawiedzie, sprawdź sudo journalctl -u first-api.service -n 50 --no-pager przed wielokrotnym restartowaniem.

Dodaj trasę HTTPS po lokalnej kontroli

Zrób kopię zapasową istniejącej konfiguracji Caddy'ego pod nieużywaną nazwą pliku. Dodaj ten blok do /etc/caddy/Caddyfile bez zastępowania niepowiązanych witryn:

api.example.com {
    reverse_proxy 127.0.0.1:3000
}

W standardowym przepływie dla domeny publicznej nazwa hosta musi rozwiązywać się do serwera, porty 80/443 muszą docierać do Caddy'ego, a magazyn certyfikatów Caddy'ego musi pozostać zapisywalny i trwały. Sprawdź każdą opublikowaną trasę A/AAAA. Pozostaw dostęp SSH nienaruszony i trzymaj port 3000 prywatny. Te wymagania pochodzą z Automatyczny HTTPS Caddy'ego; składnia upstreamu jest udokumentowana w reverse_proxy.

sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile &&
sudo systemctl reload caddy.service

Przeładuj tylko po pomyślnej walidacji; caddy validate sprawdza zaadaptowaną konfigurację. Przepływ pracy usługi z pakietu opisano w przewodniku usługi Caddy'ego. Z osobnego klienta zażądaj https://api.example.com/healthz używając swojej prawdziwej nazwy hosta. Oczekuj zaufanego połączenia TLS i tej samej odpowiedzi wydania, bez omijania kontroli certyfikatów. Następnie zweryfikuj, że /api/message zwraca swój komunikat, a nieznana ścieżka zwraca 404.

Zachowaj znane wydanie i bezpieczny punkt zatrzymania

Po tym, jak obie kontrole zadziałają, włącz API dla przyszłych rozruchów za pomocą sudo systemctl enable first-api.service. Zapisz wersję środowiska uruchomieniowego, plik źródłowy, jednostkę i konfigurację Caddy'ego. W następnym wydaniu utwórz nowy numerowany katalog, sprawdź składnię jako użytkownik usługi, zaktualizuj obie ścieżki jednostki, przeładuj systemd i zrestartuj API. Zachowaj poprzedni katalog, dopóki nowe wydanie nie zostanie zaakceptowane.

Aby zatrzymać ten przykład, użyj sudo systemctl stop first-api.service. Caddy zgłosi awarię upstreamu, dopóki ta trasa pozostaje skonfigurowana; usuń tylko tę trasę i zwaliduj/przeładuj Caddy'ego przy jej wycofywaniu. Wycofaj nieudane wydanie kodu, wybierając poprzednie ścieżki jednostki i powtarzając kontrole. Późniejsza migracja bazy danych wymaga własnego planu odzyskiwania. Kontynuuj z ścieżką żądania od DNS do aplikacji lub znajdowaniem przyczyny zatrzymania aplikacji.

Wykorzystana dokumentacja

Główne źródła dla tej strony. Sprawdź dokumentację wersji zainstalowanej we własnym środowisku.