dockerize app
This commit is contained in:
215
DOCKER.md
Normal file
215
DOCKER.md
Normal file
@@ -0,0 +1,215 @@
|
||||
# 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 <container_id> | 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 <container_id>
|
||||
```
|
||||
|
||||
### 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 <container_id> wget -O- http://localhost:8000/
|
||||
```
|
||||
|
||||
### View real-time logs
|
||||
|
||||
```bash
|
||||
docker logs -f <container_id>
|
||||
```
|
||||
|
||||
## 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
|
||||
```
|
||||
Reference in New Issue
Block a user