# Node.js-API hosten, ohne Server zu verwalten

> Eine Node.js-API als Docker-Image ohne Root auf Port 8080 verpacken, auf Docker Hub hochladen und auf blitz.cloud in der EU mit HTTPS hosten.

Web page: https://blitz.cloud/de/guides/deploy-nodejs-api/
Updated: 2026-09-26

Um eine Node.js-API auf blitz.cloud zu hosten, ohne einen Server zu verwalten, packst du sie in ein kleines Docker-Image, das auf Port 8080 lauscht und als normaler Benutzer läuft, lädst das Image auf Docker Hub hoch und wählst es im blitz.cloud-Dashboard aus. blitz.cloud startet es in einer eigenen Sandbox unter einer HTTPS-Adresse und startet es neu, wenn der Prozess abstürzt. Keine VM, keine nginx-Konfiguration, keine Zertifikate zum Erneuern.

Der Code in dieser Anleitung ist das [node-api-Beispiel](https://github.com/blitzworks-io/blitz-cloud-examples/tree/main/node-api). Es nutzt Nodes eingebautes `http`-Modul, du musst also nichts außer Node selbst kennen. Eine Express- oder Fastify-App funktioniert genauso.

## Der Server

Zwei Details sorgen dafür, dass sich eine Node-App auf blitz.cloud gut verhält. Sie liest ihren Port aus der Umgebung, mit 8080 als Standard, und sie beendet sich sauber, wenn sie `SIGTERM` bekommt. So wird ein Container bei einem Neustart gebeten, sich herunterzufahren.

```javascript
import http from "node:http";

const port = Number(process.env.PORT ?? 8080);

const server = http.createServer((req, res) => {
  if (req.url === "/healthz") {
    res.writeHead(200, { "content-type": "application/json" });
    return res.end(JSON.stringify({ ok: true }));
  }
  res.writeHead(200, { "content-type": "application/json" });
  res.end(JSON.stringify({ hello: "from blitz.cloud" }));
});

server.listen(port, () => console.log(`listening on :${port}`));

process.on("SIGTERM", () => server.close(() => process.exit(0)));
```

Die vollständige Version im Repository spricht zusätzlich mit PostgreSQL, wenn `DATABASE_URL` gesetzt ist. Dieser Teil steht in [Eine App mit PostgreSQL-Datenbank ausrollen](https://blitz.cloud/de/guides/deploy-app-with-postgres/).

## Das Dockerfile

```dockerfile
# Install dependencies in a throwaway stage so the final image has no npm cache.
FROM node:22.23.2-alpine3.24 AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev

FROM node:22.23.2-alpine3.24
ENV NODE_ENV=production PORT=8080
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY package.json ./
COPY src ./src
# The official Node image ships a "node" user with uid 1000, the same uid
# blitz.cloud runs every app as.
USER node
EXPOSE 8080
CMD ["node", "src/server.js"]
```

`EXPOSE 8080` ist hier keine Dekoration. blitz.cloud liest die Ports, die ein Image angibt, und nimmt diesen, du musst also nirgends einen Port eintippen.

Auch wichtig: direkt mit `node` starten statt mit `npm start`. npm reicht `SIGTERM` nicht zuverlässig weiter, und dein Shutdown-Handler würde nie laufen.

## So testen, wie blitz.cloud es startet

```bash
docker build --platform linux/amd64 -t blitz-example-node-api .
docker run --rm --user 1000:1000 --cap-drop ALL --security-opt no-new-privileges \
  -p 8080:8080 blitz-example-node-api
```

```bash
curl http://localhost:8080/
# {"hello":"from blitz.cloud","database":"none"}
```

Als wir genau das ausgeführt haben, antworteten `/` und `/healthz` mit `200`. Wenn deine eigene App an dieser Stelle scheitert, scheitert sie auch auf blitz.cloud, und auf deinem Laptop ist der Fehler leichter zu lesen.

## Auf Docker Hub hochladen

```bash
docker build --platform linux/amd64 -t yourname/blitz-example-node-api:1.0.0 -t yourname/blitz-example-node-api:latest .
docker login
docker push --all-tags yourname/blitz-example-node-api
```

Das Repository muss öffentlich sein. Der Assistent durchsucht Docker Hub; ein öffentliches Image auf ghcr.io oder Quay klappt auch, wenn du den vollen Namen eintippst. Tagge jeden Build zweimal, mit einer Version wie `1.0.0` und mit `latest`: Die Version zeigt dir, welcher Build welcher ist, und auf `latest` baut der Weg mit dem Neustart weiter unten auf.

Wenn du nicht von deinem Laptop hochladen willst: Das Beispiel-Repository hat einen [GitHub-Actions-Workflow](https://github.com/blitzworks-io/blitz-cloud-examples/blob/main/.github/workflows/docker-publish.yml), der für amd64 baut und bei jedem Commit auf `main` hochlädt, sobald du in deinem Fork `DOCKERHUB_USERNAME` und `DOCKERHUB_TOKEN` als Secrets hinterlegst.

## Auf blitz.cloud ausrollen

1. Klicke im [Dashboard](https://dashboard.blitz.cloud/) auf "Host something new" (Neues hosten) und wähle "An app from Docker Hub" (eine App von Docker Hub).
2. Suche nach `yourname/blitz-example-node-api`, wähle `latest` und klicke auf "Continue" (warum, steht weiter unten beim Ausliefern neuer Versionen). Ein gerade hochgeladenes Repository kann eine Weile brauchen, bis es in der Docker-Hub-Suche auftaucht.
3. Unter "What this app needs" sollte Port 8080 stehen, "the one the app itself declares".
4. Gib einen Namen und eine Adresse wie `notes` ein und klicke auf "Put it online".

Deine API ist dann unter `https://notes.yourname.blitz.cloud` erreichbar.

## Konfiguration und Secrets

Einstellungen gehören in den Tab "Environment" der App. Die Werte werden verschlüsselt gespeichert, auf dem Bildschirm maskiert und kommen beim nächsten Neustart bei der App an: Wert ändern, dann neu starten. Bis zu 64 Einstellungen pro App.

## Eine neue Version ausliefern

Roll den Tag `latest` aus und lade bei einem Release ein neues `latest` hoch. Für einen Tag, der sich bewegt, sind automatische Updates von Anfang an eingeschaltet: Jede Nacht gegen 4:00 UTC schaut blitz.cloud nach, wohin `latest` zeigt, und bringt einen neueren Build online. Startet die neue Version nicht innerhalb von zehn Minuten, kommt die vorherige zurück. Soll es sofort gehen, klick in der App auf "Restart". Ein Tag namens `latest` wird bei jedem Start neu geladen, also holt der Neustart den neuen Build. Am Namen des Tags siehst du nicht, welcher Build läuft; der Tab "Activity" der App listet jede Version, die online ging.

Liegt dein Code auf GitHub, kannst du Docker Hub ganz weglassen. Verbinde in blitz.cloud dein GitHub-Konto und wähl das Repository, auch ein privates, und den Branch aus. Dann baut jeder Push das Dockerfile von oben und bringt die neue Version online. Siehe [GitHub-Projekt ausrollen](https://blitz.cloud/de/docs/deploy-from-github/).

## Passt das?

Für eine kleine JSON-API, einen Webhook-Empfänger oder einen Discord-Bot mit HTTP-Endpunkt: ja. Jede App bekommt 128 MB Arbeitsspeicher reserviert, bis zu 512 MB, und einen Anteil an einer CPU. Für eine stark ausgelastete API, die mehrere Kerne braucht, oder für Serverless-Funktionen, die auf null skalieren und pro Anfrage abrechnen, ist blitz.cloud nicht gemacht.
