Docker-Deployment fuer nuccy

- Dockerfile (Next.js standalone, Multi-Stage) + .dockerignore
- deploy.sh fuer strom-next angepasst (Registry docker.citysensor.de,
  multiplatform build & push)
- docker-compose.prod.yml: Netzwerk 'smarthome' (external), InfluxDB als
  Host 'influx', alle Env-Defaults gesetzt, INFLUX_TOKEN aus .env
- .env.production.example (nur Token/Port), public/ fuer den Image-Build
- README: Deploy-Anleitung

Lokal verifiziert: Image baut, Container startet und liefert HTTP 200.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-28 16:34:24 +02:00
parent 8873ffe9d3
commit 6fdf29f040
8 changed files with 242 additions and 1 deletions
+51
View File
@@ -0,0 +1,51 @@
# dependencies
node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# testing
coverage
# next.js
.next/
out/
build
dist
# misc
.DS_Store
*.pem
# debug
*.log
# local env files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# vercel
.vercel
# typescript
*.tsbuildinfo
# git
.git
.gitignore
# editor
.vscode
.idea
# docker
Dockerfile
.dockerignore
docker-compose*.yml
# other
README.md
+8
View File
@@ -0,0 +1,8 @@
# Auf nuccy als ".env" neben docker-compose.prod.yml ablegen (NICHT committen).
# Nur Geheimnisse/Abweichungen; der Rest steht in docker-compose.prod.yml.
# InfluxDB Read-Token (Bucket strom)
INFLUX_TOKEN=
# Optional: abweichender Host-Port (Default 3000)
# STROM_PORT=3000
+1
View File
@@ -29,6 +29,7 @@ yarn-error.log*
.env*
!.env.example
!.env.local.example
!.env.production.example
# vercel
.vercel
+51
View File
@@ -0,0 +1,51 @@
# Multi-stage build for Next.js application (standalone output)
FROM node:22-alpine AS base
# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
# Copy package files
COPY package.json package-lock.json* ./
RUN npm ci
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Set build date as build argument
ARG BUILD_DATE
ENV NEXT_PUBLIC_BUILD_DATE=${BUILD_DATE}
# Disable telemetry during build
ENV NEXT_TELEMETRY_DISABLED=1
# Build the application
RUN npm run build
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Copy necessary files
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"]
+39 -1
View File
@@ -101,10 +101,48 @@ curl -s -XPOST "http://nuccy:8086/api/v2/query?org=citysensor" \
schema.fieldKeys(bucket: "strom", predicate: (r) => r._measurement == "arbeit")'
```
## Starten
## Starten (lokal)
```bash
npm run dev # http://localhost:3000
npm run build # Produktionsbuild
npm start
```
## Docker / Deployment auf nuccy
Die App läuft als Container auf **nuccy** im externen Docker-Netzwerk
**`smarthome`** und erreicht die InfluxDB dort unter dem Host **`influx`**
(`http://influx:8086`).
### Image bauen & in die Registry pushen (vom Entwicklungsrechner)
```bash
./deploy.sh # Tag latest
./deploy.sh v1.2.0 # eigener Tag
```
Baut multiplattform (amd64/arm64) und pusht nach
`docker.citysensor.de/strom-next:<tag>`.
### Auf nuccy starten
`docker-compose.prod.yml` neben eine `.env` legen (aus
`.env.production.example`) und das **InfluxDB-Read-Token** dort eintragen:
```bash
# .env
INFLUX_TOKEN=...
# optional: STROM_PORT=3000
```
Dann:
```bash
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d
```
Die App ist anschließend auf nuccy unter Port `3000` (bzw. `STROM_PORT`)
erreichbar. Alle InfluxDB-/Lade-Einstellungen sind in `docker-compose.prod.yml`
gesetzt; nur das Token kommt aus der `.env`.
Executable
+59
View File
@@ -0,0 +1,59 @@
#!/bin/bash
# Deploy Script für strom-next
# Baut das Docker Image und lädt es zu docker.citysensor.de hoch
set -e
# Konfiguration
REGISTRY="docker.citysensor.de"
IMAGE_NAME="strom-next"
TAG="${1:-latest}" # Erster Parameter oder "latest"
FULL_IMAGE="${REGISTRY}/${IMAGE_NAME}:${TAG}"
# Build-Datum
BUILD_DATE=$(date +%d.%m.%Y)
echo "=========================================="
echo "strom-next Deploy Script"
echo "=========================================="
echo "Registry: ${REGISTRY}"
echo "Image: ${IMAGE_NAME}"
echo "Tag: ${TAG}"
echo "Build-Datum: ${BUILD_DATE}"
echo "=========================================="
echo ""
# 1. Login zur Registry (falls noch nicht eingeloggt)
echo ">>> Login zu ${REGISTRY}..."
docker login "${REGISTRY}"
echo ""
# 2. Multiplatform Builder einrichten (docker-container driver erforderlich)
echo ">>> Richte Multiplatform Builder ein..."
if ! docker buildx inspect multiplatform-builder &>/dev/null; then
docker buildx create --name multiplatform-builder --driver docker-container --bootstrap
fi
docker buildx use multiplatform-builder
echo ""
# 3. Docker Image bauen und pushen (Multiplatform)
echo ">>> Baue Multiplatform Docker Image und pushe zu Registry..."
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg BUILD_DATE="${BUILD_DATE}" \
-t "${FULL_IMAGE}" \
--push \
.
echo ">>> Build und Push erfolgreich!"
echo ""
echo "=========================================="
echo "✓ Deploy erfolgreich abgeschlossen!"
echo "=========================================="
echo ""
echo "Auf nuccy ausführen (Verzeichnis mit docker-compose.prod.yml + .env):"
echo " docker compose -f docker-compose.prod.yml pull"
echo " docker compose -f docker-compose.prod.yml up -d"
echo ""
+33
View File
@@ -0,0 +1,33 @@
# Docker Compose für nuccy
# Container im externen Docker-Netzwerk 'smarthome', erreicht InfluxDB als 'influx'.
# Geheimnisse (INFLUX_TOKEN) kommen aus einer .env-Datei neben dieser Compose-Datei.
services:
strom-app:
image: docker.citysensor.de/strom-next:latest
container_name: strom-next-app
restart: unless-stopped
ports:
- "${STROM_PORT:-3000}:3000"
environment:
- NODE_ENV=production
# InfluxDB im smarthome-Netz
- INFLUX_URL=http://influx:8086
- INFLUX_TOKEN=${INFLUX_TOKEN}
- INFLUX_ORG=citysensor
- INFLUX_BUCKET=strom
# Rohdaten (24h) bzw. Rollup (7d/31d/365d)
- INFLUX_MEASUREMENT=vzlogger
- INFLUX_ROLLUP_MEASUREMENT=arbeit_hourly
- INFLUX_FIELD=arbeit
- INFLUX_UNIT_FACTOR=0.001
# E-Auto-Lade-Erkennung
- INFLUX_POWER_FIELD=leistung
- LADEN_THRESHOLD_KW=11
- LADEN_MIN_HOURS=2
- LADEN_MAX_GAP_MIN=10
networks:
- smarthome
networks:
smarthome:
external: true
View File