From 41d2dcf3d07ebb578a0e0514eabc75954d4f3a67 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 2 Jan 2026 21:45:28 +0000 Subject: [PATCH 1/4] Initial plan From c992aa979385a6f5067994b19c073321a85e7352 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 2 Jan 2026 21:56:54 +0000 Subject: [PATCH 2/4] Add comprehensive MySQL documentation across core files - Updated README.md with MySQL support in features and config - Expanded database-selection.md with MySQL comparison and production HA guidance - Enhanced internal/database/README.md with MySQL references - Updated getting-started/configuration.md with MySQL configuration - Added MySQL to docs/README.md quick reference - Updated Helm chart and deployment docs with MySQL and HA warnings - Added CHANGELOG entry for MySQL documentation Co-authored-by: mfittko <326798+mfittko@users.noreply.github.com> --- CHANGELOG.md | 1 + README.md | 17 +++- deploy/helm/llm-proxy/README.md | 16 +++- docs/README.md | 7 +- docs/database/database-selection.md | 132 +++++++++++++++++++++++--- docs/deployment/helm.md | 33 +++++++ docs/getting-started/configuration.md | 29 +++++- internal/database/README.md | 28 +++--- 8 files changed, 227 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58784bd2..dcc3446d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Common Changelog](https://common-changelog.org/). ### Added +- **MySQL Documentation** ([#246](https://github.com/sofatutor/llm-proxy/pull/246)): Comprehensive documentation updates for MySQL support including README updates, database selection guide, Helm deployment docs, configuration reference, architecture docs, and production HA guidance so users can confidently deploy and operate llm-proxy with MySQL alongside SQLite and PostgreSQL. - **MySQL Helm Chart Support** ([#255](https://github.com/sofatutor/llm-proxy/pull/255)): Adds comprehensive MySQL support to the Helm chart with values, templates, helper functions, deployment integration, and updated docs so users can deploy llm-proxy with MySQL alongside SQLite and PostgreSQL. - **MySQL Compose Profile** ([#253](https://github.com/sofatutor/llm-proxy/pull/253)): Added optional MySQL backend with dedicated Docker Compose services, build flags, docs, and environment vars so teams can run isolated dev and test stacks alongside existing databases. - **MySQL Integration Suite** ([#256](https://github.com/sofatutor/llm-proxy/pull/256)): Introduced comprehensive MySQL integration tests and helpers covering connections, migrations, CRUD operations, concurrency, transactions, and stats so the suite can be exercised locally and validated in CI. diff --git a/README.md b/README.md index 30314410..2370a603 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ A transparent, secure proxy for OpenAI's API with token management, rate limitin - **Async Event Bus & Dispatcher**: All API instrumentation events are handled via an always-on, fully asynchronous event bus (in-memory or Redis) with support for multiple subscribers, batching, retry logic, and graceful shutdown. Persistent event logging is handled by a dispatcher CLI or the `--file-event-log` flag. - **OpenAI Token Counting**: Accurate prompt and completion token counting using tiktoken-go. - **Metrics Endpoint (provider-agnostic)**: Optional JSON metrics endpoint; Prometheus scraping/export is optional and not required by core features -- **Multiple Database Support**: SQLite (default) and PostgreSQL with automatic migrations +- **Multiple Database Support**: SQLite (default), PostgreSQL, and MySQL with automatic migrations - **Database Migrations**: Version-controlled schema changes with rollback support. See [Migration Guide](docs/database/migrations.md) - **Docker Deployment** @@ -101,7 +101,7 @@ MANAGEMENT_TOKEN=your-secure-management-token ./bin/llm-proxy - `FILE_EVENT_LOG`: Path to persistent event log file (enables file event logging via dispatcher) ### Database Configuration -The LLM Proxy supports **SQLite** (default) and **PostgreSQL** as database backends. +The LLM Proxy supports **SQLite** (default), **PostgreSQL**, and **MySQL** as database backends. **SQLite (default):** - `DB_DRIVER`: Database driver, set to `sqlite` (default) @@ -111,12 +111,21 @@ The LLM Proxy supports **SQLite** (default) and **PostgreSQL** as database backe - `DB_DRIVER`: Set to `postgres` for PostgreSQL - `DATABASE_URL`: PostgreSQL connection string (e.g., `postgres://user:password@localhost:5432/llmproxy?sslmode=require`) -**Connection Pool (both drivers):** +**MySQL:** +- `DB_DRIVER`: Set to `mysql` for MySQL +- `DATABASE_URL`: MySQL connection string (e.g., `llmproxy:secret@tcp(localhost:3306)/llmproxy?parseTime=true&tls=true`) + +**Connection Pool (all drivers):** - `DATABASE_POOL_SIZE`: Maximum open connections (default `10`) - `DATABASE_MAX_IDLE_CONNS`: Maximum idle connections (default `5`) - `DATABASE_CONN_MAX_LIFETIME`: Connection max lifetime (default `1h`) -See [PostgreSQL Setup Guide](docs/database/docker-compose-postgres.md) for detailed PostgreSQL configuration. +**Build Requirements:** +- SQLite: No build tags required (included by default) +- PostgreSQL: Requires `-tags postgres` build flag +- MySQL: Requires `-tags mysql` build flag + +See [Database Selection Guide](docs/database/database-selection.md) for choosing the right database, or the [PostgreSQL Setup Guide](docs/database/docker-compose-postgres.md) and [MySQL Setup Guide](docs/database/docker-compose-mysql.md) for detailed configuration. ### Caching Configuration - `HTTP_CACHE_ENABLED`: Enable HTTP response caching (default `true`) diff --git a/deploy/helm/llm-proxy/README.md b/deploy/helm/llm-proxy/README.md index 6a0c5cd5..5280c172 100644 --- a/deploy/helm/llm-proxy/README.md +++ b/deploy/helm/llm-proxy/README.md @@ -202,7 +202,13 @@ helm install llm-proxy deploy/helm/llm-proxy \ ``` **IMPORTANT:** -- In-cluster PostgreSQL is for development/testing only, NOT recommended for production +- **⚠️ For production high-availability (HA) deployments, use an external managed PostgreSQL service:** + - Amazon Aurora PostgreSQL / Amazon RDS for PostgreSQL + - Google Cloud SQL for PostgreSQL + - Azure Database for PostgreSQL + - Self-managed PostgreSQL with replication +- The in-cluster PostgreSQL StatefulSet is hardcoded to `replicas: 1` and is suitable for **development/testing only** +- It does not provide high availability or automatic failover - Ensure your Docker image is built with PostgreSQL support using the `postgres` build tag - Default images are built with: `docker build --build-arg POSTGRES_SUPPORT=true` - You cannot use both in-cluster and external PostgreSQL simultaneously @@ -261,7 +267,13 @@ helm install llm-proxy deploy/helm/llm-proxy \ ``` **IMPORTANT:** -- In-cluster MySQL is for development/testing only, NOT recommended for production +- **⚠️ For production high-availability (HA) deployments, use an external managed MySQL service:** + - Amazon Aurora MySQL / Amazon RDS for MySQL + - Google Cloud SQL for MySQL + - Azure Database for MySQL + - Self-managed MySQL Group Replication or InnoDB Cluster +- The in-cluster MySQL StatefulSet is hardcoded to `replicas: 1` and is suitable for **development/testing only** +- It does not provide high availability or automatic failover - Ensure your Docker image is built with MySQL support using the `mysql` build tag - Build command: `docker build --build-arg MYSQL_SUPPORT=true -t llm-proxy:mysql .` - You cannot use both in-cluster and external MySQL simultaneously diff --git a/docs/README.md b/docs/README.md index 56961b10..dd00dddb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -33,7 +33,8 @@ Start with the main [README](../README.md) for a quick overview, then follow the - **[API Configuration](guides/api-configuration.md)** - Configure API providers, endpoints, and security policies - **[Security Best Practices](deployment/security.md)** - Production security, secrets management, and hardening - **[Docker Compose PostgreSQL Setup](database/docker-compose-postgres.md)** - Run llm-proxy with PostgreSQL using Docker Compose -- **[Database Selection Guide](database/database-selection.md)** - Choose between SQLite and PostgreSQL +- **[Docker Compose MySQL Setup](database/docker-compose-mysql.md)** - Run llm-proxy with MySQL using Docker Compose +- **[Database Selection Guide](database/database-selection.md)** - Choose between SQLite, PostgreSQL, and MySQL - **[Database Migrations Guide](database/migrations.md)** - Version-controlled schema changes ## Observability & Monitoring @@ -87,9 +88,9 @@ The [OpenAPI specification](../api/openapi.yaml) provides machine-readable API d |----------|---------|---------| | `MANAGEMENT_TOKEN` | Admin API access | **Required** | | `LISTEN_ADDR` | Server address | `:8080` | -| `DB_DRIVER` | Database driver (`sqlite` or `postgres`) | `sqlite` | +| `DB_DRIVER` | Database driver (`sqlite`, `postgres`, or `mysql`) | `sqlite` | | `DATABASE_PATH` | SQLite database path | `./data/llm-proxy.db` | -| `DATABASE_URL` | PostgreSQL connection string | - | +| `DATABASE_URL` | PostgreSQL or MySQL connection string | - | | `LOG_LEVEL` | Logging level | `info` | | `HTTP_CACHE_ENABLED` | Enable response caching | `true` | | `HTTP_CACHE_BACKEND` | Cache backend (`in-memory` or `redis`) | `in-memory` | diff --git a/docs/database/database-selection.md b/docs/database/database-selection.md index 235a3c46..d5ced3d3 100644 --- a/docs/database/database-selection.md +++ b/docs/database/database-selection.md @@ -10,15 +10,18 @@ This guide helps you choose between SQLite and PostgreSQL for your LLM Proxy dep ## Overview -The LLM Proxy supports two database backends: - -| Feature | SQLite | PostgreSQL | -|---------|--------|------------| -| Setup Complexity | Zero configuration | Requires server setup | -| Scalability | Single instance | Multiple instances | -| Concurrent Writes | Limited | Excellent | -| Best For | Development, small deployments | Production, high-traffic | -| Maintenance | None | Requires DBA knowledge | +The LLM Proxy supports three database backends: + +| Feature | SQLite | PostgreSQL | MySQL | +|---------|--------|------------|-------| +| Setup Complexity | Zero configuration | Requires server setup | Requires server setup | +| Scalability | Single instance | Multiple instances | Multiple instances | +| Concurrent Writes | Limited | Excellent | Excellent | +| Best For | Development, small deployments | Production, high-traffic | Production, web apps | +| Build Tag Required | No | Yes (`-tags postgres`) | Yes (`-tags mysql`) | +| Maintenance | None | Requires DBA knowledge | Requires DBA knowledge | +| Cloud Managed Options | N/A | RDS, Aurora, Cloud SQL, Azure | RDS, Aurora, Cloud SQL, Azure | +| In-Cluster Helm | N/A | Dev/Test only (single replica) | Dev/Test only (single replica) | ## SQLite (Default) @@ -112,9 +115,100 @@ DATABASE_URL=postgres://user@server:pass@server.postgres.database.azure.com:5432 - **Concurrent connections**: Thousands with proper configuration - **Recommended**: 100+ requests/second, multiple instances +### Production Deployment + +**⚠️ For production high-availability (HA) deployments, use an external managed PostgreSQL service:** +- Amazon Aurora PostgreSQL / Amazon RDS for PostgreSQL +- Google Cloud SQL for PostgreSQL +- Azure Database for PostgreSQL +- Self-managed PostgreSQL with replication + +**Important:** The in-cluster PostgreSQL StatefulSet in the Helm chart is hardcoded to `replicas: 1` and is suitable for **development/testing only**. It does not provide high availability or automatic failover. + +## MySQL + +MySQL is recommended for production deployments, especially for teams already familiar with MySQL or using MySQL-based infrastructure. + +### When to Use MySQL + +- **Production deployments** - Excellent reliability and wide ecosystem +- **High traffic** - Handles thousands of concurrent connections +- **Multiple instances** - Required for horizontal scaling +- **MySQL familiarity** - Team has existing MySQL expertise +- **MySQL infrastructure** - Already using MySQL for other services + +### Configuration + +```bash +export DB_DRIVER=mysql +export DATABASE_URL=llmproxy:secret@tcp(localhost:3306)/llmproxy?parseTime=true&tls=true + +# Optional: Connection pool settings +export DATABASE_POOL_SIZE=10 +export DATABASE_MAX_IDLE_CONNS=5 +export DATABASE_CONN_MAX_LIFETIME=1h +``` + +### Connection String Format + +``` +[user]:[password]@tcp([host]:[port])/[database]?parseTime=true&tls=[mode] +``` + +**TLS/SSL Options:** + +| Parameter | Description | Use Case | +|-----------|-------------|----------| +| `tls=false` | No TLS | Development only | +| `tls=true` | TLS with system CA verification | Production (recommended) | +| `tls=skip-verify` | TLS without certificate verification | Not recommended | +| `tls=custom` | TLS with custom CA | Advanced configurations | + +**Examples:** + +```bash +# Local development (no TLS) +DATABASE_URL=llmproxy:secret@tcp(localhost:3306)/llmproxy?parseTime=true + +# Production with TLS +DATABASE_URL=llmproxy:secret@tcp(localhost:3306)/llmproxy?parseTime=true&tls=true + +# AWS RDS MySQL +DATABASE_URL=admin:password@tcp(mydb.xxx.rds.amazonaws.com:3306)/llmproxy?parseTime=true&tls=true + +# Google Cloud SQL MySQL +DATABASE_URL=root:password@tcp(10.x.x.x:3306)/llmproxy?parseTime=true&tls=true + +# Azure Database for MySQL +DATABASE_URL=admin@server:password@tcp(server.mysql.database.azure.com:3306)/llmproxy?parseTime=true&tls=true +``` + +### Performance Characteristics + +- **Read performance**: Excellent with proper indexing +- **Write performance**: Excellent with connection pooling +- **Concurrent connections**: Thousands with proper configuration +- **Recommended**: 100+ requests/second, multiple instances + +### Compatibility + +- **Minimum Version**: MySQL 8.0+ +- **MariaDB Support**: MariaDB 10.5+ is compatible +- **Build Requirement**: Binary must be built with `-tags mysql` flag + +### Production Deployment + +**⚠️ For production high-availability (HA) deployments, use an external managed MySQL service:** +- Amazon Aurora MySQL / Amazon RDS for MySQL +- Google Cloud SQL for MySQL +- Azure Database for MySQL +- Self-managed MySQL Group Replication or InnoDB Cluster + +**Important:** The in-cluster MySQL StatefulSet in the Helm chart is hardcoded to `replicas: 1` and is suitable for **development/testing only**. It does not provide high availability or automatic failover. + ## Migration Between Databases -### SQLite to PostgreSQL +### SQLite to PostgreSQL or MySQL 1. **Export data from SQLite:** @@ -123,17 +217,26 @@ DATABASE_URL=postgres://user@server:pass@server.postgres.database.azure.com:5432 sqlite3 data/llm-proxy.db ".dump tokens" > tokens.sql ``` -2. **Start PostgreSQL:** +2. **Start target database:** ```bash + # PostgreSQL docker compose --profile postgres up -d postgres + + # MySQL + docker compose --profile mysql up -d mysql ``` 3. **Update configuration:** ```bash + # For PostgreSQL export DB_DRIVER=postgres export DATABASE_URL=postgres://llmproxy:secret@localhost:5432/llmproxy?sslmode=disable + + # For MySQL + export DB_DRIVER=mysql + export DATABASE_URL=llmproxy:secret@tcp(localhost:3306)/llmproxy?parseTime=true ``` 4. **Start the proxy** (migrations run automatically): @@ -145,15 +248,16 @@ DATABASE_URL=postgres://user@server:pass@server.postgres.database.azure.com:5432 5. **Import data** (requires SQL syntax adaptation): ```bash - # Note: SQLite and PostgreSQL SQL dialects differ + # Note: SQLite, PostgreSQL, and MySQL SQL dialects differ # Manual adjustment of exported SQL may be required ``` ### Considerations -- **Schema migrations**: Run automatically on startup for both databases +- **Schema migrations**: Run automatically on startup for all databases - **Data migration**: Manual process, requires SQL dialect conversion - **Downtime**: Plan for maintenance window during migration +- **Build tags**: Ensure binary is built with appropriate tags (`-tags postgres` or `-tags mysql`) ## Connection Pooling @@ -219,5 +323,7 @@ See the [PostgreSQL Troubleshooting Guide](postgresql-troubleshooting.md) for co ## Related Documentation - [Docker Compose PostgreSQL Setup](docker-compose-postgres.md) +- [Docker Compose MySQL Setup](docker-compose-mysql.md) - [Database Migrations Guide](migrations.md) - [Migration Concurrency](migrations-concurrency.md) +- [PostgreSQL Troubleshooting Guide](postgresql-troubleshooting.md) diff --git a/docs/deployment/helm.md b/docs/deployment/helm.md index 337fea17..0ad2e750 100644 --- a/docs/deployment/helm.md +++ b/docs/deployment/helm.md @@ -17,6 +17,7 @@ Deploy LLM Proxy to Kubernetes using the official Helm chart. The chart supports - **SQLite** for single-instance deployments (development/testing) - **PostgreSQL** for production (external or in-cluster) +- **MySQL** for production (external or in-cluster) - **Redis** for event bus and caching (external) - **Ingress** for external access with TLS - **Horizontal Pod Autoscaler (HPA)** for automatic scaling @@ -93,6 +94,38 @@ docker build --build-arg POSTGRES_SUPPORT=true -t your-registry/llm-proxy:v1.0.0 ``` Pre-built images from `ghcr.io/sofatutor/llm-proxy` include PostgreSQL support by default. +**⚠️ Production HA Note**: For high-availability deployments, use an external managed PostgreSQL service (Aurora, RDS, Cloud SQL, Azure Database). The in-cluster PostgreSQL option is for development/testing only and does not provide HA or automatic failover. + +### 2b. MySQL (External, Production) + +Production deployment with external MySQL: + +```bash +# Create secrets +kubectl create secret generic llm-proxy-secrets \ + --from-literal=MANAGEMENT_TOKEN="$(openssl rand -base64 32)" + +# NOTE: Replace USER and PASSWORD with your actual DB credentials; never commit real secrets +kubectl create secret generic llm-proxy-db \ + --from-literal=DATABASE_URL="USER:PASSWORD@tcp(mysql.example.com:3306)/llmproxy?parseTime=true&tls=true" + +# Deploy with external MySQL +helm install llm-proxy deploy/helm/llm-proxy \ + --set image.repository=your-registry/llm-proxy \ + --set image.tag=v1.0.0 \ + --set secrets.managementToken.existingSecret.name=llm-proxy-secrets \ + --set secrets.databaseUrl.existingSecret.name=llm-proxy-db \ + --set env.DB_DRIVER=mysql +``` + +**Important**: If building images yourself, ensure MySQL support is enabled: +```bash +docker build --build-arg MYSQL_SUPPORT=true -t your-registry/llm-proxy:v1.0.0 . +``` +Pre-built images from `ghcr.io/sofatutor/llm-proxy` include MySQL support by default. + +**⚠️ Production HA Note**: For high-availability deployments, use an external managed MySQL service (Aurora MySQL, RDS MySQL, Cloud SQL MySQL, Azure Database for MySQL). The in-cluster MySQL option is for development/testing only and does not provide HA or automatic failover. + ### 3. External Redis (Multi-Instance) Deploy with Redis for event bus and caching: diff --git a/docs/getting-started/configuration.md b/docs/getting-started/configuration.md index 4a26406e..3ffc0189 100644 --- a/docs/getting-started/configuration.md +++ b/docs/getting-started/configuration.md @@ -37,7 +37,7 @@ Command-line flags > Environment variables > Configuration files > Defaults ### Database Configuration -LLM Proxy supports SQLite (default) and PostgreSQL databases. +LLM Proxy supports SQLite (default), PostgreSQL, and MySQL databases. #### SQLite (Default) @@ -63,7 +63,32 @@ postgres://user:password@host:port/database?sslmode=require DATABASE_URL=postgres://llmproxy:secret@localhost:5432/llmproxy?sslmode=require ``` -#### Connection Pool (Both Drivers) +**Build Requirement:** Binary must be built with `-tags postgres` flag. + +#### MySQL + +| Variable | Type | Default | Description | +|----------|------|---------|-------------| +| `DB_DRIVER` | string | `sqlite` | Set to `mysql` for MySQL | +| `DATABASE_URL` | string | - | MySQL connection string | + +**MySQL Connection String Format:** +``` +user:password@tcp(host:port)/database?parseTime=true&tls=true +``` + +**Example:** +```bash +DATABASE_URL=llmproxy:secret@tcp(localhost:3306)/llmproxy?parseTime=true&tls=true +``` + +**Build Requirement:** Binary must be built with `-tags mysql` flag. + +**Version Compatibility:** +- MySQL 8.0 or higher +- MariaDB 10.5 or higher + +#### Connection Pool (All Drivers) | Variable | Type | Default | Description | |----------|------|---------|-------------| diff --git a/internal/database/README.md b/internal/database/README.md index 25094261..8b6dc34f 100644 --- a/internal/database/README.md +++ b/internal/database/README.md @@ -8,7 +8,7 @@ The `database` package provides data persistence for the LLM Proxy. It handles: - Token and project CRUD operations - Audit event storage and retrieval - Database migrations using goose -- Support for SQLite (default) and PostgreSQL +- Support for SQLite (default), PostgreSQL, and MySQL - Connection pooling and transaction management ## Architecture @@ -30,6 +30,7 @@ graph TB subgraph Drivers SQLite[(SQLite)] PG[(PostgreSQL)] + MySQL[(MySQL)] end F --> DB @@ -38,6 +39,7 @@ graph TB DB --> A DB --> SQLite DB --> PG + DB --> MySQL M --> DB ``` @@ -84,11 +86,11 @@ erDiagram |------|-------------| | `DB` | Main database connection wrapper | | `Config` | SQLite-specific configuration | -| `FullConfig` | Multi-driver configuration (SQLite + PostgreSQL) | +| `FullConfig` | Multi-driver configuration (SQLite + PostgreSQL + MySQL) | | `Project` | Project entity model | | `Token` | Token entity model | | `AuditEvent` | Audit log entry model | -| `DriverType` | Database driver enum (SQLite, Postgres) | +| `DriverType` | Database driver enum (SQLite, Postgres, MySQL) | ### Constructor Functions @@ -124,21 +126,22 @@ The `DB` struct provides CRUD operations for all entities: | Variable | Description | Default | |----------|-------------|---------| -| `DB_DRIVER` | Database driver (`sqlite`, `postgres`) | `sqlite` | +| `DB_DRIVER` | Database driver (`sqlite`, `postgres`, `mysql`) | `sqlite` | | `DATABASE_PATH` | SQLite database path | `data/llm-proxy.db` | -| `DATABASE_URL` | PostgreSQL connection URL | - | +| `DATABASE_URL` | PostgreSQL or MySQL connection URL | - | | `DATABASE_POOL_SIZE` | Max open connections | 10 | | `DATABASE_MAX_IDLE_CONNS` | Max idle connections | 5 | | `DATABASE_CONN_MAX_LIFETIME` | Connection lifetime | 1h | -### SQLite vs PostgreSQL +### Database Comparison -| Feature | SQLite | PostgreSQL | -|---------|--------|------------| -| Setup | Zero configuration | Requires server | -| Concurrency | Single writer | Multiple writers | -| Use case | Development, single instance | Production, multi-instance | -| Connection string | File path | URL with credentials | +| Feature | SQLite | PostgreSQL | MySQL | +|---------|--------|------------|-------| +| Setup | Zero configuration | Requires server | Requires server | +| Concurrency | Single writer | Multiple writers | Multiple writers | +| Use case | Development, single instance | Production, multi-instance | Production, multi-instance | +| Connection string | File path | URL with credentials | DSN with tcp() | +| Build tag | None | `-tags postgres` | `-tags mysql` | ## Migration Workflow @@ -223,6 +226,7 @@ Migrations run automatically on `New()`. See `internal/database/migrations/READM | `database.go` | Core DB struct, connection, and migrations | | `factory.go` | Multi-driver database factory | | `factory_postgres.go` | PostgreSQL-specific factory | +| `factory_mysql.go` | MySQL-specific factory | | `models.go` | Data models (Project, Token, AuditEvent) | | `project.go` | Project CRUD operations | | `token.go` | Token CRUD operations | From ded5e44c2c1d9e785ea0b045f986740ff3429de7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 2 Jan 2026 21:59:30 +0000 Subject: [PATCH 3/4] Add MySQL to quickstart, architecture docs, and HA warnings - Updated quickstart.md with MySQL build options and setup - Enhanced architecture.md with MySQL database support - Added production HA warnings to docker-compose docs - Updated deployment architecture diagrams to include MySQL Co-authored-by: mfittko <326798+mfittko@users.noreply.github.com> --- docs/architecture/architecture.md | 17 ++++++++------ docs/database/docker-compose-mysql.md | 9 +++++++ docs/database/docker-compose-postgres.md | 11 ++++++++- docs/getting-started/quickstart.md | 30 ++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/docs/architecture/architecture.md b/docs/architecture/architecture.md index 27fc7c6e..b5116f00 100644 --- a/docs/architecture/architecture.md +++ b/docs/architecture/architecture.md @@ -365,9 +365,11 @@ The proxy implementation is based on Go's `httputil.ReverseProxy` with customiza - Tokens table: Stores tokens with expiration and usage limits - **Implementation**: `internal/database/*` - **Technology**: - - **SQLite** is used for MVP, local development, and small-scale/self-hosted deployments for its simplicity and zero-dependency deployment. - - **PostgreSQL** is recommended for production deployments requiring high concurrency, advanced features, or distributed/cloud-native scaling. - - The codebase and schema/migrations are designed to support both SQLite and PostgreSQL, enabling a smooth migration path as needed. + - **SQLite** (default): Zero-dependency option for local development, MVP, and small-scale/self-hosted deployments + - **PostgreSQL**: Recommended for production deployments requiring high concurrency, advanced features, or distributed/cloud-native scaling + - **MySQL**: Recommended for production deployments, especially for teams with existing MySQL infrastructure or expertise + - The codebase and schema/migrations are designed to support all three databases, enabling a smooth migration path as needed + - Build tags (`-tags postgres` or `-tags mysql`) control which database drivers are compiled into the binary ### Token Management @@ -570,7 +572,8 @@ sequenceDiagram The application is designed for flexible deployment: - For MVP, local, and small-scale deployments, a single container with SQLite is recommended for simplicity. -- For production or scaling needs, PostgreSQL can be used as the backing database, either in a container or as a managed service. The application should be configured to connect to PostgreSQL as needed. +- For production or scaling needs, PostgreSQL or MySQL can be used as the backing database, either in a container or as a managed service. The application should be configured to connect to the chosen database as needed. +- Build tags must be used when compiling with PostgreSQL (`-tags postgres`) or MySQL (`-tags mysql`) support. ### Single Container Deployment @@ -615,9 +618,9 @@ flowchart TD Proxy2 --> Redis Proxy3 --> Redis - Proxy1 --> Postgres[("PostgreSQL")] - Proxy2 --> Postgres - Proxy3 --> Postgres + Proxy1 --> Database[("PostgreSQL/MySQL")] + Proxy2 --> Database + Proxy3 --> Database Proxy1 --> API["Target API"] Proxy2 --> API diff --git a/docs/database/docker-compose-mysql.md b/docs/database/docker-compose-mysql.md index f2fba2c7..68d11da8 100644 --- a/docs/database/docker-compose-mysql.md +++ b/docs/database/docker-compose-mysql.md @@ -67,6 +67,15 @@ MySQL named locking requires the 'mysql' build tag The llm-proxy supports SQLite (default), PostgreSQL, and MySQL as database backends. This guide explains how to run the MySQL setup using Docker Compose. +**⚠️ Important for Production:** +- The Docker Compose MySQL setup is intended for **development and testing only** +- For production high-availability (HA) deployments, use an external managed MySQL service: + - Amazon Aurora MySQL / Amazon RDS for MySQL + - Google Cloud SQL for MySQL + - Azure Database for MySQL + - Self-managed MySQL Group Replication or InnoDB Cluster +- The Docker Compose MySQL instance runs as a single container and does not provide high availability or automatic failover + ## Quick Start ### Prerequisites diff --git a/docs/database/docker-compose-postgres.md b/docs/database/docker-compose-postgres.md index 5012ef47..8ad875e8 100644 --- a/docs/database/docker-compose-postgres.md +++ b/docs/database/docker-compose-postgres.md @@ -64,7 +64,16 @@ PostgreSQL support not compiled in; build with -tags postgres to enable ## Overview -The llm-proxy supports both SQLite (default) and PostgreSQL as database backends. This guide explains how to run the PostgreSQL setup using Docker Compose. +The llm-proxy supports SQLite (default), PostgreSQL, and MySQL as database backends. This guide explains how to run the PostgreSQL setup using Docker Compose. + +**⚠️ Important for Production:** +- The Docker Compose PostgreSQL setup is intended for **development and testing only** +- For production high-availability (HA) deployments, use an external managed PostgreSQL service: + - Amazon Aurora PostgreSQL / Amazon RDS for PostgreSQL + - Google Cloud SQL for PostgreSQL + - Azure Database for PostgreSQL + - Self-managed PostgreSQL with replication +- The Docker Compose PostgreSQL instance runs as a single container and does not provide high availability or automatic failover ## Quick Start diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md index e51cb5a2..6bb36f4c 100644 --- a/docs/getting-started/quickstart.md +++ b/docs/getting-started/quickstart.md @@ -11,6 +11,18 @@ nav_order: 2 go build -o llm-proxy ./cmd/proxy ``` +Or build with database support: +```bash +# With PostgreSQL support +go build -tags postgres -o llm-proxy ./cmd/proxy + +# With MySQL support +go build -tags mysql -o llm-proxy ./cmd/proxy + +# With both PostgreSQL and MySQL support +go build -tags "postgres,mysql" -o llm-proxy ./cmd/proxy +``` + 2) Setup ```bash ./llm-proxy setup --interactive @@ -31,6 +43,24 @@ docker run -d --name redis -p 6379:6379 redis:alpine HTTP_CACHE_ENABLED=true HTTP_CACHE_BACKEND=redis REDIS_ADDR=localhost:6379 ./llm-proxy server ``` +3c) Start with PostgreSQL (optional) +```bash +# Start PostgreSQL with Docker Compose +docker compose --profile postgres up -d postgres + +# Start proxy with PostgreSQL (requires -tags postgres build) +DB_DRIVER=postgres DATABASE_URL=postgres://llmproxy:secret@localhost:5432/llmproxy?sslmode=disable ./llm-proxy server +``` + +3d) Start with MySQL (optional) +```bash +# Start MySQL with Docker Compose +docker compose --profile mysql up -d mysql + +# Start proxy with MySQL (requires -tags mysql build) +DB_DRIVER=mysql DATABASE_URL=llmproxy:secret@tcp(localhost:3306)/llmproxy?parseTime=true ./llm-proxy server +``` + 4) Generate a token - In the Admin UI: Tokens → Generate Token (recommended) - Or via CLI (replace IDs): From bd8ad6a36a0ecafce792dcf248384ea070e15157 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 2 Jan 2026 22:01:21 +0000 Subject: [PATCH 4/4] Complete MySQL documentation with installation and deployment guides - Updated installation.md with MySQL build instructions - Enhanced deployment/index.md with MySQL quick start examples - Added database-specific build tag examples throughout - Ensured all deployment paths mention MySQL support Co-authored-by: mfittko <326798+mfittko@users.noreply.github.com> --- docs/deployment/index.md | 24 ++++++++++++++++++++++-- docs/getting-started/installation.md | 20 ++++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/docs/deployment/index.md b/docs/deployment/index.md index 59357c0f..a074437f 100644 --- a/docs/deployment/index.md +++ b/docs/deployment/index.md @@ -19,7 +19,7 @@ Production deployment guides for LLM Proxy. For production deployments, we recommend **AWS ECS with CDK**: -- Aurora PostgreSQL Serverless v2 for database +- Aurora PostgreSQL Serverless v2 or Aurora MySQL for database - ElastiCache Redis for caching and rate limiting - ALB with ACM for HTTPS termination - Auto-scaling based on CPU/request count @@ -32,7 +32,7 @@ See the [AWS ECS Architecture Guide](aws-ecs-cdk.md) for details. For organizations with existing Kubernetes infrastructure, we provide a **comprehensive Helm chart**: - Single-instance deployments with SQLite (development) -- Multi-replica deployments with PostgreSQL and Redis (production) +- Multi-replica deployments with PostgreSQL, MySQL, and Redis (production) - Ingress support with TLS (NGINX, Traefik, etc.) - Horizontal Pod Autoscaler (HPA) for automatic scaling - Event dispatcher for observability platforms (Lunary, Helicone) @@ -76,6 +76,26 @@ helm install llm-proxy deploy/helm/llm-proxy \ --set env.DB_DRIVER=postgres ``` +**Helm Quick Start (Production with MySQL)**: + +> **Note**: If using a custom-built image, ensure it's built with MySQL support: `docker build --build-arg MYSQL_SUPPORT=true ...`. See the [full guide](helm.md) for details. + +```bash +kubectl create secret generic llm-proxy-secrets \ + --from-literal=MANAGEMENT_TOKEN="$(openssl rand -base64 32)" + +# NOTE: Replace USER and PASSWORD with your actual DB credentials; never commit real secrets +kubectl create secret generic llm-proxy-db \ + --from-literal=DATABASE_URL="USER:PASSWORD@tcp(mysql.example.com:3306)/llmproxy?parseTime=true&tls=true" + +helm install llm-proxy deploy/helm/llm-proxy \ + --set image.repository=your-registry/llm-proxy \ + --set image.tag=v1.0.0 \ + --set secrets.managementToken.existingSecret.name=llm-proxy-secrets \ + --set secrets.databaseUrl.existingSecret.name=llm-proxy-db \ + --set env.DB_DRIVER=mysql +``` + ## Other Deployment Options - **Docker Compose** - Good for local development and testing (see repository root) diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md index c027dab4..376fa93c 100644 --- a/docs/getting-started/installation.md +++ b/docs/getting-started/installation.md @@ -271,9 +271,19 @@ cd llm-proxy # Install dependencies make dev-setup -# Build the binary +# Build the binary (SQLite only) make build +# Or build with database support +# With PostgreSQL support +go build -tags postgres -o bin/llm-proxy ./cmd/proxy + +# With MySQL support +go build -tags mysql -o bin/llm-proxy ./cmd/proxy + +# With both PostgreSQL and MySQL support +go build -tags "postgres,mysql" -o bin/llm-proxy ./cmd/proxy + # The binary is created at ./bin/llm-proxy ``` @@ -283,9 +293,15 @@ make build # Set required environment variables export MANAGEMENT_TOKEN=$(openssl rand -base64 32) -# Start the server +# Start the server with SQLite (default) ./bin/llm-proxy server +# Or start with PostgreSQL (requires -tags postgres build) +DB_DRIVER=postgres DATABASE_URL=postgres://... ./bin/llm-proxy server + +# Or start with MySQL (requires -tags mysql build) +DB_DRIVER=mysql DATABASE_URL=user:pass@tcp(host:port)/db?parseTime=true ./bin/llm-proxy server + # Or start with custom options ./bin/llm-proxy server --addr :9000 --db ./custom/path/db.sqlite ```