244 lines
8.7 KiB
Markdown
244 lines
8.7 KiB
Markdown
# Docker Compose Deployment Guide
|
|
|
|
This guide explains how to deploy the AI application locally using Docker Compose.
|
|
|
|
## Overview
|
|
|
|
Docker Compose provides a convenient way to:
|
|
|
|
- **Develop locally** with the same containerized environment used in production
|
|
- **Manage services** as a single stack (backend, frontend, and Nginx)
|
|
- **Persist data** using volume mounts
|
|
- **Enable service-to-service communication** using Docker's internal networking
|
|
|
|
## Prerequisites
|
|
|
|
- Docker Desktop installed and running
|
|
- Docker Compose v2.0+ (included with Docker Desktop)
|
|
- A `.env` file with required environment variables (see [Configuration](#configuration))
|
|
|
|
## Quick Start
|
|
|
|
1. **Clone the repository** and navigate to the project root:
|
|
|
|
```bash
|
|
cd ai.allucanget.biz
|
|
```
|
|
|
|
2. **Configure environment variables** in `.env`:
|
|
|
|
```bash
|
|
# Copy the example if you don't have a .env file
|
|
cp .env.example .env
|
|
|
|
# Edit .env and fill in required values
|
|
# - OPENROUTER_API_KEY: Your openrouter.ai API key
|
|
# - JWT_SECRET: A random secret for signing JWT tokens
|
|
# - FLASK_SECRET_KEY: A random secret for Flask session cookies
|
|
```
|
|
|
|
3. **Build and start the services**:
|
|
|
|
```bash
|
|
docker compose up --build
|
|
```
|
|
|
|
4. **Access the application**:
|
|
- Frontend UI: http://localhost:12016
|
|
- Backend API: http://localhost:12015
|
|
- API Health: http://localhost:12015/health
|
|
- Nginx Proxy: http://localhost:80 (routes to frontend) or http://localhost:80/api (routes to backend)
|
|
|
|
5. **View logs**:
|
|
|
|
```bash
|
|
# All services
|
|
docker compose logs -f
|
|
|
|
# Specific service
|
|
docker compose logs -f backend
|
|
docker compose logs -f frontend
|
|
```
|
|
|
|
6. **Stop the services**:
|
|
|
|
```bash
|
|
docker compose down
|
|
```
|
|
|
|
## Configuration
|
|
|
|
### Environment Variables
|
|
|
|
The `.env` file in the project root is automatically loaded by Docker Compose. Required variables:
|
|
|
|
| Variable | Purpose | Example |
|
|
| -------------------- | ------------------------------------------ | ---------------------------------------------------------------------------- |
|
|
| `OPENROUTER_API_KEY` | API key for AI generation | `sk-or-v1-...` |
|
|
| `JWT_SECRET` | Secret for JWT token signing | (random hex string) |
|
|
| `FLASK_SECRET_KEY` | Secret for Flask session cookies | (random hex string) |
|
|
| `BACKEND_URL` | Internal URL for frontend to reach backend | `http://backend:12015` (Docker) or `http://localhost:12015` (local dev) |
|
|
| `CORS_ORIGINS` | Allowed CORS origins for backend | `http://localhost:12016` (local) or `https://ai.allucanget.biz` (production) |
|
|
| `APP_URL` | Public URL of the backend | `http://localhost` or `https://ai.allucanget.biz` |
|
|
| `APP_NAME` | Application name | `AI Allucanget` |
|
|
|
|
### Volume Mounts
|
|
|
|
The `docker-compose.yml` defines the following volume:
|
|
|
|
- `./data:/app/data` — Persists the DuckDB database (`app.db`) between container restarts
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Docker Network: app-network (internal bridge) │
|
|
├─────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌──────────────────┐ ┌──────────────────────────┐ │
|
|
│ │ Frontend │ │ Backend │ │
|
|
│ │ Port 12016 │ │ Port 12015 │ │
|
|
│ │ Flask + Gunicorn│◄──►│ FastAPI + Uvicorn │ │
|
|
│ │ (Service name: │ │ (Service name: backend) │ │
|
|
│ │ frontend) │ │ │ │
|
|
│ └──────────────────┘ │ ┌────────────────────┐ │ │
|
|
│ ▲ │ │ DuckDB Database │ │ │
|
|
│ │ │ │ /app/data/app.db │ │ │
|
|
│ ┌────▼──────────────┐ │ └────────────────────┘ │ │
|
|
│ │ Nginx (Port 80) │ └──────────────────────────┘ │
|
|
│ │ Reverse Proxy │ │
|
|
│ └───────────────────┘ │
|
|
│ ▲ │
|
|
│ │ (bind mount) │
|
|
│ Host:80, 443 │
|
|
└─────────────────────────────────────────────────────────┘
|
|
│
|
|
Host OS
|
|
```
|
|
|
|
## Common Tasks
|
|
|
|
### View service status
|
|
|
|
```bash
|
|
docker compose ps
|
|
```
|
|
|
|
Output example:
|
|
|
|
```
|
|
NAME COMMAND SERVICE STATUS PORTS
|
|
ai-backend "uvicorn app.main:a…" backend Up 2m 0.0.0.0:12015->12015/tcp
|
|
ai-frontend "gunicorn app.main:…" frontend Up 2m 0.0.0.0:12016->12016/tcp
|
|
ai-nginx "nginx -g daemon of…" nginx Up 2m 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp
|
|
```
|
|
|
|
### Rebuild images
|
|
|
|
```bash
|
|
# Rebuild all services
|
|
docker compose build
|
|
|
|
# Rebuild a specific service
|
|
docker compose build backend
|
|
docker compose build frontend
|
|
```
|
|
|
|
### Access container shell
|
|
|
|
```bash
|
|
# Backend shell
|
|
docker compose exec backend bash
|
|
|
|
# Frontend shell
|
|
docker compose exec frontend bash
|
|
```
|
|
|
|
### View service logs
|
|
|
|
```bash
|
|
# Tail all logs
|
|
docker compose logs -f
|
|
|
|
# Follow only backend logs
|
|
docker compose logs -f backend
|
|
|
|
# Last 100 lines of frontend logs
|
|
docker compose logs --tail 100 frontend
|
|
```
|
|
|
|
### Clean up
|
|
|
|
```bash
|
|
# Stop containers but keep volumes and images
|
|
docker compose stop
|
|
|
|
# Stop and remove containers
|
|
docker compose down
|
|
|
|
# Stop containers and remove volumes (WARNING: deletes database!)
|
|
docker compose down -v
|
|
|
|
# Remove images as well
|
|
docker compose down --rmi all
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### "Docker daemon is not running"
|
|
|
|
**Error**: `error during connect: This error may indicate the client is not properly configured`
|
|
|
|
**Solution**: Start Docker Desktop (Windows/Mac) or start the Docker daemon (Linux).
|
|
|
|
### "Port 12015 or 12016 already in use"
|
|
|
|
**Error**: `Error response from daemon: bind: address already in use`
|
|
|
|
**Solution**: Either stop the other application using that port, or modify the ports in `docker-compose.yml`:
|
|
|
|
```yaml
|
|
ports:
|
|
- "13000:12015" # Maps host:13000 to container:12015
|
|
- "13001:12016" # Maps host:13001 to container:12016
|
|
```
|
|
|
|
### Frontend cannot reach backend
|
|
|
|
**Error**: Connection refused or 502 Bad Gateway
|
|
|
|
**Ensure**:
|
|
|
|
1. Backend service is running: `docker compose ps`
|
|
2. `BACKEND_URL` in `.env` is set to `http://backend:12015` (not `localhost`)
|
|
3. Services are on the same Docker network: `docker compose ps` shows them in the same `docker-compose.yml`
|
|
|
|
### Database file not persisting
|
|
|
|
**Issue**: Data is lost after `docker compose down`
|
|
|
|
**Solution**: The volume mount `./data:/app/data` should persist data automatically. Check that:
|
|
|
|
1. The `data/` directory exists on your host
|
|
2. The volume is mounted correctly in `docker-compose.yml`
|
|
3. DuckDB has write permissions to the `data/` directory
|
|
|
|
## Performance Tips
|
|
|
|
- **Development**: Use `docker compose up` for real-time logs and quick iterations
|
|
- **Background**: Use `docker compose up -d` to run services detached
|
|
- **Rebuilds**: Use `docker compose up --build` only when dependencies or Dockerfiles change
|
|
- **Caching**: Docker caches layers; unchanged steps build faster
|
|
|
|
## Next Steps
|
|
|
|
- **Deployment**: See [Coolify Deployment](./coolify.md) for production deployment
|
|
- **Testing**: See [Testing Guide](../TESTING.md) for running tests
|
|
- **Architecture**: See [Deployment View](../7-deployment-view.md) for system architecture
|
|
|
|
## Additional Resources
|
|
|
|
- [Docker Compose Documentation](https://docs.docker.com/compose/)
|
|
- [Docker Networking Guide](https://docs.docker.com/network/)
|
|
- [Best Practices for Writing Dockerfiles](https://docs.docker.com/develop/dev-best-practices/dockerfile_best-practices/)
|