OffVPSVPS OFFSHORESoporte

Desplegar una app

Dale a tu primera API una release repetible.

Fai funzionare una piccola API localmente, rendi il suo processo ripristinabile, e solo allora collega il suo nome host e HTTPS. Mantieni esplicito il percorso di rilascio e la via di ritorno.

Guida sul campo OffVPS · Revisionato · 5 min di lettura

Prepara un ambiente piccolo e controllato

Questa procedura è destinata a un sistema Linux con systemd, un account amministratore, un runtime Node.js 24 LTS già installato, curl e il servizio system pacchettizzato di Caddy. Conferma prima le versioni installate e i percorsi dei pacchetti; la pagina dei rilasci di Node identifica le linee di rilascio supportate. Installazione e provisioning del provider sono attività separate. Usa una macchina che controlli e mantieni disponibile una sessione SSH testata e un percorso di ripristino. I nomi first-api y /opt/first-api devono essere inutilizzati prima di creare questo esempio.

Per HTTPS hai anche bisogno di un dominio che controlli, record A/AAAA corretti e permesso di esporre il traffico web. api.example.com sotto è un esempio riservato: sostituiscilo con il tuo nome host. Questa API deliberatamente non contiene database, autenticazione o dati dei clienti. Dimostra un processo ripetibile, non un prodotto completo o una distribuzione OffVPS testata.

Verifica il runtime e crea un rilascio

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

Il resto dell'esempio presuppone che l'eseguibile condiviso verificato sia /usr/bin/node. Se il tuo differisce, sostituisci quel percorso in ogni controllo e in ExecStart. Un runtime nella home privata del tuo utente di login non è automaticamente disponibile per un servizio di sistema. Crea l'account di servizio e una directory di rilascio di proprietà di root, fermandoti se viene trovato un account o percorso esistente inatteso.

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

Usando il tuo editor con accesso amministrativo, salva quanto segue come /opt/first-api/releases/001/server.mjs, di proprietà di root e leggibile dall'utente del servizio. Il rilascio contiene solo questo file; non ci sono dipendenze di pacchetto o segreti.

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

L'indirizzo di loopback esplicito mantiene il listener dell'API sul server stesso. Caddy sarà il suo punto di ingresso pubblico. Il API HTTP Node documenta la gestione delle richieste, i timeout e lo spegnimento del server. Controlla il file come l'account che lo eseguirà effettivamente:

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

Assegna al processo una definizione di servizio

Salva /etc/systemd/system/first-api.service con questo contenuto:

[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

L'unità usa un utente dedicato, un eseguibile esplicito e una directory di lavoro con versione. Il ripristino automatico è limitato in frequenza; un arresto intenzionale del servizio non attiva Restart=on-failure. Vedi systemd.service. Le restrizioni del filesystem si adattano a questa API di sola lettura; un'applicazione che scrive dati necessita di archiviazione scrivibile con ambito deliberato. I segreti non appartengono a queste righe di ambiente. Vedi impostazioni di esecuzione di 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

El && le protezioni fermano la sequenza incollata quando un comando fallisce. Risolvi gli avvisi di validazione prima di avviare, e non continuare al blocco successivo dopo un controllo fallito. Verifica dell'unità può individuare problemi di sintassi ed eseguibile, ma un controllo riuscito non è prova di un'applicazione funzionante. La risposta di health prevista è {"status":"ok","release":"001"}. Se fallisce, ispeziona sudo journalctl -u first-api.service -n 50 --no-pager prima di riavviare ripetutamente.

Aggiungi la rotta HTTPS dopo il controllo locale

Esegui il backup della configurazione Caddy esistente con un nome file inutilizzato. Aggiungi questo blocco a /etc/caddy/Caddyfile senza sostituire siti non correlati:

api.example.com {
    reverse_proxy 127.0.0.1:3000
}

Per il flusso standard con dominio pubblico, il nome host deve risolvere al server, le porte 80/443 devono raggiungere Caddy, e l'archiviazione dei certificati di Caddy deve rimanere scrivibile e persistente. Controlla ogni rotta A/AAAA pubblicata. Lascia intatto l'accesso SSH e mantieni privata la porta 3000. Questi requisiti provengono da HTTPS automatico di Caddy; la sintassi upstream è documentata in reverse_proxy.

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

Ricarica solo dopo una validazione riuscita; caddy validate controlla la configurazione adattata. Il flusso di lavoro del servizio pacchettizzato è descritto in guida al servizio di Caddy. Da un client separato, richiedi https://api.example.com/healthz usando il tuo nome host reale. Aspettati una connessione TLS affidabile e la stessa risposta di rilascio, senza aggirare i controlli del certificato. Poi verifica /api/message restituisce il suo messaggio e un percorso sconosciuto restituisce 404.

Conserva un rilascio noto e un punto di arresto sicuro

Dopo che entrambi i controlli funzionano, abilita l'API per i prossimi avvii con sudo systemctl enable first-api.service. Registra la versione del runtime, il file sorgente, l'unità e la configurazione di Caddy. Per il rilascio successivo, crea una nuova directory numerata, controllane la sintassi come utente del servizio, aggiorna entrambi i percorsi dell'unità, ricarica systemd e riavvia l'API. Mantieni la directory precedente fino a quando il nuovo rilascio è accettato.

Per fermare questo esempio, usa sudo systemctl stop first-api.service. Caddy segnalerà un errore upstream finché quella rotta rimane configurata; rimuovi solo questa rotta e valida/ricarica Caddy quando la ritiri. Esegui il rollback di un rilascio di codice fallito selezionando i percorsi dell'unità precedenti e ripetendo i controlli. Una successiva migrazione del database necessita del proprio piano di ripristino. Continua con il percorso di richiesta dal DNS all'applicazione или trovare perché un'app si è fermata.

使用的文档

本页的主要参考。请核对您自己环境中安装版本对应的文档。