blitz.cloudBetaAnmeldenKostenlos starten

Statische Seite (Astro, Hugo, Next.js) mit eigener Subdomain hosten

Astro, Hugo, Vite oder Next.js-Static-Export in ein nginx-Image ohne Root auf Port 8080 bauen und auf blitz.cloud mit HTTPS unter eigener Subdomain hosten.

Aktualisiert

Um eine statische Seite auf blitz.cloud zu hosten, baust du sie zu einfachen Dateien, kopierst sie in das unprivilegierte nginx-Image, lädst das Image auf Docker Hub hoch und rollst es aus. Die Seite bekommt eine eigene Subdomain wie blog.yourname.blitz.cloud mit HTTPS. Das klappt mit jedem Generator, der einen Ordner mit HTML ausgibt: Astro, Hugo, Eleventy, eine Vite-App oder Next.js mit output: "export".

Zuerst ein ehrlicher Vergleich. Netlify, Cloudflare Pages und GitHub Pages bauen statische Seiten direkt aus einem Git-Repository und liefern sie über ein globales CDN aus. Das ist weniger Arbeit als diese Anleitung. blitz.cloud lohnt sich, wenn die Seite neben deinen anderen Apps unter einer Adresse liegen soll, aus Deutschland ausgeliefert, ohne US-Anbieter dazwischen. Ausgeliefert wird von einem Standort, nicht über ein CDN.

Das Dockerfile

Das ist das static-site-Beispiel, eine Astro-Seite. Zwei Stufen: Node baut die Seite, nginx liefert sie aus.

# Build stage: turn the Astro project into plain files in dist/.
FROM node:22.23.2-alpine3.24 AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build

# Serve stage: nginx without root, listening on 8080.
FROM nginxinc/nginx-unprivileged:1.30.4-alpine3.24
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist /usr/share/nginx/html
# blitz.cloud runs every app as uid 1000. nginx-unprivileged keeps its pid
# file and temp folders in /tmp, which any uid can write to.
USER 1000
EXPOSE 8080

Das normale nginx-Image lauscht auf Port 80 und startet als Root, deshalb läuft es nicht auf blitz.cloud. nginxinc/nginx-unprivileged ist die offizielle Variante genau für diesen Fall.

Die nginx-Konfiguration

server {
    # The unprivileged nginx image listens on 8080 instead of 80, so it runs
    # without root.
    listen 8080;
    server_name _;
    root /usr/share/nginx/html;

    # Behind blitz.cloud's HTTPS proxy nginx only sees plain HTTP on 8080.
    # Relative redirects keep /about -> /about/ on the address the visitor used.
    absolute_redirect off;

    location / {
        try_files $uri $uri/ $uri.html =404;
    }

    # Astro puts fingerprinted assets in /_astro/, safe to cache for a year.
    location /_astro/ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    error_page 404 /404.html;

    gzip on;
    gzip_types text/css application/javascript application/json image/svg+xml;
}

absolute_redirect off ist die Zeile, die gern vergessen wird. Ohne sie wird ein Aufruf von /about auf http://blog.yourname.blitz.cloud:8080/about/ umgeleitet, weil nginx die Weiterleitung aus dem baut, was es sieht, und hinter dem HTTPS-Proxy sieht es einfaches HTTP auf Port 8080. Genau das ist uns beim Testen des Beispiels passiert.

Andere Generatoren

Nur die Build-Stufe ändert sich. Lass die Zeile COPY --from=build auf den Ausgabeordner des Generators zeigen.

GeneratorBuild-BefehlAusgabeordner
Astronpm run builddist
Vite (React, Vue, Svelte)npm run builddist
Next.js mit output: "export"npm run buildout
Hugohugo --minifypublic

Bei Next.js deckt ein Static Export nur Seiten ab, die keinen Server brauchen. Wenn deine App Server Components mit Datenabruf pro Anfrage, API-Routen oder Middleware nutzt, nimm stattdessen das Standalone-Setup aus Eine App von Vercel zu einem EU-Hoster umziehen.

Bei einer Single-Page-App mit Routing im Browser ersetzt du =404 in try_files durch /index.html, damit Deep Links die App laden.

Bauen, testen und hochladen

docker build --platform linux/amd64 -t yourname/blitz-example-static-site:1.0.0 -t yourname/blitz-example-static-site:latest .
docker run --rm --user 1000:1000 --cap-drop ALL --security-opt no-new-privileges \
  -p 8080:8080 yourname/blitz-example-static-site:1.0.0

In unserem Test lieferten / und /about/ ein 200, /about ein 301 auf /about/, und eine fehlende Seite ein echtes 404. Dann hochladen:

docker push --all-tags yourname/blitz-example-static-site

Mit deiner Subdomain online stellen

  1. Klicke im Dashboard auf "Host something new" (Neues hosten) und wähle "An app that is already packaged up" (eine fertig verpackte App).
  2. Suche dein Image, wähle die Version, klicke auf "Continue".
  3. Gib eine Adresse ein. Tippst du blog, ist die Seite unter https://blog.yourname.blitz.cloud erreichbar. Eine App kannst du auch direkt auf deine Hauptadresse legen, https://yourname.blitz.cloud, was gut zu einer persönlichen Homepage passt.
  4. Klicke auf "Put it online".

Das Zertifikat deckt deine Hauptadresse und jede Subdomain darunter ab und erneuert sich selbst. Siehe Adressen und HTTPS.

Kann ich meine eigene Domain nutzen?

Noch nicht. Eine eigene Domain wie example.com zu verbinden ist geplant, aber heute nicht live. Bis dahin liegt die Seite unter yourname.blitz.cloud.

Stell heute deine erste App online.

Kostenloser Tarif, keine Kreditkarte, keine Warteliste.

Kostenloses Konto anlegen