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:
@@ -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
|
||||
@@ -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
|
||||
@@ -29,6 +29,7 @@ yarn-error.log*
|
||||
.env*
|
||||
!.env.example
|
||||
!.env.local.example
|
||||
!.env.production.example
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
+51
@@ -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"]
|
||||
@@ -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`.
|
||||
|
||||
@@ -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 ""
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user