Deploying DOCAT
DOCAT is a lightweight, self-hosted documentation hosting platform designed to simplify the process of managing and serving multiple versions of project documentation. Built with simplicity and efficiency in mind, DOCAT allows development teams to upload, organize, and serve documentation for different versions of their software projects through a clean, intuitive web interface.
Unlike complex documentation platforms that require extensive configuration and maintenance, DOCAT focuses on doing one thing exceptionally well: hosting versioned documentation. The platform automatically generates a version selector, provides a simple upload mechanism via its API, and serves documentation with minimal overhead. Whether you’re documenting internal tools, open-source projects, or commercial software, DOCAT provides a straightforward solution that integrates seamlessly into CI/CD pipelines and development workflows.
Why Deploy DOCAT on Klutch.sh?
Klutch.sh provides an ideal platform for hosting DOCAT with several key advantages:
- Simple Docker Deployment: Deploy your Dockerfile and Klutch.sh automatically handles containerization and orchestration
- Persistent Storage: Attach volumes to store documentation across deployments, ensuring your docs are never lost
- Automatic HTTPS: All deployments come with automatic SSL certificates for secure documentation access
- Cost-Effective Hosting: DOCAT’s lightweight design means minimal resource usage and lower hosting costs
- Zero Maintenance: No need to manage servers, updates are as simple as rebuilding your container
- Instant Scaling: Adjust resources as your documentation library grows
- CI/CD Integration: Easy integration with GitHub Actions or GitLab CI for automated documentation deployment
Prerequisites
Before deploying DOCAT, ensure you have:
- A Klutch.sh account (sign up at klutch.sh)
- Git installed locally
- Basic familiarity with Docker
- Documentation to host (HTML, static sites from Sphinx, MkDocs, JSDoc, etc.)
- Understanding of RESTful APIs for documentation uploads
- Node.js and npm (for local testing with DOCAT CLI)
Understanding DOCAT’s Architecture
DOCAT uses a straightforward architecture optimized for serving static documentation:
Core Components
Nginx Web Server: DOCAT uses Nginx as its primary web server to serve static documentation files. Nginx handles HTTP requests, serves documentation content, and manages routing between different project versions.
Backend API: A lightweight Python/Flask API manages documentation uploads, version management, and project organization. The API provides endpoints for:
- Uploading new documentation versions
- Listing available projects and versions
- Managing documentation metadata
- Deleting old versions
File System Storage: Documentation is stored in a structured directory hierarchy on the file system:
/doc├── project-name/│ ├── 1.0.0/│ │ └── index.html│ ├── 1.1.0/│ │ └── index.html│ └── latest/│ └── index.htmlFrontend Interface: A simple, responsive web interface allows users to:
- Browse available projects
- Select documentation versions
- Navigate through documentation
- Search across versions (if enabled)
Request Flow
- User accesses DOCAT via web browser
- Nginx serves the frontend application
- User selects a project and version
- Nginx serves static documentation files from the file system
- Version selector automatically updates based on available versions
- API handles upload requests from CI/CD pipelines or manual uploads
Version Management
DOCAT manages documentation versions through:
- Semantic Versioning: Supports standard semantic version formats (1.0.0, 2.1.3, etc.)
- Branch Names: Can host documentation for feature branches
- Tags: Support for custom tags like “stable”, “latest”, “beta”
- Automatic Indexing: Automatically generates project and version listings
Upload Mechanism
Documentation can be uploaded via:
- HTTP API: POST requests with documentation archives (zip/tar.gz)
- DOCAT CLI: Command-line tool for easy uploads
- CI/CD Integration: Direct integration from build pipelines
- Manual Upload: Via curl or other HTTP clients
Installation and Setup
Step 1: Create the Dockerfile
Create a Dockerfile in your project root. We’ll use the official DOCAT image as a base:
FROM docat/docat:latest
# Install additional dependencies if neededRUN apt-get update && apt-get install -y \ curl \ vim \ && rm -rf /var/lib/apt/lists/*
# Create upload token file (optional, for secure uploads)RUN mkdir -p /app/docatCOPY upload_tokens.json /app/docat/upload_tokens.json
# Set proper permissionsRUN chown -R nginx:nginx /var/www/html /doc
# Expose portEXPOSE 80
# Health checkHEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ CMD curl -f http://localhost/ || exit 1
# Use default CMD from base imageAlternatively, build from scratch for more control:
FROM python:3.11-alpine
# Install system dependenciesRUN apk add --no-cache \ nginx \ supervisor \ curl
# Create app directoryWORKDIR /app
# Install DOCATRUN pip install --no-cache-dir docat
# Copy Nginx configurationCOPY nginx.conf /etc/nginx/nginx.conf
# Copy supervisor configurationCOPY supervisord.conf /etc/supervisord.conf
# Create necessary directoriesRUN mkdir -p /doc /var/log/docat /var/log/nginx /run/nginx \ && chown -R nginx:nginx /doc /var/log/docat
# Expose portEXPOSE 80
# Health checkHEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ CMD curl -f http://localhost/ || exit 1
# Start supervisorCMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]Step 2: Create Upload Tokens Configuration
Create upload_tokens.json to secure documentation uploads:
{ "tokens": [ { "name": "ci-token", "token": "your-secure-token-here-change-in-production", "projects": ["*"] }, { "name": "project-specific-token", "token": "another-secure-token", "projects": ["my-project", "another-project"] } ]}Security Note: Generate strong tokens using:
openssl rand -base64 32Step 3: Create Nginx Configuration
Create nginx.conf (if building from scratch):
user nginx;worker_processes auto;error_log /var/log/nginx/error.log warn;pid /run/nginx.pid;
events { worker_connections 1024;}
http { include /etc/nginx/mime.types; default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; client_max_body_size 100M;
gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml application/atom+xml image/svg+xml text/x-js text/x-component text/x-cross-domain-policy;
server { listen 80; server_name localhost;
# API endpoints location /api/ { proxy_pass http://localhost:5000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }
# Documentation files location /doc/ { alias /doc/; autoindex off; try_files $uri $uri/ =404; }
# Frontend application location / { root /var/www/html; try_files $uri $uri/ /index.html; }
# Security headers add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; }}Step 4: Create Supervisor Configuration
Create supervisord.conf (if building from scratch):
[supervisord]nodaemon=truelogfile=/var/log/supervisor/supervisord.logpidfile=/var/run/supervisord.pid
[program:docat]command=python -m docat.appdirectory=/appautostart=trueautorestart=truestderr_logfile=/var/log/docat/docat.err.logstdout_logfile=/var/log/docat/docat.out.log
[program:nginx]command=nginx -g "daemon off;"autostart=trueautorestart=truestderr_logfile=/var/log/nginx/error.logstdout_logfile=/var/log/nginx/access.logStep 5: Create Environment Configuration
Create .env file for local development:
# DOCAT ConfigurationDOCAT_UPLOAD_TOKEN=your-secure-token-hereDOCAT_SERVE_PORT=80DOCAT_DOC_PATH=/doc
# StorageDOC_STORAGE_PATH=/doc
# API ConfigurationAPI_PORT=5000API_HOST=0.0.0.0
# Feature flagsENABLE_SEARCH=trueENABLE_VERSIONS=trueStep 6: Create Docker Compose for Local Development
Create docker-compose.yml for local testing:
version: '3.8'
services: docat: build: . ports: - "8080:80" volumes: - docat-docs:/doc - ./upload_tokens.json:/app/docat/upload_tokens.json:ro environment: - DOCAT_UPLOAD_TOKEN=${DOCAT_UPLOAD_TOKEN:-change-me} restart: unless-stopped
volumes: docat-docs:Step 7: Initialize Git Repository
git initgit add Dockerfile nginx.conf supervisord.conf upload_tokens.json docker-compose.yml .envgit commit -m "Initial DOCAT deployment configuration"Step 8: Test Locally
Before deploying to Klutch.sh, test your configuration locally:
# Build and start the containerdocker-compose up -d
# Check logsdocker-compose logs -f
# Access DOCAT at http://localhost:8080
# Test upload (requires documentation to upload)curl -X POST http://localhost:8080/api/project/test-project/1.0.0 \ -H "Docat-Api-Key: your-secure-token-here" \ -F "file=@docs.tar.gz"Deploying to Klutch.sh
Step 1: Push to GitHub
Create a new repository on GitHub and push your code:
git remote add origin https://github.com/yourusername/docat-klutch.gitgit branch -M mastergit push -u origin masterStep 2: Connect Repository to Klutch.sh
- Navigate to klutch.sh/app
- Click "New Project" and select "Import from GitHub"
- Authorize Klutch.sh to access your GitHub repositories
- Select your DOCAT repository from the list
- Klutch.sh will automatically detect the Dockerfile in your repository
Step 3: Configure Traffic Settings
- In the project settings, select **HTTP** as the traffic type
- Set the internal port to **80**
- Klutch.sh will automatically provision an HTTPS endpoint for your application
Step 4: Add Persistent Storage
DOCAT requires persistent storage for documentation files:
- In your project settings, navigate to the "Storage" section
- Add a volume with mount path: `/doc` and size: `20GB` (adjust based on documentation size)
Storage recommendations:
- Small projects (1-5 projects): 10GB
- Medium projects (5-20 projects): 20GB - 50GB
- Large organizations (20+ projects): 50GB - 200GB+
Step 5: Configure Environment Variables
Add the following environment variables in your Klutch.sh dashboard:
DOCAT_UPLOAD_TOKEN: Your secure upload token (generate withopenssl rand -base64 32)DOCAT_SERVE_PORT:80DOCAT_DOC_PATH:/doc
Optional variables:
ENABLE_SEARCH:true(if search functionality is needed)API_PORT:5000
Step 6: Deploy
- Review your configuration settings
- Click "Deploy" to start the deployment process
- Klutch.sh will build your Docker image and deploy the container
- Monitor the build logs for any errors
- Once deployed, your DOCAT instance will be available at `your-app.klutch.sh`
Getting Started with DOCAT
Initial Setup
After your first deployment, access your DOCAT instance:
-
Navigate to Your Instance: Visit
https://your-app.klutch.sh -
Verify Installation: You should see the DOCAT interface with no projects listed initially
-
Prepare Upload Token: Keep your
DOCAT_UPLOAD_TOKENhandy for uploading documentation
Preparing Documentation
DOCAT accepts documentation in various formats. Here’s how to prepare common documentation types:
Sphinx Documentation
# Build Sphinx documentationcd docs/make html
# Create archivecd _build/htmltar -czf ../../sphinx-docs.tar.gz .MkDocs Documentation
# Build MkDocs sitemkdocs build
# Create archivecd site/tar -czf ../mkdocs-docs.tar.gz .JSDoc Documentation
# Generate JSDocjsdoc -c jsdoc.json -r src/ -d docs/
# Create archivecd docs/tar -czf ../jsdoc-docs.tar.gz .Static HTML Documentation
# Any static HTML sitecd your-docs/tar -czf ../docs.tar.gz .Uploading Documentation
Method 1: Using curl
Upload documentation directly via curl:
# Upload version 1.0.0 of my-projectcurl -X POST https://your-app.klutch.sh/api/project/my-project/1.0.0 \ -H "Docat-Api-Key: your-secure-token-here" \ -F "file=@docs.tar.gz"
# Upload with branch namecurl -X POST https://your-app.klutch.sh/api/project/my-project/feature-branch \ -H "Docat-Api-Key: your-secure-token-here" \ -F "file=@docs.tar.gz"
# Upload as "latest"curl -X POST https://your-app.klutch.sh/api/project/my-project/latest \ -H "Docat-Api-Key: your-secure-token-here" \ -F "file=@docs.tar.gz"Response on success:
{ "message": "Documentation uploaded successfully", "project": "my-project", "version": "1.0.0"}Method 2: Using DOCAT CLI
Install the DOCAT CLI tool:
npm install -g docat-cliUpload documentation:
# Configure DOCAT CLIexport DOCAT_URL=https://your-app.klutch.shexport DOCAT_API_KEY=your-secure-token-here
# Upload documentationdocat push --project my-project --version 1.0.0 ./docs/
# Upload from build directorycd build/html && docat push --project my-project --version 2.0.0 .Method 3: CI/CD Integration
GitHub Actions Example:
name: Deploy Documentation
on: push: tags: - 'v*'
jobs: deploy-docs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3
- name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.11'
- name: Install dependencies run: | pip install sphinx sphinx-rtd-theme
- name: Build documentation run: | cd docs make html
- name: Create archive run: | cd docs/_build/html tar -czf ../../../docs.tar.gz .
- name: Extract version from tag id: get_version run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Upload to DOCAT env: DOCAT_URL: ${{ secrets.DOCAT_URL }} DOCAT_API_KEY: ${{ secrets.DOCAT_API_KEY }} run: | curl -X POST $DOCAT_URL/api/project/my-project/${{ steps.get_version.outputs.VERSION }} \ -H "Docat-Api-Key: $DOCAT_API_KEY" \ -F "file=@docs.tar.gz"GitLab CI Example:
deploy-docs: stage: deploy image: python:3.11 script: - pip install sphinx sphinx-rtd-theme - cd docs && make html - cd _build/html && tar -czf ../../../docs.tar.gz . - cd ../../.. - | curl -X POST $DOCAT_URL/api/project/my-project/$CI_COMMIT_TAG \ -H "Docat-Api-Key: $DOCAT_API_KEY" \ -F "file=@docs.tar.gz" only: - tags variables: DOCAT_URL: "https://your-app.klutch.sh"Accessing Documentation
Once uploaded, access your documentation:
- Navigate to DOCAT: Visit
https://your-app.klutch.sh - Select Project: Click on your project name
- Choose Version: Select the version from the dropdown
- Browse Documentation: Navigate through your docs
Direct URL format:
https://your-app.klutch.sh/doc/project-name/version/https://your-app.klutch.sh/doc/my-project/1.0.0/https://your-app.klutch.sh/doc/my-project/latest/Managing Documentation Versions
List All Projects
curl https://your-app.klutch.sh/api/projectsResponse:
{ "projects": [ { "name": "my-project", "versions": ["1.0.0", "1.1.0", "2.0.0", "latest"] }, { "name": "another-project", "versions": ["1.0.0"] } ]}List Versions for a Project
curl https://your-app.klutch.sh/api/project/my-projectResponse:
{ "project": "my-project", "versions": ["1.0.0", "1.1.0", "2.0.0", "latest"]}Delete a Version
curl -X DELETE https://your-app.klutch.sh/api/project/my-project/1.0.0 \ -H "Docat-Api-Key: your-secure-token-here"Delete an Entire Project
curl -X DELETE https://your-app.klutch.sh/api/project/my-project \ -H "Docat-Api-Key: your-secure-token-here"Production Best Practices
Security Hardening
- Strong Upload Tokens: Generate cryptographically secure tokens:
# Generate a strong tokenopenssl rand -base64 32
# Update environment variable in Klutch.shDOCAT_UPLOAD_TOKEN=<generated-token>- Token Rotation: Regularly rotate upload tokens:
{ "tokens": [ { "name": "ci-token-2024", "token": "new-secure-token", "projects": ["*"], "created": "2024-01-01" } ]}- Project-Specific Tokens: Use different tokens for different projects:
{ "tokens": [ { "name": "frontend-team", "token": "token-for-frontend-projects", "projects": ["web-app", "mobile-app", "admin-panel"] }, { "name": "backend-team", "token": "token-for-backend-projects", "projects": ["api-server", "worker-service"] } ]}-
HTTPS Only: Ensure all connections use HTTPS (automatic with Klutch.sh)
-
Security Headers: Add additional security headers in Nginx:
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:;" always;add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;Backup Strategy
Implement regular backups of your documentation:
- Volume Backups: Schedule regular backups of the
/docdirectory:
#!/bin/bashBACKUP_DIR="/backups/docat_$(date +%Y%m%d_%H%M%S)"mkdir -p $BACKUP_DIR
# Backup documentationtar -czf $BACKUP_DIR/docs.tar.gz /doc
# Backup configurationcp upload_tokens.json $BACKUP_DIR/
# Keep only last 30 daysfind /backups -name "docat_*" -mtime +30 -delete- Automated Backups: Use cron or scheduled tasks:
# Add to crontab0 2 * * * /usr/local/bin/backup-docat.sh- Off-site Backups: Upload backups to cloud storage:
# Upload to S3aws s3 cp $BACKUP_DIR/docs.tar.gz s3://my-bucket/docat-backups/
# Or use rclone for other providersrclone copy $BACKUP_DIR remote:docat-backups/Performance Optimization
- Nginx Caching: Enable caching for static assets:
location /doc/ { alias /doc/;
# Enable caching expires 1h; add_header Cache-Control "public, immutable";
# Compression gzip_static on;}- Client-Side Caching: Set appropriate cache headers:
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable";}- Enable HTTP/2: Nginx with HTTP/2 (handled by Klutch.sh):
listen 443 ssl http2;- Precompression: Precompress large files:
# Find and compress HTML/CSS/JS filesfind /doc -type f \( -name "*.html" -o -name "*.css" -o -name "*.js" \) -exec gzip -k {} \;Monitoring and Logging
- Access Logs: Monitor documentation access:
# View recent accesstail -f /var/log/nginx/access.log
# Most accessed documentationawk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10- Error Logs: Track errors:
# View errorstail -f /var/log/nginx/error.log
# Count error typesgrep "error" /var/log/nginx/error.log | cut -d' ' -f9- | sort | uniq -c | sort -rn- Upload Monitoring: Track documentation uploads:
# Monitor API logstail -f /var/log/docat/docat.out.log | grep "upload"- Disk Usage Monitoring: Track storage consumption:
# Check documentation storagedu -sh /doc/*
# Alert if storage exceeds thresholdUSAGE=$(df /doc | tail -1 | awk '{print $5}' | sed 's/%//')if [ $USAGE -gt 80 ]; then echo "Warning: Storage usage is ${USAGE}%"fi- Health Check Script:
#!/bin/bashDOCAT_URL="https://your-app.klutch.sh"
# Check main pageif ! curl -f -s -o /dev/null $DOCAT_URL; then echo "ERROR: DOCAT is not responding" exit 1fi
# Check APIif ! curl -f -s -o /dev/null $DOCAT_URL/api/projects; then echo "ERROR: DOCAT API is not responding" exit 1fi
echo "OK: DOCAT is healthy"exit 0Resource Allocation
Recommended resources based on usage:
Small Team (1-10 projects):
- Memory: 512MB - 1GB
- CPU: 0.5 - 1 vCPU
- Storage: 10GB - 20GB
Medium Team (10-50 projects):
- Memory: 1GB - 2GB
- CPU: 1 - 2 vCPU
- Storage: 20GB - 50GB
Large Organization (50+ projects):
- Memory: 2GB - 4GB
- CPU: 2 - 4 vCPU
- Storage: 50GB - 200GB
Documentation Organization
- Naming Conventions: Use consistent project names:
# Good namingmy-projectapi-serverweb-app-frontend
# Avoid spaces and special characters- Version Naming: Follow semantic versioning:
# Releases1.0.0, 1.1.0, 2.0.0
# Pre-releases1.0.0-beta, 2.0.0-rc1
# Branchesfeature-new-api, develop, staging
# Special versionslatest, stable, edge- Project Structure: Organize related projects:
/doc├── backend-api/│ ├── 1.0.0/│ ├── 2.0.0/│ └── latest/├── frontend-web/│ ├── 1.0.0/│ └── latest/└── mobile-app/ ├── 1.0.0/ └── latest/Troubleshooting
Cannot Upload Documentation
Symptoms: Upload requests fail with 401 or 403 errors
Solutions:
- Verify Upload Token:
# Test tokencurl -X POST https://your-app.klutch.sh/api/project/test/1.0.0 \ -H "Docat-Api-Key: your-token" \ -F "file=@docs.tar.gz" -v- Check Token Configuration:
# Verify environment variable is setecho $DOCAT_UPLOAD_TOKEN
# Check token in upload_tokens.jsoncat upload_tokens.json- Verify Archive Format:
# Archive must be tar.gz or zipfile docs.tar.gz# Output should show: gzip compressed data
# Test archive extractiontar -tzf docs.tar.gz | head- Check File Size:
# Verify file isn't too large (default limit: 100MB)ls -lh docs.tar.gz
# Increase Nginx limit if needed in nginx.conf:# client_max_body_size 500M;Documentation Not Displaying
Symptoms: Uploaded documentation returns 404 or blank pages
Solutions:
- Verify Upload Success:
# List all projectscurl https://your-app.klutch.sh/api/projects
# Check specific project versionscurl https://your-app.klutch.sh/api/project/my-project- Check File Permissions:
# Inside containerls -la /doc/my-project/1.0.0/
# Fix permissions if neededchown -R nginx:nginx /doc- Verify index.html Exists:
# Check for index filels /doc/my-project/1.0.0/index.html
# Archive must contain index.html at roottar -tzf docs.tar.gz | grep index.html- Check Nginx Logs:
tail -f /var/log/nginx/error.logtail -f /var/log/nginx/access.logVersion Selector Not Working
Symptoms: Cannot switch between documentation versions
Solutions:
- Verify Multiple Versions Exist:
curl https://your-app.klutch.sh/api/project/my-project# Should show multiple versions- Check Frontend Loading:
# Verify frontend assets are loadingcurl https://your-app.klutch.sh/# Should return HTML with DOCAT interface-
Browser Console: Check for JavaScript errors in browser console
-
Clear Browser Cache: Force refresh with Ctrl+Shift+R (or Cmd+Shift+R on Mac)
High Storage Usage
Symptoms: Running out of disk space, slow performance
Solutions:
- Check Storage Usage:
# Total usagedu -sh /doc
# Per projectdu -sh /doc/* | sort -h
# Per versiondu -sh /doc/my-project/*- Delete Old Versions:
# Delete specific versioncurl -X DELETE https://your-app.klutch.sh/api/project/my-project/old-version \ -H "Docat-Api-Key: your-token"
# Script to delete old versions#!/bin/bashPROJECT="my-project"KEEP_VERSIONS=5
# List versions, skip latest N, delete restcurl -s https://your-app.klutch.sh/api/project/$PROJECT | \ jq -r '.versions[]' | \ tail -n +$((KEEP_VERSIONS + 1)) | \ while read VERSION; do curl -X DELETE https://your-app.klutch.sh/api/project/$PROJECT/$VERSION \ -H "Docat-Api-Key: your-token" done- Compress Documentation:
# Enable gzip compression in Nginx# Already configured in provided nginx.conf- Increase Volume Size: Expand storage in Klutch.sh dashboard
API Not Responding
Symptoms: API requests timeout or return errors
Solutions:
- Check API Process:
# Verify API is runningps aux | grep docat
# Check API logstail -f /var/log/docat/docat.err.log- Restart Services:
# Restart supervisorsupervisorctl restart docat
# Or restart entire containerdocker restart container_id- Check Port Binding:
# Verify API is listeningnetstat -tlnp | grep 5000- Test API Directly:
# Test from inside containercurl http://localhost:5000/projectsAdvanced Configuration
Custom Branding
Customize DOCAT’s appearance:
- Custom Logo: Replace the default logo:
# In DockerfileCOPY logo.png /var/www/html/static/logo.png- Custom Styling: Add custom CSS:
:root { --primary-color: #007bff; --background-color: #f8f9fa; --text-color: #333;}
.header { background-color: var(--primary-color);}
.project-card { border: 1px solid var(--primary-color);}Include in Nginx configuration:
location /custom.css { alias /var/www/html/custom.css;}- Custom Title: Modify HTML:
<title>Your Company Docs</title>Search Integration
Enable full-text search across documentation:
- Install Search Plugin (if using Sphinx):
extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinxcontrib.serializinghtml',]
html_theme = 'sphinx_rtd_theme'- Index Documentation:
# Use Elasticsearch or similar# Configure search backend- Search API Endpoint: Add custom search endpoint
Access Control
Implement authentication for private documentation:
- Basic Auth with Nginx:
location /doc/private-project/ { alias /doc/private-project/; auth_basic "Restricted Documentation"; auth_basic_user_file /etc/nginx/.htpasswd;}Create password file:
htpasswd -c /etc/nginx/.htpasswd username- IP Whitelist:
location /api/ { allow 192.168.1.0/24; allow 10.0.0.0/8; deny all;
proxy_pass http://localhost:5000/;}- OAuth Integration: Use oauth2-proxy for SSO:
services: oauth2-proxy: image: quay.io/oauth2-proxy/oauth2-proxy:latest ports: - "4180:4180" environment: OAUTH2_PROXY_PROVIDER: github OAUTH2_PROXY_CLIENT_ID: your-client-id OAUTH2_PROXY_CLIENT_SECRET: your-client-secret OAUTH2_PROXY_COOKIE_SECRET: your-cookie-secret OAUTH2_PROXY_UPSTREAM: http://docat:80Webhook Notifications
Send notifications when documentation is uploaded:
- Create Webhook Handler:
import requestsfrom flask import Flask, request
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])def handle_upload(): data = request.json project = data.get('project') version = data.get('version')
# Send to Slack slack_webhook = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL" message = { "text": f"📚 Documentation updated: {project} v{version}", "username": "DOCAT Bot" } requests.post(slack_webhook, json=message)
return {"status": "ok"}
if __name__ == '__main__': app.run(host='0.0.0.0', port=8080)- Configure DOCAT to Call Webhook:
# Modify DOCAT upload handler to trigger webhookAutomated Cleanup
Schedule automated cleanup of old documentation:
- Create Cleanup Script:
#!/bin/bashDOCAT_URL="https://your-app.klutch.sh"API_KEY="your-token"DAYS_TO_KEEP=90
# Find projectsPROJECTS=$(curl -s $DOCAT_URL/api/projects | jq -r '.projects[].name')
for PROJECT in $PROJECTS; do echo "Checking project: $PROJECT"
# Get versions with timestamps (requires modification to DOCAT API) VERSIONS=$(curl -s $DOCAT_URL/api/project/$PROJECT | jq -r '.versions[]')
for VERSION in $VERSIONS; do # Skip 'latest' and semantic versions if [[ "$VERSION" == "latest" ]] || [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then continue fi
# Check if version is a date-based branch (e.g., 2024-01-15) if [[ "$VERSION" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then VERSION_DATE=$(date -d "$VERSION" +%s) CUTOFF_DATE=$(date -d "$DAYS_TO_KEEP days ago" +%s)
if [ $VERSION_DATE -lt $CUTOFF_DATE ]; then echo "Deleting old version: $PROJECT/$VERSION" curl -X DELETE $DOCAT_URL/api/project/$PROJECT/$VERSION \ -H "Docat-Api-Key: $API_KEY" fi fi donedone- Schedule with Cron:
# Add to crontab - run weekly0 3 * * 0 /usr/local/bin/cleanup-old-docs.shMulti-Language Support
Host documentation in multiple languages:
- Language-Specific Projects:
# Upload English docscurl -X POST https://your-app.klutch.sh/api/project/my-project-en/1.0.0 \ -H "Docat-Api-Key: $TOKEN" -F "file=@docs-en.tar.gz"
# Upload Spanish docscurl -X POST https://your-app.klutch.sh/api/project/my-project-es/1.0.0 \ -H "Docat-Api-Key: $TOKEN" -F "file=@docs-es.tar.gz"- Language Selector: Add custom frontend to switch languages
API Extensions
Extend DOCAT API with custom endpoints:
from flask import Flask, jsonifyimport os
app = Flask(__name__)
@app.route('/api/stats')def stats(): """Return documentation statistics""" doc_path = '/doc' stats = { 'total_projects': len(os.listdir(doc_path)), 'total_size_mb': sum( os.path.getsize(os.path.join(dirpath, filename)) for dirpath, _, filenames in os.walk(doc_path) for filename in filenames ) / (1024 * 1024) } return jsonify(stats)
@app.route('/api/health')def health(): """Health check endpoint""" return jsonify({'status': 'healthy', 'version': '1.0.0'})Additional Resources
- DOCAT GitHub Repository
- DOCAT Official Documentation
- Sphinx Documentation
- MkDocs Documentation
- JSDoc Documentation
- Klutch.sh Documentation
- Persistent Storage Guide
- Custom Domain Configuration
Conclusion
DOCAT provides a straightforward, efficient solution for hosting versioned documentation. By deploying on Klutch.sh, you benefit from automatic HTTPS, persistent storage, and simple Docker-based deployment without the complexity of managing servers or dealing with complicated hosting configurations.
The platform’s simplicity is its strength—it does one thing and does it well. With easy API integration, support for multiple documentation formats, and seamless CI/CD integration, DOCAT fits naturally into modern development workflows. Whether you’re documenting a single open-source project or managing documentation for dozens of enterprise applications, DOCAT scales to meet your needs.
The version management system makes it easy to maintain documentation for multiple releases, while the clean interface ensures users can quickly find the information they need. Integration with popular documentation generators like Sphinx, MkDocs, and JSDoc means you can continue using your preferred tools while centralizing documentation hosting.
Start with the basic configuration outlined in this guide, then expand functionality through custom branding, search integration, or access controls as your documentation needs grow. Your documentation remains under your control, deployment is automated through CI/CD pipelines, and the lightweight design ensures fast page loads and minimal hosting costs.
Deploy DOCAT today and provide your team and users with a centralized, version-aware documentation hub that makes finding the right information effortless.