Fix Docker startup script and complete application deployment

- Update docker-start.sh to force correct profiles (qdrant, admin)
- Fix PostgreSQL port mapping from 5432 to 15432 across all configs
- Resolve MCP import conflicts by renaming src/mcp to src/mcp_servers
- Fix admin interface StaticFiles mount syntax error
- Update LLM client to support both Ollama and OpenAI-compatible APIs
- Configure host networking for Discord bot container access
- Correct database connection handling for async context managers
- Update environment variables and Docker compose configurations
- Add missing production dependencies and Dockerfile improvements
This commit is contained in:
root
2025-07-05 15:09:29 -07:00
parent 824b118e93
commit 3d9e8ffbf0
59 changed files with 1100 additions and 244 deletions

View File

@@ -224,6 +224,12 @@ class FishbowlSetup:
self.python_executable, "-m", "pip", "install", "-r", "requirements.txt"
], check=True)
self.print_info("Installing additional production dependencies...")
additional_deps = ["asyncpg", "python-dotenv"]
subprocess.run([
self.python_executable, "-m", "pip", "install"
] + additional_deps, check=True)
self.print_success("All Python dependencies installed successfully")
except subprocess.CalledProcessError as e:
self.print_error(f"Failed to install dependencies: {e}")
@@ -294,7 +300,7 @@ class FishbowlSetup:
self.config["database"] = {
"type": "postgresql",
"host": "localhost",
"port": 5432,
"port": 15432,
"name": "discord_fishbowl",
"username": "postgres",
"password": self.ask_question("Database password", "fishbowl_password"),
@@ -305,7 +311,7 @@ class FishbowlSetup:
self.config["database"] = {
"type": "postgresql",
"host": self.ask_question("PostgreSQL host", "localhost"),
"port": int(self.ask_question("PostgreSQL port", "5432")),
"port": int(self.ask_question("PostgreSQL port", "15432")),
"name": self.ask_question("Database name", "discord_fishbowl"),
"username": self.ask_question("Database username", "postgres"),
"password": self.ask_question("Database password", secret=True),
@@ -378,7 +384,7 @@ class FishbowlSetup:
self.config["vector_db"] = {
"type": "chromadb",
"host": "localhost",
"port": 8000,
"port": 8001,
"use_docker": True
}
self.use_docker_services = True
@@ -738,10 +744,17 @@ python -m src.admin.app
f.write(docker_env_content)
self.print_success("Docker environment file created")
# Start Docker services
if self.ask_yes_no("Start Docker services now?", True):
# Ask which Docker setup to use
docker_choices = [
"Services only (PostgreSQL, Redis, ChromaDB)",
"Complete application stack (includes Discord bot and admin interface)",
"Don't start services now"
]
docker_choice = self.ask_choice("Choose Docker setup:", docker_choices, 1)
if "Services only" in docker_choice:
try:
self.print_info("Starting PostgreSQL and Redis containers...")
self.print_info("Starting PostgreSQL, Redis, and ChromaDB containers...")
subprocess.run([
"docker", "compose", "-f", "docker-compose.services.yml",
"--env-file", ".env.docker", "up", "-d"
@@ -759,8 +772,46 @@ python -m src.admin.app
except subprocess.CalledProcessError as e:
self.print_error(f"Failed to start Docker services: {e}")
self.print_info("You can start them manually with: docker compose -f docker-compose.services.yml up -d")
elif "Complete application" in docker_choice:
try:
self.print_info("Building and starting complete Docker stack...")
self.print_warning("This will build the application container, which may take a few minutes...")
# Determine vector database profile
cmd = ["docker", "compose", "--env-file", ".env.docker"]
if self.config["vector_db"]["type"] == "chromadb":
cmd.extend(["--profile", "chromadb"])
elif self.config["vector_db"]["type"] == "qdrant":
cmd.extend(["--profile", "qdrant"])
cmd.extend(["up", "-d", "--build"])
subprocess.run(cmd, check=True, cwd=self.project_root)
self.print_success("Complete Docker stack started successfully")
self.print_success("Discord Fishbowl services are now running!")
print("\n📍 Services available at:")
print(" 🤖 Discord Fishbowl App: Running in container")
print(" 🌐 Admin Interface: http://localhost:8000")
print(" 📊 PostgreSQL: localhost:15432")
print(" 🔴 Redis: localhost:6379")
# Show correct vector database
if self.config["vector_db"]["type"] == "chromadb":
print(" 🧠 ChromaDB: http://localhost:8001")
elif self.config["vector_db"]["type"] == "qdrant":
print(" 🔍 Qdrant: http://localhost:6333")
print(" Dashboard: http://localhost:6333/dashboard")
print("\n💡 Use './docker-start.sh' to restart the complete stack later")
except subprocess.CalledProcessError as e:
self.print_error(f"Failed to start complete Docker stack: {e}")
self.print_info("You can start it manually with: ./docker-start.sh")
else:
self.print_info("To start services later: docker compose -f docker-compose.services.yml --env-file .env.docker up -d")
self.print_info("Docker services not started. You can start them later with:")
print(" Services only: docker compose -f docker-compose.services.yml --env-file .env.docker up -d")
print(" Complete stack: ./docker-start.sh")
def create_docker_env_content(self) -> str:
"""Create Docker environment file content"""
@@ -770,22 +821,64 @@ python -m src.admin.app
"",
]
# Database configuration
if self.config["database"].get("use_docker"):
lines.extend([
"# Database",
f"DB_PASSWORD={self.config['database']['password']}",
"",
])
# Redis configuration
if self.config["redis"].get("use_docker"):
lines.extend([
"# Redis",
f"REDIS_PASSWORD={self.config['redis']['password']}",
"",
])
# Discord configuration
lines.extend([
"# Discord Bot (Replace with your actual tokens)",
f"DISCORD_BOT_TOKEN={self.config['discord']['token']}",
f"DISCORD_GUILD_ID={self.config['discord']['guild_id']}",
f"DISCORD_CHANNEL_ID={self.config['discord']['channel_id']}",
"",
])
# LLM configuration
lines.extend([
"# LLM Configuration",
f"LLM_BASE_URL={self.config['ai']['api_base']}",
f"LLM_MODEL={self.config['ai']['model']}",
"",
])
# Vector database configuration
if self.config.get("vector_db", {}).get("type") in ["chromadb", "qdrant"]:
lines.extend([
"# Vector Database",
f"VECTOR_DB_TYPE={self.config['vector_db']['type']}",
"",
])
# Admin interface configuration
lines.extend([
"# Admin Interface",
f"SECRET_KEY={self.config['admin']['secret_key']}",
f"ADMIN_USERNAME={self.config['admin']['admin_username']}",
f"ADMIN_PASSWORD={self.config['admin']['admin_password']}",
"",
])
# Optional services
lines.extend([
"# Optional PgAdmin credentials (if using --profile admin)",
"PGADMIN_PASSWORD=admin123",
"",
"# Logging",
"LOG_LEVEL=INFO",
"",
])
return "\n".join(lines)
@@ -828,10 +921,15 @@ python -m src.admin.app
# How to start
print("🚀 To start the fishbowl:")
if platform.system() == "Windows":
print(" > start.bat")
if self.use_docker_services:
print(" Complete Docker stack: $ ./docker-start.sh")
print(" Services only: $ docker compose -f docker-compose.services.yml up -d")
print(" Local development: $ ./start.sh")
else:
print(" $ ./start.sh")
if platform.system() == "Windows":
print(" > start.bat")
else:
print(" $ ./start.sh")
print()
# Admin interface