diff --git a/app/api/beos/route.ts b/app/api/beos/route.ts index c53e250..e4626ed 100644 --- a/app/api/beos/route.ts +++ b/app/api/beos/route.ts @@ -1,7 +1,10 @@ import { NextResponse } from 'next/server'; import { query } from '@/lib/db'; +import { getSession } from '@/lib/session'; export async function GET() { + const session = await getSession(); + if (!session) return NextResponse.json({ error: 'Nicht angemeldet' }, { status: 401 }); try { const rows = await query( 'SELECT id AS ID, `kürzel` AS Kuerzel, CONCAT(IFNULL(vorname, \'\'), IF(vorname IS NOT NULL, \' \', \'\'), name) AS Name FROM beos WHERE `kürzel` IS NOT NULL ORDER BY name ASC' diff --git a/app/api/objekte/route.ts b/app/api/objekte/route.ts index 1b02bd5..9ea873b 100644 --- a/app/api/objekte/route.ts +++ b/app/api/objekte/route.ts @@ -1,7 +1,10 @@ import { NextResponse } from 'next/server'; import { query } from '@/lib/db'; +import { getSession } from '@/lib/session'; export async function GET() { + const session = await getSession(); + if (!session) return NextResponse.json({ error: 'Nicht angemeldet' }, { status: 401 }); try { const rows = await query('SELECT ID, Name FROM objekte ORDER BY LastUsed DESC LIMIT 100'); return NextResponse.json(rows); diff --git a/app/api/wetter/route.ts b/app/api/wetter/route.ts index 2f67013..21fe0e3 100644 --- a/app/api/wetter/route.ts +++ b/app/api/wetter/route.ts @@ -1,6 +1,9 @@ import { NextResponse } from 'next/server'; +import { getSession } from '@/lib/session'; export async function GET() { + const session = await getSession(); + if (!session) return NextResponse.json({ error: 'Nicht angemeldet' }, { status: 401 }); const temp = Math.round((8 + Math.random() * 15) * 10) / 10; const feuchte = Math.round((40 + Math.random() * 50) * 10) / 10; const druck = Math.round((990 + Math.random() * 30) * 10) / 10; diff --git a/app/layout.tsx b/app/layout.tsx index 0ef1fc0..e67a268 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,4 +1,4 @@ -import type { Metadata } from 'next'; +import type { Metadata, Viewport } from 'next'; import './globals.css'; export const metadata: Metadata = { @@ -6,6 +6,11 @@ export const metadata: Metadata = { description: 'Logbuch für die Sternwarte Welzheim', }; +export const viewport: Viewport = { + width: 'device-width', + initialScale: 1, +}; + export default function RootLayout({ children }: { children: React.ReactNode }) { return ( diff --git a/components/CustomSelect.tsx b/components/CustomSelect.tsx index 4696a33..d302f77 100644 --- a/components/CustomSelect.tsx +++ b/components/CustomSelect.tsx @@ -39,7 +39,7 @@ export default function CustomSelect({ options, placeholder, onChange, keepOpen diff --git a/components/LogbuchForm.tsx b/components/LogbuchForm.tsx index c9959d7..6252669 100644 --- a/components/LogbuchForm.tsx +++ b/components/LogbuchForm.tsx @@ -218,7 +218,7 @@ export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved setEnde(e.target.value + 'T' + (ende.slice(11, 16) || '00:00')); }} required - className="flex-1 px-2 py-2 border-2 border-gray-400 rounded-lg bg-white text-sm focus:border-blue-500 focus:outline-none" + className="flex-1 px-2 py-2 border-2 border-gray-400 rounded-lg bg-white text-sm text-gray-900 focus:border-blue-500 focus:outline-none" /> - {value} + {value}
diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..24d0179 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,48 @@ +services: + + logbuch_mysql: + image: mysql:lts + container_name: logbuch_mysql + restart: unless-stopped + environment: + MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS} + MYSQL_DATABASE: ${DB_NAME} + MYSQL_USER: ${DB_USER} + MYSQL_PASSWORD: ${DB_PASS} + volumes: + - db_data:/var/lib/mysql + networks: + - logbuch_net + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p${DB_ROOT_PASS}"] + interval: 10s + timeout: 5s + retries: 10 + # Kein Port nach außen — nur internes Netzwerk + + logbuch_app: + image: docker.citysensor.de/logbuch:latest + container_name: logbuch_app + restart: unless-stopped + environment: + DB_HOST: logbuch_mysql + DB_PORT: 3306 + DB_USER: ${DB_USER} + DB_PASS: ${DB_PASS} + DB_NAME: ${DB_NAME} + AUTH_SECRET: ${AUTH_SECRET} + NODE_ENV: production + ports: + - "127.0.0.1:${APP_PORT:-3000}:3000" + depends_on: + logbuch_mysql: + condition: service_healthy + networks: + - logbuch_net + +networks: + logbuch_net: + driver: bridge + +volumes: + db_data: diff --git a/dump_for_server.sh b/dump_for_server.sh new file mode 100755 index 0000000..c6c4ed7 --- /dev/null +++ b/dump_for_server.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# Erstellt einen SQL-Dump der 5 App-Tabellen aus dem lokalen logbuch_mysql-Container. +# Die Datei logbuch_dump.sql dann auf den Server kopieren und dort server_import.sh ausführen. + +set -e + +CONTAINER="logbuch_mysql" +DB="sternwarte" +ROOT_PASS="SFluorit" +TABLES="beos objekte logbuch logbuch_beos logbuch_objekte" +OUTFILE="logbuch_dump.sql" + +echo "Exportiere Tabellen aus '$CONTAINER'..." +docker exec "$CONTAINER" mysqldump \ + -u root -p"$ROOT_PASS" \ + --single-transaction \ + --no-tablespaces \ + "$DB" $TABLES > "$OUTFILE" + +echo "Dump gespeichert: $OUTFILE ($(wc -c < "$OUTFILE" | tr -d ' ') Bytes)" +echo "" +echo "Nächste Schritte:" +echo " scp $OUTFILE user@server:/opt/logbuch/" +echo " scp docker-compose.prod.yml user@server:/opt/logbuch/" +echo " scp .env.prod.example user@server:/opt/logbuch/.env.prod" +echo " # Auf dem Server: .env.prod befüllen, dann:" +echo " # docker-compose -f docker-compose.prod.yml --env-file .env.prod up -d" +echo " # ./server_import.sh" diff --git a/lib/db.ts b/lib/db.ts index e392a96..444113d 100644 --- a/lib/db.ts +++ b/lib/db.ts @@ -3,6 +3,7 @@ import type { QueryResult } from 'mysql2/promise'; const dbConfig = { host: process.env.DB_HOST || 'mydbase_mysql', + port: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 3306, user: process.env.DB_USER, password: process.env.DB_PASS, database: process.env.DB_NAME || 'logbuch', diff --git a/logbuch_dump.sql b/logbuch_dump.sql new file mode 100644 index 0000000..69a05bf --- /dev/null +++ b/logbuch_dump.sql @@ -0,0 +1,191 @@ +-- MySQL dump 10.13 Distrib 8.4.3, for Linux (aarch64) +-- +-- Host: localhost Database: sternwarte +-- ------------------------------------------------------ +-- Server version 8.4.3 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!50503 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `beos` +-- + +DROP TABLE IF EXISTS `beos`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `beos` ( + `id` int NOT NULL, + `name` varchar(20) NOT NULL, + `vorname` varchar(20) DEFAULT NULL, + `kürzel` varchar(5) DEFAULT NULL, + `adresse` varchar(50) NOT NULL, + `plz` varchar(10) NOT NULL, + `ort` varchar(30) NOT NULL, + `email_1` varchar(40) NOT NULL, + `email_2` varchar(40) DEFAULT NULL, + `telefon_p` varchar(20) DEFAULT NULL, + `telefon_m` varchar(20) DEFAULT NULL, + `telefon_d` varchar(20) DEFAULT NULL, + `telefon_fax` varchar(20) DEFAULT NULL, + `weburl` varchar(30) DEFAULT NULL, + `gender` char(1) NOT NULL, + `schluesselnr` int DEFAULT NULL, + `gruppe` varchar(20) DEFAULT NULL, + `bemerkung` varchar(50) DEFAULT NULL, + `pw` varchar(70) DEFAULT NULL, + `MustChangePassword` tinyint(1) DEFAULT '1', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `beos` +-- + +LOCK TABLES `beos` WRITE; +/*!40000 ALTER TABLE `beos` DISABLE KEYS */; +INSERT INTO `beos` VALUES (1,'Brückner','Steffen','Brü','Hegelstr. 10','71093','Weil im Schönbuch','brueckner@ccdastro.de',NULL,'070312627550',NULL,NULL,'070312627551',NULL,'m',2,'Mi II,Sa A',NULL,NULL,0),(2,'Dschida','Hans','HD','Rain 5','73660','Urbach','hansdschida1@gmail.com',NULL,'0718184322','015575359828','07195142599',NULL,NULL,'m',21,'Mi I,Sa C',NULL,'$2b$10$9EqDIW7xyTGsNE0NJqt5Pef1p/9C8FMj1tRfO0JPYkFaKouPey95W',0),(5,'Ess','Andrea','Ess','Beethovenweg 8','73630','Remshalden','andrea.ess@t-online.de',NULL,'071512703929',NULL,'07151566486',NULL,NULL,'w',NULL,NULL,NULL,NULL,0),(6,'Förnzler','Ulrich','Fö','Ober Str. 12','7ß190','Stuttgart','papa.foernzler@gmx.de',NULL,'07112865188','01778239801',NULL,NULL,NULL,'m',12,NULL,NULL,NULL,0),(7,'Fürst','Reinhard','rxf','Forststr. 66a','70176','Stuttgart','rexfue@gmail.com',NULL,'07116369409','01713129481',NULL,NULL,'','m',4,'Mo I,Sa C',NULL,'$2b$10$nmpF4s1rgeVF.6o1Nv7nk.OvAlcEJKsrAWeiqgESyBcKtvxw0fZNS',0),(8,'Gertz','Martin','MG','Buhlstr. 39/1','71384','Weinstadt','martin.gertz@gmx.de','martin.gertz@stihl.de','071519459521','015788298545','07151262545','071512682545',NULL,'m',5,'Sa B','HOBS',NULL,0),(9,'Meyer-Hamme','Olaf','MH','Eichenweg 29','73650','Winterbach','olaf.meyer-hamme@gmx.de',NULL,'071814808656','015221962790','07181977050',NULL,NULL,'m',22,'Mi II,Sa C',NULL,NULL,0),(10,'Idler','Rudolf','ID','Stettener Str. 26/1','71394','Kernen','r.idler@freenet.de',NULL,NULL,'01782097963','07119576017',NULL,NULL,'m',11,'Sa A',NULL,NULL,0),(11,'Nikolaizig','Jörg','JN','Grundweinberge 22','71642','Ludwigsburg','joniko@web.de',NULL,'07141257447','015122894226','071316444249',NULL,NULL,'m',10,'Mo II,Sa A',NULL,NULL,0),(15,'Weishaar','Christoph','CW','Leintelstr. 48','71336','Waiblingen-Bittenfeld','erfinderwerkstatt@t-online.de','c.weishaar@pilz.de ','071462840172',NULL,'07113409216','07113409434',NULL,'m',7,'Mi I,Sa B',NULL,'$2b$10$wSc60txkGL8cvNEZeF8IS.Yzfm8xvM1yJ/EbbRJRI5GkK3ERpkesW',0),(16,'Zoller','Matthias','Zo','Rosenstr. 49','71063','Sindelfingen','mazoller@gmx.de',NULL,'07031876466','01713752637','071197242618',NULL,NULL,'m',8,'Mo II,Sa A',NULL,NULL,0),(17,'Keller','Hans-Ulrich','HUK','Planetarium','','Stuttgart','hans-ulrich.keller@stuttgart.de','planetarium@stuttgart.de','07114403350',NULL,'07111629226','07112163912',NULL,'m',1,NULL,NULL,NULL,0),(18,'Gräber','Hubert','HHG','Im Brunnengarten 20','73630','Remshalden','hubert.graeber@t-online.de',NULL,'0718141612',NULL,NULL,'0718146145',NULL,'m',6,'Mo I,Sa C',NULL,NULL,0),(19,'Mitterhuber','Markus','MM','Robert-Koch-Str. 132','70565','Stuttgart','st155087@stud.uni-stuttgart.de','markusmitterhuber@outlook.de',NULL,'016092976568',NULL,NULL,NULL,'m',14,'Sa B',NULL,NULL,0),(20,'Schneider','Eva','ES','Baumblüte 20','73642','Welzheim','schneider-welzheim@t-online.de',NULL,'07182935424','01727168353',NULL,NULL,NULL,'w',NULL,'Sa B',NULL,NULL,0),(21,'Güssmann','Marc','GM','Spreeweg 8','71522','Backnang','marcguessmann@aol.com',NULL,' 071911873059',NULL,'0711951341200',NULL,NULL,'m',18,'Mo I,Sa A',NULL,NULL,0),(22,'Recknagel','Malin','MR','Stöcklestr. 36','72070','Tübingen ','malin.recknagel@freenet.de',NULL,NULL,'015776638250',NULL,NULL,NULL,'w',9,'','hat sich aus der Gruppe abgemeldet',NULL,0),(23,'Schuler','Bernd','SC','','','','bkschuler@gmail.com',NULL,NULL,NULL,NULL,NULL,NULL,'m',NULL,'Mo I,Sa C',NULL,NULL,0),(24,'Riedl','Christoph','RC','Schillerstr. 30','73773','Aichwald','wp.riedl@my-steuerberatung.com',NULL,'',NULL,'0711 4116772','0711 4116773',NULL,'m',NULL,NULL,NULL,NULL,0),(25,'Nastos','Xeno','XN','','','','XNastos@t-online.de',NULL,NULL,NULL,NULL,NULL,NULL,'m',NULL,'Mi II,Sa B',NULL,NULL,0),(26,'Bernhard','Ralf','RB','Alpenrosenstr. 22','70563','Stuttgart','ralf_bernhard@web.de',NULL,'0711 4204151',NULL,NULL,NULL,NULL,'m',11,'Mo II,Sa A',NULL,NULL,0); +/*!40000 ALTER TABLE `beos` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `objekte` +-- + +DROP TABLE IF EXISTS `objekte`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `objekte` ( + `ID` int NOT NULL AUTO_INCREMENT, + `Name` varchar(200) NOT NULL, + `LastUsed` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`ID`), + UNIQUE KEY `Name` (`Name`) +) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `objekte` +-- + +LOCK TABLES `objekte` WRITE; +/*!40000 ALTER TABLE `objekte` DISABLE KEYS */; +INSERT INTO `objekte` VALUES (1,'Mond','2026-04-29 08:07:16','2026-04-27 15:44:00'),(2,'Jupiter','2026-04-29 08:07:16','2026-04-27 15:44:00'),(3,'M57','2026-04-28 11:39:17','2026-04-27 15:44:00'),(4,'Abend Stern','2026-04-28 11:35:55','2026-04-27 15:56:24'),(5,'eps Lyr','2026-04-27 18:34:44','2026-04-27 18:17:16'),(6,'beta Cyg','2026-04-28 11:39:17','2026-04-27 18:34:44'),(7,'M31','2026-04-28 11:39:17','2026-04-28 11:39:17'),(8,'M45','2026-04-29 08:07:16','2026-04-29 07:59:50'),(9,'Saturn','2026-04-29 08:07:16','2026-04-29 08:06:16'),(10,'M42','2026-04-29 08:07:16','2026-04-29 08:06:16'),(11,'alp Ori','2026-04-29 08:06:16','2026-04-29 08:06:16'),(12,'alpha Ori','2026-04-29 08:07:16','2026-04-29 08:07:16'); +/*!40000 ALTER TABLE `objekte` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `logbuch` +-- + +DROP TABLE IF EXISTS `logbuch`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `logbuch` ( + `ID` int NOT NULL AUTO_INCREMENT, + `Kuppel` enum('West','Ost','Süd','Pluto') NOT NULL DEFAULT 'West', + `ArtFuehrung` enum('RF','SF','PrF','BEOS','SonF','TD','Beob','ToT','Sonst') NOT NULL DEFAULT 'RF', + `Beginn` datetime NOT NULL, + `Ende` datetime NOT NULL, + `Besucher` int DEFAULT '0', + `Bemerkungen` text, + `WetterTemp` decimal(5,1) DEFAULT NULL, + `WetterFeuchte` decimal(5,1) DEFAULT NULL, + `WetterDruck` decimal(7,1) DEFAULT NULL, + `created_by` int DEFAULT NULL, + `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`ID`), + KEY `created_by` (`created_by`), + CONSTRAINT `logbuch_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `beos` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `logbuch` +-- + +LOCK TABLES `logbuch` WRITE; +/*!40000 ALTER TABLE `logbuch` DISABLE KEYS */; +INSERT INTO `logbuch` VALUES (1,'West','RF','2026-04-27 20:00:00','2026-04-27 22:00:00',22,'Test\n',15.7,68.6,1006.3,7,'2026-04-27 15:44:00'),(2,'West','RF','2026-04-27 17:44:00','2026-04-27 17:44:00',0,NULL,11.6,89.0,1016.6,7,'2026-04-27 15:45:19'),(3,'West','RF','2026-04-27 17:52:00','2026-04-27 17:52:00',22,NULL,22.8,55.1,993.8,7,'2026-04-27 15:56:24'),(4,'West','RF','2026-04-27 18:06:00','2026-04-27 18:06:00',6,NULL,11.0,67.2,1002.7,7,'2026-04-27 16:06:59'),(5,'West','RF','2026-04-27 20:16:00','2026-04-27 20:16:00',1,NULL,20.3,67.9,1014.8,2,'2026-04-27 18:17:16'),(6,'West','RF','2026-04-28 09:45:00','2026-04-28 09:00:00',0,NULL,12.2,83.1,1017.1,2,'2026-04-28 07:00:01'),(8,'West','RF','2026-04-28 09:15:00','2026-04-28 09:15:00',0,NULL,9.6,56.8,1000.3,2,'2026-04-28 07:02:13'),(9,'West','RF','2026-04-28 09:15:00','2026-04-28 09:15:00',0,NULL,9.6,56.8,1000.3,2,'2026-04-28 07:02:41'),(14,'Pluto','Beob','2024-01-10 18:30:00','2024-01-10 23:00:00',0,NULL,16.4,43.4,1015.3,15,'2026-04-29 07:59:50'),(15,'West','Sonst','2024-01-20 18:00:00','2024-01-20 19:45:00',3,'Private Führung',8.5,53.0,1001.2,2,'2026-04-29 08:06:16'); +/*!40000 ALTER TABLE `logbuch` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `logbuch_beos` +-- + +DROP TABLE IF EXISTS `logbuch_beos`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `logbuch_beos` ( + `ID` int NOT NULL AUTO_INCREMENT, + `LogbuchID` int NOT NULL, + `BeoID` int NOT NULL, + PRIMARY KEY (`ID`), + KEY `LogbuchID` (`LogbuchID`), + KEY `BeoID` (`BeoID`), + CONSTRAINT `logbuch_beos_ibfk_1` FOREIGN KEY (`LogbuchID`) REFERENCES `logbuch` (`ID`) ON DELETE CASCADE, + CONSTRAINT `logbuch_beos_ibfk_2` FOREIGN KEY (`BeoID`) REFERENCES `beos` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=41 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `logbuch_beos` +-- + +LOCK TABLES `logbuch_beos` WRITE; +/*!40000 ALTER TABLE `logbuch_beos` DISABLE KEYS */; +INSERT INTO `logbuch_beos` VALUES (1,1,7),(2,1,2),(3,1,23),(4,2,7),(5,2,21),(6,3,7),(7,3,9),(8,4,7),(9,4,15),(11,5,2),(12,6,2),(14,8,2),(15,9,2),(38,14,15),(40,15,2); +/*!40000 ALTER TABLE `logbuch_beos` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `logbuch_objekte` +-- + +DROP TABLE IF EXISTS `logbuch_objekte`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `logbuch_objekte` ( + `ID` int NOT NULL AUTO_INCREMENT, + `LogbuchID` int NOT NULL, + `ObjektID` int DEFAULT NULL, + `ObjektName` varchar(200) NOT NULL, + PRIMARY KEY (`ID`), + KEY `LogbuchID` (`LogbuchID`), + KEY `ObjektID` (`ObjektID`), + CONSTRAINT `logbuch_objekte_ibfk_1` FOREIGN KEY (`LogbuchID`) REFERENCES `logbuch` (`ID`) ON DELETE CASCADE, + CONSTRAINT `logbuch_objekte_ibfk_2` FOREIGN KEY (`ObjektID`) REFERENCES `objekte` (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `logbuch_objekte` +-- + +LOCK TABLES `logbuch_objekte` WRITE; +/*!40000 ALTER TABLE `logbuch_objekte` DISABLE KEYS */; +INSERT INTO `logbuch_objekte` VALUES (1,1,1,'Mond'),(2,1,2,'Jupiter'),(3,1,3,'M57'),(4,2,2,'Jupiter'),(5,3,4,'Abend Stern'),(6,4,4,'Abend Stern'),(7,4,3,'M57'),(10,5,4,'Abend Stern'),(11,5,5,'eps Lyr'),(12,5,1,'Mond'),(13,5,6,'beta Cyg'),(19,14,8,'M45'),(26,15,2,'Jupiter'),(27,15,10,'M42'),(28,15,8,'M45'),(29,15,1,'Mond'),(30,15,9,'Saturn'),(31,15,12,'alpha Ori'); +/*!40000 ALTER TABLE `logbuch_objekte` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2026-04-30 5:31:48 diff --git a/migrate_db.sh b/migrate_db.sh new file mode 100755 index 0000000..673af5d --- /dev/null +++ b/migrate_db.sh @@ -0,0 +1,103 @@ +#!/bin/bash +# Erstellt einen neuen MySQL-Container "logbuch_mysql" und migriert +# die 5 App-relevanten Tabellen aus dem bestehenden "db"-Container. + +set -e + +# ── Konfiguration ──────────────────────────────────────────────────────────── +SRC_CONTAINER="db" +SRC_DB="sternwarte" +SRC_ROOT_PASS="SFluorit" + +NEW_CONTAINER="logbuch_mysql" +NEW_DB="sternwarte" +NEW_ROOT_PASS="SFluorit" # ggf. hier ändern +NEW_PORT="3307" # Host-Port (3306 ist schon belegt) +MYSQL_IMAGE="arm64v8/mysql:lts" +NETWORK="sternwarte_default" + +TABLES="beos objekte logbuch logbuch_beos logbuch_objekte" + +# ── Hilfsfunktion ──────────────────────────────────────────────────────────── +wait_for_mysql() { + local container="$1" + local pass="$2" + echo -n "Warte auf MySQL in '$container' " + for i in $(seq 1 60); do + if docker exec "$container" mysqladmin ping -u root -p"$pass" --silent 2>/dev/null; then + echo " bereit." + return 0 + fi + echo -n "." + sleep 2 + done + echo "" + echo "FEHLER: MySQL in '$container' nicht erreichbar nach 120s." >&2 + exit 1 +} + +# ── Prüfen ob Quell-Container läuft ───────────────────────────────────────── +if ! docker inspect "$SRC_CONTAINER" &>/dev/null; then + echo "FEHLER: Quell-Container '$SRC_CONTAINER' nicht gefunden." >&2 + exit 1 +fi +echo "Quell-Container '$SRC_CONTAINER' gefunden." + +# ── Alten Ziel-Container entfernen falls vorhanden ────────────────────────── +if docker inspect "$NEW_CONTAINER" &>/dev/null; then + echo "Container '$NEW_CONTAINER' existiert bereits — wird gestoppt und entfernt..." + docker rm -f "$NEW_CONTAINER" +fi + +# ── Neuen Container starten ────────────────────────────────────────────────── +echo "Starte neuen Container '$NEW_CONTAINER'..." +docker run -d \ + --name "$NEW_CONTAINER" \ + --network "$NETWORK" \ + -p "${NEW_PORT}:3306" \ + -e MYSQL_ROOT_PASSWORD="$NEW_ROOT_PASS" \ + -e MYSQL_DATABASE="$NEW_DB" \ + "$MYSQL_IMAGE" + +wait_for_mysql "$NEW_CONTAINER" "$NEW_ROOT_PASS" + +# ── Daten migrieren ────────────────────────────────────────────────────────── +echo "Migriere Tabellen: $TABLES" +echo "(Dump von '$SRC_CONTAINER' → Import in '$NEW_CONTAINER')" + +docker exec "$SRC_CONTAINER" mysqldump \ + -u root -p"$SRC_ROOT_PASS" \ + --single-transaction \ + --no-tablespaces \ + "$SRC_DB" $TABLES \ +| docker exec -i "$NEW_CONTAINER" mysql \ + -u root -p"$NEW_ROOT_PASS" \ + "$NEW_DB" + +echo "Migration abgeschlossen." + +# ── Zeilenzähler zur Verifikation ──────────────────────────────────────────── +echo "" +echo "Zeilenzähler (Quelle → Ziel):" +for TABLE in $TABLES; do + SRC_COUNT=$(docker exec "$SRC_CONTAINER" mysql -u root -p"$SRC_ROOT_PASS" -sN \ + -e "SELECT COUNT(*) FROM $TABLE;" "$SRC_DB" 2>/dev/null) + DST_COUNT=$(docker exec "$NEW_CONTAINER" mysql -u root -p"$NEW_ROOT_PASS" -sN \ + -e "SELECT COUNT(*) FROM $TABLE;" "$NEW_DB" 2>/dev/null) + STATUS="✓" + [ "$SRC_COUNT" != "$DST_COUNT" ] && STATUS="✗ ABWEICHUNG" + printf " %-25s %5s → %5s %s\n" "$TABLE" "$SRC_COUNT" "$DST_COUNT" "$STATUS" +done + +# ── Abschluss ───────────────────────────────────────────────────────────────── +echo "" +echo "══════════════════════════════════════════════════════" +echo "Neuer Container: $NEW_CONTAINER" +echo " Netzwerk: $NETWORK" +echo " Host-Port: $NEW_PORT" +echo " Datenbank: $NEW_DB" +echo "" +echo "Nächster Schritt — .env anpassen:" +echo " DB_HOST=$NEW_CONTAINER" +echo " DB_PASS=$NEW_ROOT_PASS" +echo "══════════════════════════════════════════════════════" diff --git a/server_import.sh b/server_import.sh new file mode 100755 index 0000000..1b7e155 --- /dev/null +++ b/server_import.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# Auf dem Server ausführen, nachdem docker-compose gestartet wurde. +# Importiert logbuch_dump.sql in den laufenden logbuch_mysql-Container. + +set -e + +CONTAINER="logbuch_mysql" +DB="sternwarte" +DUMPFILE="${1:-logbuch_dump.sql}" + +if [ ! -f "$DUMPFILE" ]; then + echo "FEHLER: Dump-Datei '$DUMPFILE' nicht gefunden." >&2 + exit 1 +fi + +# Root-Passwort aus .env.prod lesen +ROOT_PASS=$(grep DB_ROOT_PASS .env.prod | cut -d= -f2) +if [ -z "$ROOT_PASS" ]; then + echo "FEHLER: DB_ROOT_PASS nicht in .env.prod gefunden." >&2 + exit 1 +fi + +echo "Importiere '$DUMPFILE' in Container '$CONTAINER'..." +docker exec -i "$CONTAINER" mysql -u root -p"$ROOT_PASS" "$DB" < "$DUMPFILE" + +echo "Verifikation:" +for TABLE in beos objekte logbuch logbuch_beos logbuch_objekte; do + COUNT=$(docker exec "$CONTAINER" mysql -u root -p"$ROOT_PASS" -sN \ + -e "SELECT COUNT(*) FROM $TABLE;" "$DB" 2>/dev/null) + printf " %-25s %5s Zeilen\n" "$TABLE" "$COUNT" +done + +echo "Import abgeschlossen."