Ryan Malloy 50c80596d0 Add comprehensive Docker deployment and file upload functionality
Features Added:
• Docker containerization with multi-stage Python 3.12 build
• Caddy reverse proxy integration with automatic SSL
• File upload interface for .claude.json imports with preview
• Comprehensive hook system with 39+ hook types across 9 categories
• Complete documentation system with Docker and import guides

Technical Improvements:
• Enhanced database models with hook tracking capabilities
• Robust file validation and error handling for uploads
• Production-ready Docker compose configuration
• Health checks and resource limits for containers
• Database initialization scripts for containerized deployments

Documentation:
• Docker Deployment Guide with troubleshooting
• Data Import Guide with step-by-step instructions
• Updated Getting Started guide with new features
• Enhanced documentation index with responsive grid layout

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-11 08:02:09 -06:00

415 lines
15 KiB
HTML

{% extends "docs/base.html" %}
{% block title %}Docker Deployment - Claude Code Project Tracker{% endblock %}
{% block doc_content %}
<div class="row">
<div class="col-lg-8">
<h1 class="mb-4">
<i class="fab fa-docker text-primary me-2"></i>
Docker Deployment Guide
</h1>
<p class="lead">
Deploy Claude Code Project Tracker using Docker with Caddy reverse proxy for production environments.
</p>
<!-- Prerequisites -->
<section class="mb-5">
<h2><i class="fas fa-check-circle me-2"></i>Prerequisites</h2>
<div class="alert alert-info">
<p class="mb-2"><strong>Required:</strong></p>
<ul class="mb-0">
<li>Docker and Docker Compose installed</li>
<li>Caddy with docker-proxy plugin</li>
<li>External Caddy network configured</li>
<li>Domain name (or local development domain)</li>
</ul>
</div>
</section>
<!-- Quick Start -->
<section class="mb-5">
<h2><i class="fas fa-rocket me-2"></i>Quick Start</h2>
<p>Follow these steps to get Claude Code Tracker running with Docker:</p>
<div class="card mb-3">
<div class="card-header bg-light">
<h5 class="mb-0">1. Clone and Configure</h5>
</div>
<div class="card-body">
<pre><code class="language-bash"># Clone the repository
git clone &lt;repository-url&gt; claude-tracker
cd claude-tracker
# Copy environment template
cp .env.example .env</code></pre>
</div>
</div>
<div class="card mb-3">
<div class="card-header bg-light">
<h5 class="mb-0">2. Configure Environment</h5>
</div>
<div class="card-body">
<p>Edit the <code>.env</code> file with your settings:</p>
<pre><code class="language-bash"># Domain configuration
DOMAIN=claude.l.supported.systems
# Database settings
DATABASE_URL=sqlite+aiosqlite:////app/data/tracker.db
# Application settings
DEBUG=false
PYTHONPATH=/app</code></pre>
</div>
</div>
<div class="card mb-3">
<div class="card-header bg-light">
<h5 class="mb-0">3. Deploy with Docker Compose</h5>
</div>
<div class="card-body">
<pre><code class="language-bash"># Build and start the container
docker-compose up -d
# View logs
docker-compose logs -f
# Check status
docker-compose ps</code></pre>
</div>
</div>
</section>
<!-- Docker Configuration -->
<section class="mb-5">
<h2><i class="fas fa-cog me-2"></i>Docker Configuration</h2>
<h4 class="mt-4">Dockerfile</h4>
<p>The application uses a multi-stage Docker build with Python 3.12 and uv package manager:</p>
<div class="card mb-3">
<div class="card-body">
<pre><code class="language-dockerfile"># Multi-stage build with Python 3.12
FROM python:3.12-slim
# Install uv package manager
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
# Application setup
WORKDIR /app
COPY . .
# Install dependencies and create virtual environment
RUN uv venv && uv pip install -r requirements.txt
# Database initialization script
COPY init_db.py ./
# Startup script with database initialization
CMD ["./start.sh"]</code></pre>
</div>
</div>
<h4 class="mt-4">docker-compose.yml</h4>
<p>The Docker Compose configuration includes Caddy integration:</p>
<div class="card mb-3">
<div class="card-body">
<pre><code class="language-yaml">services:
claude-tracker:
build:
context: .
dockerfile: Dockerfile
container_name: claude-tracker-api
restart: unless-stopped
environment:
- DATABASE_URL=sqlite+aiosqlite:////app/data/tracker.db
- DEBUG=true
- PYTHONPATH=/app
volumes:
- ./data:/app/data
- ./app/dashboard/static:/app/app/dashboard/static:ro
networks:
- caddy
labels:
# Caddy reverse proxy configuration
caddy: ${DOMAIN:-claude.l.supported.systems}
caddy.reverse_proxy: "{{upstreams 8000}}"
expose:
- 8000
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
networks:
caddy:
external: true
name: caddy</code></pre>
</div>
</div>
</section>
<!-- Caddy Integration -->
<section class="mb-5">
<h2><i class="fas fa-globe me-2"></i>Caddy Integration</h2>
<p>The application integrates with Caddy using docker-proxy labels for automatic SSL and reverse proxy configuration.</p>
<div class="card mb-3">
<div class="card-header bg-light">
<h5 class="mb-0">Caddy Labels Explained</h5>
</div>
<div class="card-body">
<ul>
<li><code>caddy: ${DOMAIN}</code> - Sets the domain for the service</li>
<li><code>caddy.reverse_proxy: "{{upstreams 8000}}"</code> - Proxies to port 8000</li>
<li>Automatic SSL certificate generation</li>
<li>Health check integration</li>
<li>Load balancing support</li>
</ul>
</div>
</div>
</section>
<!-- Database & Persistence -->
<section class="mb-5">
<h2><i class="fas fa-database me-2"></i>Database & Persistence</h2>
<p>The application uses SQLite with proper volume mounting for data persistence:</p>
<div class="card mb-3">
<div class="card-header bg-light">
<h5 class="mb-0">Volume Configuration</h5>
</div>
<div class="card-body">
<ul>
<li><code>./data:/app/data</code> - Database and file storage</li>
<li><code>./app/dashboard/static:/app/app/dashboard/static:ro</code> - Static assets (read-only)</li>
</ul>
<div class="alert alert-warning mt-3">
<i class="fas fa-exclamation-triangle me-1"></i>
<strong>Important:</strong> Ensure the <code>./data</code> directory exists and has proper permissions before starting the container.
</div>
</div>
</div>
</section>
<!-- Management Commands -->
<section class="mb-5">
<h2><i class="fas fa-terminal me-2"></i>Management Commands</h2>
<div class="row">
<div class="col-md-6">
<div class="card h-100">
<div class="card-header">
<h5 class="mb-0">Container Management</h5>
</div>
<div class="card-body">
<pre><code class="language-bash"># Start services
docker-compose up -d
# Stop services
docker-compose down
# Restart services
docker-compose restart
# View logs
docker-compose logs -f
# Check status
docker-compose ps</code></pre>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-100">
<div class="card-header">
<h5 class="mb-0">Database Management</h5>
</div>
<div class="card-body">
<pre><code class="language-bash"># Execute shell in container
docker-compose exec claude-tracker sh
# Initialize database manually
docker-compose exec claude-tracker python init_db.py
# Backup database
cp ./data/tracker.db ./data/tracker.db.backup
# View database size
du -h ./data/tracker.db</code></pre>
</div>
</div>
</div>
</div>
</section>
<!-- Monitoring & Health -->
<section class="mb-5">
<h2><i class="fas fa-heartbeat me-2"></i>Monitoring & Health</h2>
<div class="card mb-3">
<div class="card-header bg-light">
<h5 class="mb-0">Health Checks</h5>
</div>
<div class="card-body">
<p>The container includes built-in health checks:</p>
<ul>
<li><strong>Endpoint:</strong> <code>http://localhost:8000/health</code></li>
<li><strong>Interval:</strong> 30 seconds</li>
<li><strong>Timeout:</strong> 10 seconds</li>
<li><strong>Retries:</strong> 3 attempts</li>
<li><strong>Start Period:</strong> 30 seconds</li>
</ul>
<pre><code class="language-bash"># Check health status
docker-compose ps
curl https://your-domain.com/health</code></pre>
</div>
</div>
<div class="card mb-3">
<div class="card-header bg-light">
<h5 class="mb-0">Resource Limits</h5>
</div>
<div class="card-body">
<p>Configured resource limits:</p>
<ul>
<li><strong>CPU Limit:</strong> 1.0 core</li>
<li><strong>Memory Limit:</strong> 512MB</li>
<li><strong>CPU Reservation:</strong> 0.25 core</li>
<li><strong>Memory Reservation:</strong> 128MB</li>
</ul>
</div>
</div>
</section>
<!-- Troubleshooting -->
<section class="mb-5">
<h2><i class="fas fa-tools me-2"></i>Troubleshooting</h2>
<div class="accordion" id="troubleshootingAccordion">
<div class="accordion-item">
<h2 class="accordion-header" id="headingOne">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne">
Container keeps restarting
</button>
</h2>
<div id="collapseOne" class="accordion-collapse collapse" data-bs-parent="#troubleshootingAccordion">
<div class="accordion-body">
<pre><code class="language-bash"># Check logs for errors
docker-compose logs claude-tracker
# Check database permissions
ls -la ./data/
# Verify database initialization
docker-compose exec claude-tracker python init_db.py</code></pre>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="headingTwo">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo">
502 Bad Gateway errors
</button>
</h2>
<div id="collapseTwo" class="accordion-collapse collapse" data-bs-parent="#troubleshootingAccordion">
<div class="accordion-body">
<pre><code class="language-bash"># Check if container is running
docker-compose ps
# Verify health check
docker-compose exec claude-tracker curl localhost:8000/health
# Check Caddy network connectivity
docker network ls | grep caddy</code></pre>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="headingThree">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree">
Database connection issues
</button>
</h2>
<div id="collapseThree" class="accordion-collapse collapse" data-bs-parent="#troubleshootingAccordion">
<div class="accordion-body">
<pre><code class="language-bash"># Create data directory if missing
mkdir -p ./data
chmod 755 ./data
# Remove corrupted database
rm ./data/tracker.db
# Restart container to reinitialize
docker-compose restart</code></pre>
</div>
</div>
</div>
</div>
</section>
<!-- Security Considerations -->
<section class="mb-5">
<h2><i class="fas fa-shield-alt me-2"></i>Security Considerations</h2>
<div class="alert alert-warning">
<h5><i class="fas fa-exclamation-triangle me-1"></i>Production Security</h5>
<ul class="mb-0">
<li>Set <code>DEBUG=false</code> in production</li>
<li>Use strong domain names and SSL certificates</li>
<li>Regularly backup the database</li>
<li>Monitor container logs for suspicious activity</li>
<li>Keep Docker images updated</li>
<li>Limit container resource usage</li>
</ul>
</div>
</section>
</div>
<!-- Sidebar -->
<div class="col-lg-4">
<div class="card sticky-top" style="top: 1rem;">
<div class="card-header">
<h5 class="mb-0"><i class="fas fa-list me-1"></i>Quick Reference</h5>
</div>
<div class="card-body">
<h6>Essential Commands</h6>
<div class="code-block mb-3">
<pre><code># Deploy
docker-compose up -d
# Logs
docker-compose logs -f
# Stop
docker-compose down</code></pre>
</div>
<h6>Key Files</h6>
<ul class="list-unstyled">
<li><i class="fas fa-file me-1"></i><code>.env</code></li>
<li><i class="fas fa-file me-1"></i><code>docker-compose.yml</code></li>
<li><i class="fas fa-file me-1"></i><code>Dockerfile</code></li>
<li><i class="fas fa-folder me-1"></i><code>./data/</code></li>
</ul>
<h6>Default Ports</h6>
<ul class="list-unstyled">
<li><i class="fas fa-network-wired me-1"></i>8000 (Internal)</li>
<li><i class="fas fa-globe me-1"></i>80/443 (Caddy)</li>
</ul>
</div>
</div>
</div>
</div>
{% endblock %}