# Docker Setup Guide This document explains how to build and run the Akern-Genai application using Docker. ## Overview The Docker configuration includes: - **Multi-stage build** for smaller image size - **Entrypoint script** with proper signal handling and exit status management - **Configurable port** via environment variables - **Health checks** for monitoring - **Non-root user** for security - **Optimized build** with `.dockerignore` ## Files - [`Dockerfile`](Dockerfile) - Multi-stage Docker build configuration - [`entrypoint.sh`](entrypoint.sh) - Entrypoint script with signal handling - [`docker-compose.yml`](docker-compose.yml) - Docker Compose configuration - [`.dockerignore`](.dockerignore) - Files excluded from Docker build context ## Environment Variables The following environment variables can be configured: | Variable | Default | Description | | ----------- | --------- | ----------------------------------------------------- | | `PORT` | `8000` | Port on which the application listens | | `HOST` | `0.0.0.0` | Host address to bind to | | `WORKERS` | `1` | Number of uvicorn worker processes | | `LOG_LEVEL` | `info` | Logging level (debug, info, warning, error, critical) | ## Building the Image ### Using Docker directly: ```bash docker build -t akern-genai:latest . ``` ### Using Docker Compose: ```bash docker-compose build ``` ## Running the Container ### Using Docker directly: ```bash # Run with default configuration (port 8000) docker run -p 8000:8000 akern-genai:latest # Run with custom port docker run -p 3000:3000 -e PORT=3000 akern-genai:latest # Run with multiple workers docker run -p 8000:8000 -e WORKERS=4 akern-genai:latest # Run with custom log level docker run -p 8000:8000 -e LOG_LEVEL=debug akern-genai:latest ``` ### Using Docker Compose: ```bash # Run with default configuration docker-compose up # Run with custom port PORT=3000 docker-compose up # Run in detached mode docker-compose up -d # Stop the container docker-compose down ``` ### Using environment file: Create a `.env` file in the project root: ```env PORT=8000 HOST=0.0.0.0 WORKERS=1 LOG_LEVEL=info ``` Then run: ```bash docker-compose up ``` ## Signal Handling The entrypoint script properly handles termination signals: - **SIGTERM** - Graceful shutdown (sent by `docker stop`) - **SIGINT** - Interrupt signal (Ctrl+C) The script will: 1. Forward the signal to uvicorn 2. Wait up to 30 seconds for graceful shutdown 3. Force kill if shutdown doesn't complete in time 4. Exit with the same status code as uvicorn ## Health Check The container includes a health check that monitors the application: - **Interval**: 30 seconds - **Timeout**: 10 seconds - **Start period**: 5 seconds - **Retries**: 3 Check container health: ```bash docker ps docker inspect | grep -A 10 Health ``` ## Multi-Stage Build The Dockerfile uses a two-stage build: ### Stage 1: Builder - Installs build dependencies (gcc, musl-dev, etc.) - Creates a virtual environment - Installs Python dependencies ### Stage 2: Runtime - Uses minimal Alpine Linux - Only includes runtime dependencies - Copies the virtual environment from builder - Runs as non-root user This results in a significantly smaller final image. ## Security Features - **Non-root user**: Application runs as `appuser` (UID 1000) - **Minimal base image**: Alpine Linux with only necessary packages - **No build tools in runtime**: Compiler and build tools are not included in final image ## Troubleshooting ### Container exits immediately Check logs: ```bash docker logs ``` ### Port already in use Change the port: ```bash docker run -p 3000:3000 -e PORT=3000 akern-genai:latest ``` ### Health check failing Verify the application is running: ```bash docker exec -it wget -O- http://localhost:8000/ ``` ### View real-time logs ```bash docker logs -f ``` ## Image Size Comparison - **Before**: ~200-300 MB (single stage with build tools) - **After**: ~100-150 MB (multi-stage, minimal runtime) ## Production Considerations For production deployment: 1. **Use specific image tags** instead of `latest` 2. **Set appropriate worker count** based on CPU cores 3. **Configure resource limits** in docker-compose.yml or Kubernetes 4. **Use a reverse proxy** (nginx, traefik) for SSL termination 5. **Set up logging aggregation** (ELK, Loki, etc.) 6. **Configure monitoring** (Prometheus, Grafana) Example docker-compose.yml with resource limits: ```yaml services: app: deploy: resources: limits: cpus: "2" memory: 1G reservations: cpus: "0.5" memory: 512M ```