Initial commit
This commit is contained in:
406
Docker Backend/prepare-deployment.js
Normal file
406
Docker Backend/prepare-deployment.js
Normal file
@@ -0,0 +1,406 @@
|
||||
const fs = require('fs').promises;
|
||||
const fsSync = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const SOURCE_DIR = __dirname;
|
||||
const DEPLOY_DIR = path.join(__dirname, '..', 'DEPLOYMENT_READY');
|
||||
|
||||
// Dateien und Ordner die KOPIERT werden sollen
|
||||
const INCLUDE_FILES = [
|
||||
// Docker
|
||||
'Dockerfile',
|
||||
'docker-compose.yml',
|
||||
'.dockerignore',
|
||||
|
||||
// Package
|
||||
'package.json',
|
||||
'package-lock.json',
|
||||
|
||||
// Source Code
|
||||
'src/**/*',
|
||||
|
||||
// Fonts
|
||||
'fonts/**/*.svg',
|
||||
|
||||
// Config Example
|
||||
'.env.example'
|
||||
];
|
||||
|
||||
// Dateien die NICHT kopiert werden sollen
|
||||
const EXCLUDE_PATTERNS = [
|
||||
'node_modules',
|
||||
'output',
|
||||
'cache',
|
||||
'.git',
|
||||
'bruno-tests',
|
||||
'*.md',
|
||||
'test-*.js',
|
||||
'test-*.json',
|
||||
'test-*.sh',
|
||||
'generate-*.js',
|
||||
'server.log',
|
||||
'.env',
|
||||
'deploy.sh',
|
||||
'prepare-deployment.js',
|
||||
'DEPLOYMENT_READY'
|
||||
];
|
||||
|
||||
function shouldExclude(filePath) {
|
||||
const relativePath = path.relative(SOURCE_DIR, filePath);
|
||||
|
||||
return EXCLUDE_PATTERNS.some(pattern => {
|
||||
if (pattern.includes('*')) {
|
||||
const regex = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
|
||||
return regex.test(path.basename(filePath)) || regex.test(relativePath);
|
||||
}
|
||||
return relativePath.startsWith(pattern) || path.basename(filePath) === pattern;
|
||||
});
|
||||
}
|
||||
|
||||
async function ensureDir(dir) {
|
||||
try {
|
||||
await fs.mkdir(dir, { recursive: true });
|
||||
} catch (err) {
|
||||
if (err.code !== 'EEXIST') throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async function copyFile(src, dest) {
|
||||
await ensureDir(path.dirname(dest));
|
||||
await fs.copyFile(src, dest);
|
||||
}
|
||||
|
||||
async function removeDir(dir) {
|
||||
try {
|
||||
const entries = await fs.readdir(dir, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
const fullPath = path.join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
await removeDir(fullPath);
|
||||
} else {
|
||||
await fs.unlink(fullPath);
|
||||
}
|
||||
}
|
||||
await fs.rmdir(dir);
|
||||
} catch (err) {
|
||||
if (err.code !== 'ENOENT') throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async function pathExists(p) {
|
||||
try {
|
||||
await fs.access(p);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function copyDirectory(src, dest) {
|
||||
const entries = await fs.readdir(src, { withFileTypes: true });
|
||||
|
||||
await ensureDir(dest);
|
||||
|
||||
for (const entry of entries) {
|
||||
const srcPath = path.join(src, entry.name);
|
||||
const destPath = path.join(dest, entry.name);
|
||||
|
||||
if (shouldExclude(srcPath)) {
|
||||
console.log(`⏭️ Skipping: ${path.relative(SOURCE_DIR, srcPath)}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
await copyDirectory(srcPath, destPath);
|
||||
} else {
|
||||
await copyFile(srcPath, destPath);
|
||||
console.log(`✅ Copied: ${path.relative(SOURCE_DIR, srcPath)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log('🚀 Preparing Deployment Package...\n');
|
||||
|
||||
// Deployment-Verzeichnis erstellen/leeren
|
||||
if (await pathExists(DEPLOY_DIR)) {
|
||||
console.log('🗑️ Cleaning existing deployment directory...');
|
||||
await removeDir(DEPLOY_DIR);
|
||||
}
|
||||
|
||||
await ensureDir(DEPLOY_DIR);
|
||||
console.log(`📁 Created: ${DEPLOY_DIR}\n`);
|
||||
|
||||
// Dateien kopieren
|
||||
console.log('📋 Copying production files...\n');
|
||||
await copyDirectory(SOURCE_DIR, DEPLOY_DIR);
|
||||
|
||||
// Produktions-.env.example erstellen
|
||||
const envExample = `# Skrift Backend - Production Environment Variables
|
||||
|
||||
# Scriptalizer API Configuration
|
||||
SCRIPTALIZER_LICENSE_KEY=f9918b40-d11c-11f0-b558-0800200c9a66
|
||||
SCRIPTALIZER_ERR_FREQUENCY=0
|
||||
|
||||
# Preview Settings
|
||||
BATCH_SIZE=30
|
||||
CACHE_LIFETIME_HOURS=2
|
||||
RATE_LIMIT_PER_MINUTE=2
|
||||
|
||||
# Environment
|
||||
NODE_ENV=production
|
||||
PORT=4000
|
||||
`;
|
||||
|
||||
await fs.writeFile(path.join(DEPLOY_DIR, '.env.example'), envExample);
|
||||
console.log('✅ Created: .env.example\n');
|
||||
|
||||
// README für Deployment erstellen
|
||||
const deployReadme = `# Skrift Backend - Deployment Package
|
||||
|
||||
Dieses Verzeichnis enthält alle notwendigen Dateien für das Deployment auf den Server.
|
||||
|
||||
## Schnellstart
|
||||
|
||||
### 1. Zum Server kopieren
|
||||
|
||||
\`\`\`bash
|
||||
# Mit SCP
|
||||
scp -r * root@DEIN-SERVER:/opt/skrift-backend/
|
||||
|
||||
# Oder mit rsync (falls verfügbar)
|
||||
rsync -avz ./ root@DEIN-SERVER:/opt/skrift-backend/
|
||||
\`\`\`
|
||||
|
||||
### 2. Auf dem Server einrichten
|
||||
|
||||
\`\`\`bash
|
||||
ssh root@DEIN-SERVER
|
||||
|
||||
cd /opt/skrift-backend
|
||||
|
||||
# .env erstellen (aus .env.example)
|
||||
cp .env.example .env
|
||||
nano .env # Prüfen und anpassen falls nötig
|
||||
|
||||
# Output-Verzeichnis erstellen
|
||||
mkdir -p /var/skrift-output
|
||||
chmod 755 /var/skrift-output
|
||||
|
||||
# Container starten
|
||||
docker-compose up -d --build
|
||||
|
||||
# Logs prüfen
|
||||
docker-compose logs -f
|
||||
\`\`\`
|
||||
|
||||
### 3. Testen
|
||||
|
||||
\`\`\`bash
|
||||
curl http://localhost:4000/health
|
||||
\`\`\`
|
||||
|
||||
## Enthaltene Dateien
|
||||
|
||||
- \`src/\` - Backend Source Code
|
||||
- \`fonts/\` - SVG Fonts (Tilda, Alva, Ellie)
|
||||
- \`Dockerfile\` - Docker Image Konfiguration
|
||||
- \`docker-compose.yml\` - Docker Compose Konfiguration
|
||||
- \`package.json\` - Node.js Dependencies
|
||||
- \`.env.example\` - Environment Variables Template
|
||||
|
||||
## Wichtig
|
||||
|
||||
⚠️ **SCRIPTALIZER_ERR_FREQUENCY=0** ist bereits gesetzt - keine durchgestrichenen Wörter!
|
||||
|
||||
## Nginx Proxy Manager
|
||||
|
||||
Nach dem Start in Nginx Proxy Manager konfigurieren:
|
||||
- Domain: backend.deine-domain.de
|
||||
- Forward to: skrift-backend:4000
|
||||
- SSL: Let's Encrypt aktivieren
|
||||
|
||||
## Support
|
||||
|
||||
Bei Problemen: \`docker-compose logs -f\`
|
||||
`;
|
||||
|
||||
await fs.writeFile(path.join(DEPLOY_DIR, 'README.txt'), deployReadme);
|
||||
console.log('✅ Created: README.txt\n');
|
||||
|
||||
// Upload-Script erstellen
|
||||
const uploadScript = `#!/bin/bash
|
||||
|
||||
# Skrift Backend - Upload Script
|
||||
# Dieses Script lädt das Backend auf den Server hoch
|
||||
|
||||
# KONFIGURATION - BITTE ANPASSEN!
|
||||
SERVER_USER="root"
|
||||
SERVER_HOST="" # z.B. "123.456.789.0" oder "dein-server.de"
|
||||
SERVER_PATH="/opt/skrift-backend"
|
||||
|
||||
# Farben für Output
|
||||
RED='\\033[0;31m'
|
||||
GREEN='\\033[0;32m'
|
||||
YELLOW='\\033[1;33m'
|
||||
NC='\\033[0m' # No Color
|
||||
|
||||
# Funktion: Fehler anzeigen und beenden
|
||||
error_exit() {
|
||||
echo -e "\${RED}❌ ERROR: \$1\${NC}" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Prüfen ob Server konfiguriert ist
|
||||
if [ -z "$SERVER_HOST" ]; then
|
||||
error_exit "SERVER_HOST ist nicht gesetzt! Bitte in upload.sh die Variable SERVER_HOST setzen."
|
||||
fi
|
||||
|
||||
echo -e "\${GREEN}🚀 Skrift Backend Upload\${NC}"
|
||||
echo "======================================"
|
||||
echo "Server: \$SERVER_USER@\$SERVER_HOST"
|
||||
echo "Path: \$SERVER_PATH"
|
||||
echo ""
|
||||
|
||||
# Prüfen ob SSH-Verbindung funktioniert
|
||||
echo -e "\${YELLOW}🔍 Testing SSH connection...\${NC}"
|
||||
ssh -o ConnectTimeout=5 -o BatchMode=yes \$SERVER_USER@\$SERVER_HOST "echo '✅ SSH connection successful'" || error_exit "SSH connection failed"
|
||||
echo ""
|
||||
|
||||
# Verzeichnis auf Server erstellen
|
||||
echo -e "\${YELLOW}📁 Creating directory on server...\${NC}"
|
||||
ssh \$SERVER_USER@\$SERVER_HOST "mkdir -p \$SERVER_PATH" || error_exit "Failed to create directory"
|
||||
echo ""
|
||||
|
||||
# Dateien hochladen
|
||||
echo -e "\${YELLOW}📤 Uploading files...\${NC}"
|
||||
scp -r * \$SERVER_USER@\$SERVER_HOST:\$SERVER_PATH/ || error_exit "Upload failed"
|
||||
echo ""
|
||||
|
||||
echo -e "\${GREEN}✅ Upload successful!\${NC}"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. SSH to server: ssh \$SERVER_USER@\$SERVER_HOST"
|
||||
echo "2. Go to directory: cd \$SERVER_PATH"
|
||||
echo "3. Create .env: cp .env.example .env"
|
||||
echo "4. Create output dir: mkdir -p /var/skrift-output"
|
||||
echo "5. Start container: docker-compose up -d --build"
|
||||
echo "6. Check logs: docker-compose logs -f"
|
||||
`;
|
||||
|
||||
await fs.writeFile(path.join(DEPLOY_DIR, 'upload.sh'), uploadScript);
|
||||
await fs.chmod(path.join(DEPLOY_DIR, 'upload.sh'), 0o755);
|
||||
console.log('✅ Created: upload.sh\n');
|
||||
|
||||
// Windows Batch Upload-Script
|
||||
const uploadBat = `@echo off
|
||||
REM Skrift Backend - Windows Upload Script
|
||||
|
||||
REM KONFIGURATION - BITTE ANPASSEN!
|
||||
set SERVER_USER=root
|
||||
set SERVER_HOST=
|
||||
set SERVER_PATH=/opt/skrift-backend
|
||||
|
||||
if "%SERVER_HOST%"=="" (
|
||||
echo ERROR: SERVER_HOST ist nicht gesetzt!
|
||||
echo Bitte in upload.bat die Variable SERVER_HOST setzen.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo ========================================
|
||||
echo Skrift Backend Upload
|
||||
echo ========================================
|
||||
echo Server: %SERVER_USER%@%SERVER_HOST%
|
||||
echo Path: %SERVER_PATH%
|
||||
echo.
|
||||
|
||||
echo Uploading files...
|
||||
echo.
|
||||
|
||||
scp -r * %SERVER_USER%@%SERVER_HOST%:%SERVER_PATH%/
|
||||
|
||||
if %ERRORLEVEL% NEQ 0 (
|
||||
echo.
|
||||
echo ERROR: Upload fehlgeschlagen!
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo Upload erfolgreich!
|
||||
echo ========================================
|
||||
echo.
|
||||
echo Naechste Schritte:
|
||||
echo 1. SSH to server: ssh %SERVER_USER%@%SERVER_HOST%
|
||||
echo 2. Go to directory: cd %SERVER_PATH%
|
||||
echo 3. Create .env: cp .env.example .env
|
||||
echo 4. Create output dir: mkdir -p /var/skrift-output
|
||||
echo 5. Start container: docker-compose up -d --build
|
||||
echo 6. Check logs: docker-compose logs -f
|
||||
echo.
|
||||
pause
|
||||
`;
|
||||
|
||||
await fs.writeFile(path.join(DEPLOY_DIR, 'upload.bat'), uploadBat);
|
||||
console.log('✅ Created: upload.bat\n');
|
||||
|
||||
// Statistik
|
||||
const stats = await getDirectoryStats(DEPLOY_DIR);
|
||||
|
||||
console.log('');
|
||||
console.log('📊 Deployment Package Stats:');
|
||||
console.log('=====================================');
|
||||
console.log(`📁 Total Files: ${stats.files}`);
|
||||
console.log(`📂 Total Directories: ${stats.dirs}`);
|
||||
console.log(`💾 Total Size: ${formatBytes(stats.size)}`);
|
||||
console.log('');
|
||||
console.log('✅ Deployment Package Ready!');
|
||||
console.log('');
|
||||
console.log(`📦 Location: ${DEPLOY_DIR}`);
|
||||
console.log('');
|
||||
console.log('Next steps:');
|
||||
console.log('1. Gehe ins Verzeichnis: cd DEPLOYMENT_READY');
|
||||
console.log('2. Passe upload.sh oder upload.bat an (SERVER_HOST setzen)');
|
||||
console.log('3. Führe aus: ./upload.sh (Linux/Mac) oder upload.bat (Windows)');
|
||||
}
|
||||
|
||||
async function getDirectoryStats(dir) {
|
||||
let files = 0;
|
||||
let dirs = 0;
|
||||
let size = 0;
|
||||
|
||||
const entries = await fs.readdir(dir, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
const fullPath = path.join(dir, entry.name);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
dirs++;
|
||||
const subStats = await getDirectoryStats(fullPath);
|
||||
files += subStats.files;
|
||||
dirs += subStats.dirs;
|
||||
size += subStats.size;
|
||||
} else {
|
||||
files++;
|
||||
const stat = await fs.stat(fullPath);
|
||||
size += stat.size;
|
||||
}
|
||||
}
|
||||
|
||||
return { files, dirs, size };
|
||||
}
|
||||
|
||||
function formatBytes(bytes) {
|
||||
if (bytes === 0) return '0 Bytes';
|
||||
const k = 1024;
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error('❌ Error:', err.message);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user