Files
ai-stack-deployer/README.md
Oussama Douhou 3d056f1348 refactor: update default stack image to flexinit/agent-stack
Replace oh-my-opencode-free references with the new consolidated
flexinit/agent-stack image in source code and documentation.
2026-01-10 22:10:21 +01:00

380 lines
8.9 KiB
Markdown

# AI Stack Deployer
# ***NEVER FORGET THE PRINCIPLES RULES***
> Self-service portal for deploying personal OpenCode AI coding assistant stacks
[![Powered by Dokploy](https://img.shields.io/badge/Powered%20by-Dokploy-blue)](https://dokploy.com)
[![Built with Bun](https://img.shields.io/badge/Built%20with-Bun-black)](https://bun.sh)
[![Hono Framework](https://img.shields.io/badge/Framework-Hono-orange)](https://hono.dev)
## Overview
AI Stack Deployer is a production-ready web application that allows users to deploy their own personal AI coding assistant in seconds. Each deployment creates a fully functional OpenCode instance at `{name}.ai.flexinit.nl` with automatic HTTPS via wildcard SSL certificate.
### Key Features
- **One-Click Deployment**: Deploy AI stacks with a single form submission
- **Real-Time Progress**: SSE-powered live updates during deployment
- **Name Validation**: Real-time availability checking and format validation
- **Modern UI**: Responsive design with smooth animations
- **Production Ready**: Docker containerized with health checks
- **No DNS Setup**: Leverages pre-configured wildcard DNS and SSL
## Architecture
```
User Browser
AI Stack Deployer (Hono + Bun)
Dokploy API (10.100.0.20:3000)
Traefik (*.ai.flexinit.nl → 144.76.116.169)
User's AI Stack Container (OpenCode + ttyd)
```
### Technology Stack
- **Runtime**: Bun 1.3+
- **Framework**: Hono 4.11.3
- **Language**: TypeScript
- **Container**: Docker with multi-stage builds
- **Orchestration**: Dokploy
- **Reverse Proxy**: Traefik with wildcard SSL
## Quick Start
### Prerequisites
- Bun 1.3 or higher
- Docker (for containerized deployment)
- Valid Dokploy API token
- Access to Dokploy instance at `http://10.100.0.20:3000`
### Local Development
1. **Clone and Install**:
```bash
git clone <repository-url>
cd ai-stack-deployer
bun install
```
2. **Configure Environment**:
```bash
cp .env.example .env
# Edit .env and add your DOKPLOY_API_TOKEN
```
3. **Run Development Server**:
```bash
bun run dev
```
4. **Access the Application**:
Open http://localhost:3000 in your browser
### Production Deployment
#### Option 1: Docker Compose (Recommended)
```bash
# Build and run
docker-compose up -d
# View logs
docker-compose logs -f
# Stop
docker-compose down
```
#### Option 2: Manual Docker
```bash
# Build
docker build -t ai-stack-deployer:latest .
# Run
docker run -d \
--name ai-stack-deployer \
-p 3000:3000 \
--env-file .env \
ai-stack-deployer:latest
# Check health
curl http://localhost:3000/health
```
#### Option 3: Deploy to Dokploy
1. Build and push to registry:
```bash
docker build -t your-registry/ai-stack-deployer:latest .
docker push your-registry/ai-stack-deployer:latest
```
2. In Dokploy UI:
- Create project: `ai-stack-deployer-portal`
- Create application from Docker image
- Set domain: `portal.ai.flexinit.nl`
- Configure environment variables
- Deploy
3. Verify:
```bash
curl https://portal.ai.flexinit.nl/health
```
## API Documentation
### Endpoints
#### Health Check
```http
GET /health
```
Response:
```json
{
"status": "healthy",
"timestamp": "2026-01-09T12:00:00.000Z",
"version": "0.1.0",
"service": "ai-stack-deployer",
"activeDeployments": 0
}
```
#### Check Name Availability
```http
GET /api/check/:name
```
Response:
```json
{
"available": true,
"valid": true,
"name": "john-dev"
}
```
#### Deploy Stack
```http
POST /api/deploy
Content-Type: application/json
{
"name": "john-dev"
}
```
Response:
```json
{
"success": true,
"deploymentId": "dep_1234567890_abc123",
"url": "https://john-dev.ai.flexinit.nl",
"statusEndpoint": "/api/status/dep_1234567890_abc123"
}
```
#### Deployment Status (SSE)
```http
GET /api/status/:deploymentId
```
Server-Sent Events stream with progress updates:
```
event: progress
data: {"status":"creating_project","progress":25,"currentStep":"Creating Dokploy project"}
event: progress
data: {"status":"creating_application","progress":50,"currentStep":"Creating application container"}
event: progress
data: {"status":"deploying","progress":85,"currentStep":"Deploying application"}
event: complete
data: {"url":"https://john-dev.ai.flexinit.nl","status":"ready"}
```
## Environment Variables
### Required
- `DOKPLOY_URL` - Dokploy API URL (default: `http://10.100.0.20:3000`)
- `DOKPLOY_API_TOKEN` - Dokploy API authentication token
### Optional
- `PORT` - HTTP server port (default: `3000`)
- `HOST` - Bind address (default: `0.0.0.0`)
- `STACK_DOMAIN_SUFFIX` - Domain suffix for stacks (default: `ai.flexinit.nl`)
- `STACK_IMAGE` - Docker image for user stacks (default: `git.app.flexinit.nl/flexinit/agent-stack:latest`)
- `RESERVED_NAMES` - Comma-separated forbidden names (default: `admin,api,www,root,system,test,demo,portal`)
### Not Used in Deployment
- `HETZNER_API_TOKEN` - Only for testing/manual DNS operations
- `HETZNER_ZONE_ID` - DNS zone ID (343733 for flexinit.nl)
- `TRAEFIK_IP` - Public IP reference (144.76.116.169)
## Name Validation Rules
Stack names must follow these rules:
- 3-20 characters long
- Lowercase letters (a-z), numbers (0-9), and hyphens (-) only
- Cannot start or end with a hyphen
- Cannot be a reserved name (admin, api, www, root, system, test, demo, portal)
## Development
### Commands
```bash
# Development server with hot reload
bun run dev
# Production server
bun run start
# MCP server (for Claude Code integration)
bun run mcp
# Type checking
bun run typecheck
# Build for production
bun run build
# Test API clients
bun run src/test-clients.ts
```
### Project Structure
```
ai-stack-deployer/
├── src/
│ ├── api/
│ │ ├── dokploy.ts # Dokploy API client
│ │ └── hetzner.ts # Hetzner DNS client (testing only)
│ ├── frontend/
│ │ ├── index.html # Web UI
│ │ ├── style.css # Styles
│ │ └── app.js # Frontend logic
│ ├── index.ts # HTTP server (production)
│ ├── mcp-server.ts # MCP server (development)
│ └── test-clients.ts # API client tests
├── Dockerfile # Multi-stage Docker build
├── docker-compose.yml # Docker Compose configuration
├── .dockerignore # Docker build exclusions
├── CLAUDE.md # Claude Code guidance
└── README.md # This file
```
### MCP Server (Development Tool)
The MCP server provides Claude Code integration for deployment automation:
```bash
# Start MCP server
bun run mcp
```
Available MCP tools:
- `deploy_stack` - Deploy a new AI stack
- `check_deployment_status` - Query deployment progress
- `list_deployments` - List all deployments
- `check_name_availability` - Validate stack name
- `test_api_connections` - Test Dokploy connectivity
## Infrastructure Requirements
### Pre-configured Components
- **Wildcard DNS**: `*.ai.flexinit.nl` → `144.76.116.169`
- **Traefik**: Wildcard SSL certificate for `*.ai.flexinit.nl`
- **Dokploy**: Running at `http://10.100.0.20:3000`
- **OpenCode Image**: `git.app.flexinit.nl/flexinit/agent-stack:latest`
### Network Access
The deployer must be able to reach:
- Dokploy API at `10.100.0.20:3000` (internal network)
- No public internet access required for deployment
- Frontend users connect via Traefik at `144.76.116.169`
## Troubleshooting
### Health Check Failing
```bash
# Check if server is running
curl http://localhost:3000/health
# Check Docker logs
docker-compose logs -f ai-stack-deployer
# Restart container
docker-compose restart
```
### Deployment Stuck
1. Check Dokploy API connectivity:
```bash
curl -H "x-api-key: YOUR_TOKEN" http://10.100.0.20:3000/api/project.all
```
2. View deployment logs in browser console (F12)
3. Check server logs for errors:
```bash
docker-compose logs -f | grep ERROR
```
### Name Already Taken
If a deployment fails but the name is marked as taken:
1. Check Dokploy UI for the project `ai-stack-{name}`
2. Delete the partial deployment if present
3. Try deployment again
## Security Notes
- All API tokens stored in environment variables (never in code)
- Dokploy API accessible only on internal network
- No authentication on HTTP endpoints (add if exposing publicly)
- Name validation prevents injection attacks
- Container runs as non-root user (nodejs:1001)
## Performance
- **Deployment Time**: ~2-3 minutes per stack
- **Concurrent Deployments**: No limit (background processing)
- **Memory Usage**: ~50MB base + ~10MB per active deployment
- **State Persistence**: In-memory only (implement database for persistence)
## Contributing
See `CLAUDE.md` for development guidelines and architecture documentation.
## License
[Your License Here]
## Support
For issues or questions:
- Check the troubleshooting section above
- Review logs: `docker-compose logs -f`
- Verify environment variables in `.env`
---
**Built with ❤️ using Bun, Hono, and Dokploy**