# πŸš€ Deployment Guide - Goa-GEL Documentation Service Complete guide to deploy the documentation service in various environments. --- ## πŸ“‹ Prerequisites - Docker 20.10+ or Docker Desktop - Docker Compose 1.29+ (if using compose) - Port 8080 available (or configure different port) --- ## 🐳 Docker Deployment (Recommended) ### Quick Deploy ```bash # From the Documentation directory docker build -t goa-gel-docs . docker run -d -p 8080:80 --name goa-gel-docs goa-gel-docs # Verify it's running docker ps | grep goa-gel-docs # Access the documentation open http://localhost:8080 ``` ### Docker Compose Deploy ```bash # Start the service docker-compose up -d # Check logs docker-compose logs -f documentation # Stop the service docker-compose down ``` --- ## 🌐 Production Deployment ### 1. Build Production Image ```bash # Build with version tag docker build -t goa-gel-docs:1.0.0 . # Tag for production registry docker tag goa-gel-docs:1.0.0 your-registry.com/goa-gel-docs:1.0.0 docker tag goa-gel-docs:1.0.0 your-registry.com/goa-gel-docs:latest # Push to registry docker push your-registry.com/goa-gel-docs:1.0.0 docker push your-registry.com/goa-gel-docs:latest ``` ### 2. Deploy to Server ```bash # Pull image on production server docker pull your-registry.com/goa-gel-docs:1.0.0 # Run with production settings docker run -d \ --name goa-gel-docs \ -p 8080:80 \ --restart always \ --memory="256m" \ --cpus="0.5" \ -l "service=documentation" \ your-registry.com/goa-gel-docs:1.0.0 ``` ### 3. Health Check ```bash # Check if service is healthy curl http://localhost:8080 # Expected output: HTML of homepage # Check Docker health status docker inspect --format='{{.State.Health.Status}}' goa-gel-docs # Expected: healthy ``` --- ## ☸️ Kubernetes Deployment ### Create Kubernetes Manifests **deployment.yaml**: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: goa-gel-docs namespace: goa-gel spec: replicas: 2 selector: matchLabels: app: goa-gel-docs template: metadata: labels: app: goa-gel-docs spec: containers: - name: goa-gel-docs image: your-registry.com/goa-gel-docs:1.0.0 ports: - containerPort: 80 resources: limits: memory: "256Mi" cpu: "500m" requests: memory: "128Mi" cpu: "250m" livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 5 periodSeconds: 10 readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 3 periodSeconds: 5 ``` **service.yaml**: ```yaml apiVersion: v1 kind: Service metadata: name: goa-gel-docs namespace: goa-gel spec: selector: app: goa-gel-docs ports: - port: 80 targetPort: 80 protocol: TCP type: ClusterIP ``` **ingress.yaml**: ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: goa-gel-docs namespace: goa-gel annotations: nginx.ingress.kubernetes.io/rewrite-target: / cert-manager.io/cluster-issuer: "letsencrypt-prod" spec: ingressClassName: nginx tls: - hosts: - docs.goa-gel.gov.in secretName: goa-gel-docs-tls rules: - host: docs.goa-gel.gov.in http: paths: - path: / pathType: Prefix backend: service: name: goa-gel-docs port: number: 80 ``` ### Deploy to Kubernetes ```bash # Create namespace kubectl create namespace goa-gel # Apply manifests kubectl apply -f deployment.yaml kubectl apply -f service.yaml kubectl apply -f ingress.yaml # Check deployment kubectl get pods -n goa-gel kubectl get svc -n goa-gel kubectl get ingress -n goa-gel # Check logs kubectl logs -f deployment/goa-gel-docs -n goa-gel ``` --- ## πŸ”’ HTTPS/SSL Setup ### Option 1: Let's Encrypt (Certbot) ```bash # Install certbot sudo apt-get install certbot python3-certbot-nginx # Get certificate sudo certbot --nginx -d docs.goa-gel.gov.in # Auto-renewal is configured automatically # Test renewal sudo certbot renew --dry-run ``` ### Option 2: Custom Certificate ```nginx # Add to nginx.conf server { listen 443 ssl http2; server_name docs.goa-gel.gov.in; ssl_certificate /etc/ssl/certs/goa-gel-docs.crt; ssl_certificate_key /etc/ssl/private/goa-gel-docs.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; # ... rest of config } # Redirect HTTP to HTTPS server { listen 80; server_name docs.goa-gel.gov.in; return 301 https://$server_name$request_uri; } ``` --- ## πŸ”„ Reverse Proxy Setup ### Nginx Reverse Proxy ```nginx # /etc/nginx/sites-available/goa-gel-docs upstream docs_backend { server localhost:8080; } server { listen 80; server_name docs.goa-gel.gov.in; location / { proxy_pass http://docs_backend; 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; } } ``` ```bash # Enable site sudo ln -s /etc/nginx/sites-available/goa-gel-docs /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx ``` ### Apache Reverse Proxy ```apache # /etc/apache2/sites-available/goa-gel-docs.conf ServerName docs.goa-gel.gov.in ProxyPreserveHost On ProxyPass / http://localhost:8080/ ProxyPassReverse / http://localhost:8080/ ErrorLog ${APACHE_LOG_DIR}/goa-gel-docs-error.log CustomLog ${APACHE_LOG_DIR}/goa-gel-docs-access.log combined ``` ```bash # Enable modules and site sudo a2enmod proxy proxy_http sudo a2ensite goa-gel-docs sudo systemctl reload apache2 ``` --- ## πŸ“Š Monitoring ### Health Check Endpoint ```bash # Check if service is running curl -f http://localhost:8080/ || echo "Service down" # Check response time time curl -s http://localhost:8080/ > /dev/null ``` ### Docker Stats ```bash # Monitor resource usage docker stats goa-gel-docs # Expected: # CPU: < 1% idle, < 10% under load # Memory: ~20-50MB ``` ### Logs ```bash # View logs docker logs -f goa-gel-docs # Last 100 lines docker logs --tail 100 goa-gel-docs # Logs since timestamp docker logs --since 2024-01-01T00:00:00 goa-gel-docs ``` --- ## πŸ”§ Troubleshooting ### Service Won't Start ```bash # Check if port is in use lsof -i :8080 # Check Docker logs docker logs goa-gel-docs # Try different port docker run -d -p 9090:80 --name goa-gel-docs goa-gel-docs ``` ### High Memory Usage ```bash # Set memory limit docker update --memory="256m" goa-gel-docs # Or recreate with limit docker stop goa-gel-docs docker rm goa-gel-docs docker run -d \ -p 8080:80 \ --memory="256m" \ --name goa-gel-docs \ goa-gel-docs ``` ### Slow Performance ```bash # Check resource usage docker stats goa-gel-docs # Increase CPU allocation docker update --cpus="1.0" goa-gel-docs # Enable gzip compression (already enabled in nginx.conf) # Check if compression is working curl -H "Accept-Encoding: gzip" -I http://localhost:8080/ # Should see: Content-Encoding: gzip ``` --- ## πŸ”„ Updates ### Update Documentation Content ```bash # Update markdown files in docs/ # Then rebuild and redeploy docker build -t goa-gel-docs:1.0.1 . docker stop goa-gel-docs docker rm goa-gel-docs docker run -d -p 8080:80 --name goa-gel-docs goa-gel-docs:1.0.1 ``` ### Zero-Downtime Update (with 2+ instances) ```bash # Build new version docker build -t goa-gel-docs:1.0.1 . # Start new container on different port docker run -d -p 8081:80 --name goa-gel-docs-new goa-gel-docs:1.0.1 # Test new version curl http://localhost:8081/ # Update load balancer to point to 8081 # Then stop old container docker stop goa-gel-docs docker rm goa-gel-docs # Rename new container docker rename goa-gel-docs-new goa-gel-docs ``` --- ## πŸ” Security Best Practices ### 1. Run as Non-Root User Update Dockerfile: ```dockerfile # Add after FROM nginx:alpine RUN adduser -D -u 1000 docsuser USER docsuser ``` ### 2. Read-Only Filesystem ```bash docker run -d \ -p 8080:80 \ --read-only \ --tmpfs /tmp \ --tmpfs /var/run \ --tmpfs /var/cache/nginx \ --name goa-gel-docs \ goa-gel-docs ``` ### 3. Network Isolation ```bash # Create isolated network docker network create goa-gel-network # Run with network docker run -d \ -p 8080:80 \ --network goa-gel-network \ --name goa-gel-docs \ goa-gel-docs ``` ### 4. Security Scanning ```bash # Scan image for vulnerabilities docker scan goa-gel-docs # Or use Trivy trivy image goa-gel-docs ``` --- ## πŸ“ˆ Performance Optimization ### CDN Setup Use a CDN like Cloudflare for static assets: 1. Point domain to Cloudflare 2. Enable caching for: - `/css/*` - `/js/*` - `/docs/*` 3. Enable Brotli compression 4. Enable HTTP/3 ### Caching Headers Already configured in `nginx.conf`: ```nginx location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; } ``` --- ## πŸ§ͺ Testing Deployment ```bash # 1. Test homepage curl -I http://localhost:8080/ # Expected: 200 OK # 2. Test viewer curl -I http://localhost:8080/viewer.html # Expected: 200 OK # 3. Test documentation curl http://localhost:8080/docs/USER_GUIDE.md # Expected: Markdown content # 4. Test 404 handling curl -I http://localhost:8080/nonexistent # Expected: 404 Not Found # 5. Load test (requires Apache Bench) ab -n 1000 -c 10 http://localhost:8080/ # Should handle 1000 requests easily ``` --- ## πŸ“ž Support For deployment issues: - **Email**: devops@goa.gov.in - **Documentation**: README.md in this directory - **Source**: GitHub repository --- **Version**: 1.0.0 **Last Updated**: February 2026