Wie achis.blog läuft
achis.blog läuft auf einem eigenen VPS. Kein Managed Hosting, kein Vercel, kein Netlify — stattdessen ein Server, ein Reverse Proxy und ein systemd-Service. Hier ist, wie das zusammenhängt.
Stack
- Astro mit
@astrojs/nodeimstandalone-Modus als SSR-Server - Caddy als Reverse Proxy (HTTPS automatisch via Let’s Encrypt)
- systemd zum Verwalten des Node-Prozesses
- rsync + npm als Deploy-Mechanismus
Astro: Node-Adapter
Astro baut im standalone-Modus einen eigenen HTTP-Server, den man direkt mit Node starten kann:
// astro.config.mjs
import node from '@astrojs/node';
export default defineConfig({
site: 'https://achis.blog',
adapter: node({ mode: 'standalone' }),
});
Nach astro build liegt der Server unter dist/server/entry.mjs.
systemd-Service
Der Node-Prozess läuft als systemd-Service, der bei einem Absturz automatisch neu startet:
[Unit]
Description=achis.blog Astro Node server
After=network.target
[Service]
Type=simple
User=deploy
WorkingDirectory=/opt/achis-blog
Environment=NODE_ENV=production
Environment=PORT=3000
Environment=HOST=127.0.0.1
Environment=SITE_ORIGIN=https://achis.blog
ExecStart=/usr/bin/node ./dist/server/entry.mjs
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
HOST=127.0.0.1 sorgt dafür, dass der Node-Server nur lokal erreichbar ist — nach außen kommt ausschließlich Caddy.
Caddy als Reverse Proxy
Caddy übernimmt TLS und leitet Anfragen an den lokalen Node-Server weiter. www wird permanent auf die Apex-Domain umgeleitet:
www.achis.blog {
redir https://achis.blog{uri} permanent
}
achis.blog {
reverse_proxy 127.0.0.1:3000
}
Caddy holt das TLS-Zertifikat automatisch von Let’s Encrypt — keine manuelle Zertifikatsverwaltung nötig.
Deploy-Script
Ein einfaches Shell-Script baut lokal, synct den Output auf den Server und startet den Service neu:
#!/usr/bin/env bash
set -euo pipefail
REMOTE_HOST="yaksha"
REMOTE_DIR="/opt/achis-blog"
SERVICE="achis-blog"
cd "$(dirname "$0")/.."
echo "==> Building..."
npm run build
echo "==> Syncing dist/, package.json, package-lock.json..."
rsync -az --delete dist/ "$REMOTE_HOST:$REMOTE_DIR/dist/"
rsync -az package.json package-lock.json "$REMOTE_HOST:$REMOTE_DIR/"
echo "==> Installing production deps and restarting service..."
ssh "$REMOTE_HOST" "cd $REMOTE_DIR && npm ci --omit=dev && sudo systemctl restart $SERVICE"
echo "==> Done."
Das Build passiert lokal — auf den Server kommt nur das fertig gebaute dist/ plus package.json. npm ci --omit=dev installiert dort nur die Production-Dependencies.
Ablauf von vorne bis hinten
bash scripts/deploy.shlokal ausführen- Astro baut
dist/ - rsync überträgt
dist/,package.json,package-lock.json npm ci --omit=devauf dem Serversystemctl restart achis-blogstartet den Node-Prozess neu- Caddy routet neue Anfragen sofort an den frischen Prozess