Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

docs(examples): Kubernetes Basic Deployment

Abierto
#43 0 comentarios 0 reacciones 1 asignado Ver en GitHub

@aRustyDev ya está trabajando en esto.

Desde el 5/1/2026.

Evaluación

Este issue todavía no se ha evaluado.

Descripción

documentation

Kubernetes Basic Deployment

Deploy mdbook-htmx on Kubernetes with a simple static file server.

Overview

This example uses:

  • NGINX or Caddy: Static file serving
  • ConfigMap: Configuration
  • PersistentVolume: Documentation storage (optional)
  • Ingress: External access

Architecture

                    ┌─────────────┐
                    │   Ingress   │
                    │  (NGINX)    │
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │   Service   │
                    │  (ClusterIP)│
                    └──────┬──────┘
                           │
              ┌────────────┼────────────┐
              │            │            │
        ┌─────▼─────┐┌─────▼─────┐┌─────▼─────┐
        │  Pod #1   ││  Pod #2   ││  Pod #3   │
        │  (nginx)  ││  (nginx)  ││  (nginx)  │
        └───────────┘└───────────┘└───────────┘

Kubernetes Manifests

namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: docs
  labels:
    app.kubernetes.io/name: mdbook-htmx
    app.kubernetes.io/component: documentation
configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
  namespace: docs
data:
  nginx.conf: |
    user nginx;
    worker_processes auto;
    error_log /var/log/nginx/error.log warn;
    pid /var/run/nginx.pid;

    events {
        worker_connections 1024;
        use epoll;
        multi_accept on;
    }

    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;

        # Gzip compression
        gzip on;
        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_types text/plain text/css text/xml application/json application/javascript
                   application/xml+rss application/atom+xml image/svg+xml;

        server {
            listen 80;
            server_name _;
            root /usr/share/nginx/html;
            index index.html;

            # Security headers
            add_header X-Frame-Options "SAMEORIGIN" always;
            add_header X-Content-Type-Options "nosniff" always;
            add_header X-XSS-Protection "1; mode=block" always;
            add_header Referrer-Policy "strict-origin-when-cross-origin" always;

            # Cache static assets
            location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
                expires 1y;
                add_header Cache-Control "public, immutable";
            }

            # Don't cache HTML
            location ~* \.html$ {
                expires -1;
                add_header Cache-Control "no-cache, no-store, must-revalidate";
            }

            # SPA fallback
            location / {
                try_files $uri $uri/ /index.html;
            }

            # Health check endpoint
            location /healthz {
                access_log off;
                return 200 "OK\n";
                add_header Content-Type text/plain;
            }
        }
    }
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: docs
  namespace: docs
  labels:
    app.kubernetes.io/name: mdbook-htmx
    app.kubernetes.io/component: server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: docs
  template:
    metadata:
      labels:
        app: docs
        app.kubernetes.io/name: mdbook-htmx
    spec:
      containers:
        - name: nginx
          image: nginx:alpine
          ports:
            - containerPort: 80
              name: http
          resources:
            requests:
              cpu: 50m
              memory: 64Mi
            limits:
              cpu: 200m
              memory: 128Mi
          volumeMounts:
            - name: nginx-config
              mountPath: /etc/nginx/nginx.conf
              subPath: nginx.conf
              readOnly: true
            - name: docs-content
              mountPath: /usr/share/nginx/html
              readOnly: true
          livenessProbe:
            httpGet:
              path: /healthz
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /healthz
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 5
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            runAsNonRoot: true
            runAsUser: 101  # nginx user
            capabilities:
              drop:
                - ALL
      volumes:
        - name: nginx-config
          configMap:
            name: nginx-config
        - name: docs-content
          configMap:
            name: docs-content
      securityContext:
        fsGroup: 101
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchExpressions:
                    - key: app
                      operator: In
                      values:
                        - docs
                topologyKey: kubernetes.io/hostname
service.yaml
apiVersion: v1
kind: Service
metadata:
  name: docs
  namespace: docs
  labels:
    app.kubernetes.io/name: mdbook-htmx
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: docs
ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: docs
  namespace: docs
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
spec:
  tls:
    - hosts:
        - docs.example.com
      secretName: docs-tls
  rules:
    - host: docs.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: docs
                port:
                  number: 80

CI/CD Integration

Build and Push Docs
# .github/workflows/deploy-k8s.yml
name: Deploy to Kubernetes

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build documentation
        run: |
          cargo install mdbook mdbook-htmx
          mdbook build

      - name: Create docs ConfigMap
        run: |
          kubectl create configmap docs-content \
            --from-file=book/ \
            --dry-run=client -o yaml > k8s/docs-content.yaml

      - name: Deploy to Kubernetes
        uses: azure/k8s-deploy@v4
        with:
          manifests: |
            k8s/namespace.yaml
            k8s/configmap.yaml
            k8s/docs-content.yaml
            k8s/deployment.yaml
            k8s/service.yaml
            k8s/ingress.yaml
          namespace: docs
Using Container Image Instead

For larger documentation sets, bake docs into a container:

# Dockerfile
FROM nginx:alpine

# Copy nginx config
COPY nginx.conf /etc/nginx/nginx.conf

# Copy documentation
COPY book/ /usr/share/nginx/html/

# Create non-root user
RUN chown -R nginx:nginx /usr/share/nginx/html && \
    chmod -R 755 /usr/share/nginx/html

USER nginx

EXPOSE 80

HEALTHCHECK --interval=30s --timeout=3s \
    CMD wget --no-verbose --tries=1 --spider http://localhost/healthz || exit 1

Updated deployment:

spec:
  containers:
    - name: docs
      image: ghcr.io/org/docs:latest
      # Remove docs-content volume mount

Scaling

Horizontal Pod Autoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: docs
  namespace: docs
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: docs
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80
Pod Disruption Budget
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: docs
  namespace: docs
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: docs

Monitoring

ServiceMonitor (Prometheus)
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: docs
  namespace: docs
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: mdbook-htmx
  endpoints:
    - port: http
      path: /metrics
      interval: 30s
Grafana Dashboard

Create a dashboard showing:

  • Request rate
  • Error rate
  • Response time percentiles
  • Pod health

Resource Estimation

Component CPU Memory Replicas Total
nginx 50m-200m 64-128Mi 3 150-600m CPU, 192-384Mi

For 10K daily users: 3 replicas is typically sufficient.

Next Steps

Lenguaje dominante
Rust
Estrellas
0
Forks
1
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de aRustyDev/mdbook-htmx

Todos los issues de aRustyDev/mdbook-htmx

Issues similares

Más issues de Rust

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.