#!/bin/bash set -e mkdir -p logs download_cache app/files echo "BUILD_HASH = \"$(python3 -c 'import uuid, hashlib; print(hashlib.sha256(uuid.uuid4().bytes).hexdigest()[:8])')\"" > app/build_version.py cat <<'EOF' __ __ __ __ / | / | / | / | $$ | $$ | ______ ______ _$$ |_ ______ __ __ $$/ $$ | $$ |/ \ / \ / $$ | / \ / \ / |/ | $$ \ /$$//$$$$$$ |/$$$$$$ |$$$$$$/ /$$$$$$ |$$ \/$$/ $$ | $$ /$$/ $$ | $$ |$$ | $$/ $$ | __ $$ $$ | $$ $$< $$ | $$ $$/ $$ \__$$ |$$ | $$ |/ |$$$$$$$$/ /$$$$ \ $$ | $$$/ $$ $$/ $$ | $$ $$/ $$ |/$$/ $$ |$$ | $/ $$$$$$/ $$/ $$$$/ $$$$$$$/ $$/ $$/ $$/ EOF python3 - <<'PYEOF' import os from app.config import Config from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.backends import default_backend def generate_key_if_missing(key_size: int, priv_path: str, pub_path: str): if os.path.exists(priv_path): return parent_dir = os.path.dirname(priv_path) if parent_dir: os.makedirs(parent_dir, exist_ok=True) priv_key = rsa.generate_private_key( public_exponent=65537, key_size=key_size, backend=default_backend() ) with open(priv_path, "wb") as f: f.write( priv_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption() ) ) with open(pub_path, "wb") as f: f.write( priv_key.public_key().public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ) ) def generate_ms_blob_if_missing(pub_path: str, blob_path: str): if os.path.exists(blob_path) or not os.path.exists(pub_path): return try: import struct, base64 with open(pub_path, "rb") as f: pub_key = serialization.load_pem_public_key(f.read(), backend=default_backend()) blobheader = struct.pack('/dev/null 2>&1; then openssl rsa -pubin -inform PEM -in ./app/files/rsa_public_1024.pub -outform "MS PUBLICKEYBLOB" 2>/dev/null | base64 > ./app/files/2016pub.blob || true openssl rsa -pubin -inform PEM -in ./app/files/rsa_public_2048.pub -outform "MS PUBLICKEYBLOB" 2>/dev/null | base64 > ./app/files/2018pub.blob || true fi python3 - <<'PYEOF' import time import sys import redis import psycopg2 from app.config import Config max_retries = 30 for i in range(max_retries): try: r = redis.from_url(Config.FLASK_LIMITED_STORAGE_URI) r.ping() break except Exception as e: print(f"Waiting for Redis ({i+1}/{max_retries})...") time.sleep(2) else: print("Redis connection timeout.") sys.exit(1) for i in range(max_retries): try: conn = psycopg2.connect(Config.SQLALCHEMY_DATABASE_URI) conn.close() break except Exception as e: print(f"Waiting for PostgreSQL database ({i+1}/{max_retries})...") time.sleep(2) else: print("Database connection timeout.") sys.exit(1) from app import create_app from app.extensions import db from app.models.user import User from app.shell_commands import create_admin_user app = create_app() with app.app_context(): db.create_all() if User.query.filter_by(id=1).first() is None: try: create_admin_user() except Exception as e: print(f"Admin initialization notice: {e}") PYEOF echo "Version - $(python3 -c 'import app.build_version as v; print(v.BUILD_HASH)') (prod)" echo "Running Vortexi OSS at $(date)" exec gunicorn -b 0.0.0.0:3003 --preload --workers=4 --threads=10 "app:create_app()"