diff --git a/deploy/deploy.sh b/deploy/deploy.sh new file mode 100644 index 0000000..bc3919d --- /dev/null +++ b/deploy/deploy.sh @@ -0,0 +1,77 @@ +#!/bin/bash +set -e + +echo "🚀 SeCu Deployment Script" +echo "=========================" + +# Variables +DEPLOY_DIR="/srv/secu" +REPO_BASE="https://git.kronos-soulution.de/Flux_bot" + +# Create deployment directory +echo "📁 Creating deployment directory..." +mkdir -p $DEPLOY_DIR +cd $DEPLOY_DIR + +# Clone or pull repositories +echo "📥 Cloning/updating repositories..." + +for repo in secu secu-backend secu-frontend; do + if [ -d "$repo" ]; then + echo " Updating $repo..." + cd $repo && git pull && cd .. + else + echo " Cloning $repo..." + git clone $REPO_BASE/$repo.git + fi +done + +# Generate SSL certificates if not exist +echo "🔐 Checking SSL certificates..." +for domain in secu.kronos-soulution.de api.secu.kronos-soulution.de; do + if [ ! -d "/etc/letsencrypt/live/$domain" ]; then + echo " Generating certificate for $domain..." + certbot certonly --nginx -d $domain --non-interactive --agree-tos -m admin@kronos-soulution.de + fi +done + +# Copy nginx config +echo "🌐 Configuring Nginx..." +cp secu/deploy/nginx/secu.conf /etc/nginx/sites-available/secu.conf +ln -sf /etc/nginx/sites-available/secu.conf /etc/nginx/sites-enabled/ +nginx -t && systemctl reload nginx + +# Set JWT secret if not set +if [ -z "$JWT_SECRET" ]; then + export JWT_SECRET=$(openssl rand -base64 32) + echo "JWT_SECRET=$JWT_SECRET" >> /srv/secu/.env + echo "⚠️ Generated new JWT_SECRET - saved to /srv/secu/.env" +fi + +# Start services +echo "🐳 Starting Docker containers..." +cd secu/deploy +docker-compose down 2>/dev/null || true +docker-compose up -d + +# Wait for services +echo "⏳ Waiting for services to start..." +sleep 10 + +# Health check +echo "🏥 Health check..." +curl -sf http://localhost:8004/health && echo " Backend OK" || echo " Backend FAILED" +curl -sf http://localhost:3006 > /dev/null && echo " Frontend OK" || echo " Frontend FAILED" + +echo "" +echo "✅ Deployment complete!" +echo "" +echo "URLs:" +echo " Frontend: https://secu.kronos-soulution.de" +echo " API: https://api.secu.kronos-soulution.de" +echo "" +echo "Default Login (first user becomes Chef):" +echo " 1. Go to https://secu.kronos-soulution.de" +echo " 2. Click 'Registrieren'" +echo " 3. Organization: demo (or create new)" +echo " 4. Enter your details" diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml new file mode 100644 index 0000000..935e24d --- /dev/null +++ b/deploy/docker-compose.yml @@ -0,0 +1,65 @@ +version: '3.8' + +services: + secu-db: + image: postgres:16-alpine + container_name: secu-db + restart: unless-stopped + environment: + POSTGRES_USER: secu + POSTGRES_PASSWORD: SeCu2026!SecureDB + POSTGRES_DB: secu + volumes: + - secu-db-data:/var/lib/postgresql/data + - ../db/migrations:/docker-entrypoint-initdb.d:ro + ports: + - "5434:5432" + networks: + - secu-network + healthcheck: + test: ["CMD-SHELL", "pg_isready -U secu -d secu"] + interval: 10s + timeout: 5s + retries: 5 + + secu-backend: + image: denoland/deno:alpine + container_name: secu-backend + restart: unless-stopped + working_dir: /app + command: deno run --allow-net --allow-env --allow-read src/main.ts + environment: + DATABASE_URL: postgres://secu:SeCu2026!SecureDB@secu-db:5432/secu + JWT_SECRET: ${JWT_SECRET:-SeCu-Production-Secret-Change-Me-2026} + PORT: 8004 + volumes: + - ../../secu-backend:/app:ro + ports: + - "8004:8004" + networks: + - secu-network + depends_on: + secu-db: + condition: service_healthy + + secu-frontend: + image: node:20-alpine + container_name: secu-frontend + restart: unless-stopped + working_dir: /app + command: sh -c "npm install && npm run build && npx serve -s dist -l 3006" + environment: + VITE_API_URL: https://api.secu.kronos-soulution.de/api + volumes: + - ../../secu-frontend:/app + ports: + - "3006:3006" + networks: + - secu-network + +volumes: + secu-db-data: + +networks: + secu-network: + driver: bridge diff --git a/deploy/nginx/secu.conf b/deploy/nginx/secu.conf new file mode 100644 index 0000000..74936e2 --- /dev/null +++ b/deploy/nginx/secu.conf @@ -0,0 +1,55 @@ +# SeCu Frontend +server { + listen 80; + server_name secu.kronos-soulution.de; + return 301 https://$server_name$request_uri; +} + +server { + listen 443 ssl http2; + server_name secu.kronos-soulution.de; + + ssl_certificate /etc/letsencrypt/live/secu.kronos-soulution.de/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/secu.kronos-soulution.de/privkey.pem; + + location / { + proxy_pass http://localhost:3006; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_cache_bypass $http_upgrade; + } +} + +# SeCu API +server { + listen 80; + server_name api.secu.kronos-soulution.de; + return 301 https://$server_name$request_uri; +} + +server { + listen 443 ssl http2; + server_name api.secu.kronos-soulution.de; + + ssl_certificate /etc/letsencrypt/live/api.secu.kronos-soulution.de/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/api.secu.kronos-soulution.de/privkey.pem; + + client_max_body_size 10M; + + location / { + proxy_pass http://localhost:8004; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_cache_bypass $http_upgrade; + } +}