
Wie man Astro in Dockerized und Deployed

Dieses Dockerfile optimiert den Build- und Ausführungsprozess einer Astro-App in einem leichtgewichtigen Docker-Container durch Multi-Stage-Builds, die Dependencies trennen und die Image-Größe reduzieren.
Falls du nur zum Kopieren und Einfügen hier bist, hier ist das fertige Dockerfile, das ein Image für deine Astro-App erstellt:
FROM node:20-alpine AS base
WORKDIR /app
# Durch das Kopieren von nur package.json und package-lock.json stellen wir sicher, dass die folgenden `-deps`-Schritte
# unabhängig vom Quellcode sind. Dadurch werden die `-deps`-Schritte übersprungen, wenn sich nur der Quellcode ändert.
COPY package.json package-lock.json ./
FROM base AS prod-deps
RUN npm install --omit=dev
FROM base AS build-deps
RUN npm install
FROM build-deps AS build
COPY . .
RUN npm run build
FROM base AS runtime
COPY --from=prod-deps /app/node_modules ./node_modules # Kopiere Dependencies
COPY --from=build /app/dist ./dist # Kopiere die gebauten Dateien
# An alle Netzwerkschnittstellen binden
ENV HOST=0.0.0.0
# Port zum Abhören
ENV PORT=4321
# Nur Konvention, nicht erforderlich
EXPOSE 4321
CMD node ./dist/server/entry.mjs # Starte die App
Und hier ist die .dockerignore-Datei:
.DS_Store
node_modules
dist
Um das Image zu bauen und auszuführen, verwende diese Befehle:
docker build -t astro .
docker run -p 4321:4321 astro
Nicht nur hier zum Kopieren und Einfügen? Lass uns durchgehen, was im Dockerfile passiert!
Die Voraussetzungen
Für dieses Tutorial gehe ich davon aus, dass du bereits ein grundlegendes Astro-Projekt eingerichtet hast. Falls du ein anderes Setup hast, musst du das Dockerfile eventuell entsprechend anpassen.
Normalerweise würdest du lokal npm install
und dann npm run dev
ausführen. Für das Deployment wollen wir aber die App bauen und die Dateien von einem Server bereitstellen. Deshalb nutzen wir npm run build
zum Erzeugen der Dateien und stellen diese dann bereit.
Gehen wir die Details des Dockerfiles durch.
Das Dockerfile
FROM node:20-alpine AS base
WORKDIR /app
# Durch das Kopieren von nur package.json und package-lock.json stellen wir sicher, dass die folgenden `-deps`-Schritte
# unabhängig vom Quellcode sind. Dadurch werden die `-deps`-Schritte übersprungen, wenn sich nur der Quellcode ändert.
COPY package.json package-lock.json ./
FROM base AS prod-deps
RUN npm install --omit=dev
FROM base AS build-deps
RUN npm install
FROM build-deps AS build
COPY . .
RUN npm run build
FROM base AS runtime
COPY --from=prod-deps /app/node_modules ./node_modules # Kopiere Dependencies
COPY --from=build /app/dist ./dist # Kopiere die gebauten Dateien
# An alle Netzwerkschnittstellen binden
ENV HOST=0.0.0.0
# Port zum Abhören
ENV PORT=4321
# Nur Konvention, nicht erforderlich
EXPOSE 4321
CMD node ./dist/server/entry.mjs # Starte die App
Was passiert hier?
- Base-Stage:
- Verwendet Node.js 20 auf Alpine, was ein leichtgewichtiges Basis-Image bietet.
- Richtet das Arbeitsverzeichnis ein und kopiert die Package-Dateien für die Installation der Dependencies.
- Production-Dependencies-Stage:
- Installiert nur Production-Dependencies, ohne Dev-Dependencies.
- Build-Dependencies-Stage:
- Installiert alle Dependencies, einschließlich der zum Bauen benötigten Dev-Dependencies.
- Build-Stage:
- Kopiert das gesamte Projekt und führt den Build-Befehl aus.
- Runtime-Stage:
- Startet wieder vom Basis-Image.
- Kopiert Production-Dependencies und gebaute Dateien aus vorherigen Stages.
- Setzt Umgebungsvariablen für Host und Port.
- Exponiert Port 4321 (Astros Standard-Port).
- Startet die Astro-App mit dem gebauten Server-Entry-Point.
Dieser Multi-Stage-Ansatz optimiert den Build-Prozess und hält die finale Image-Größe kleiner, indem Build- und Laufzeitumgebungen getrennt werden.
Achte darauf, eine .dockerignore
-Datei hinzuzufügen, um die node_modules
und dist
-Ordner zu ignorieren. Das beschleunigt den Build-Prozess und reduziert die Image-Größe.
Deployment
Du kannst diesen Docker-Container bei jedem Cloud-Anbieter deployen, der Docker unterstützt. Du könntest zum Beispiel Plattformen wie Heroku, DigitalOcean oder AWS ECS verwenden. Da ich Mitgründer von Sliplane bin, zeige ich dir, wie du es dort deployen kannst.
Nach der Anmeldung kannst du einen neuen Service erstellen, indem du dein Github-Repository auswählst. Behalte dann einfach die Standardeinstellungen bei und klicke auf Deployment.
Nach dem Deployment wird deine Astro-App unter einer Subdomain von sliplane.app verfügbar sein, normalerweise ist das einfach dein Service-Name.
Du kannst auch die Logs deiner App sehen, Metriken wie CPU- und Speichernutzung einsehen, persistenten Speicher hinzufügen und vieles mehr. Wann immer du in dein Repository pushst, wird Sliplane deine App automatisch deployen.
Wenn du Sliplane ausprobieren möchtest, sind die ersten 2 Tage kostenlos! Probier es aus und lass mich wissen, was du davon hältst :)
Nächste Schritte
Gibt es noch etwas, das du wissen möchtest? Brauchst du Hilfe beim Dockerisieren deiner Astro-App? Brauchst du Hilfe beim Deployen auf einer bestimmten Plattform? Melde dich gerne! Du findest mich auf X oder kommentiere einfach hier im Blog.
Cheers,
Jonas