docs(examples): Kubernetes Basic Deployment
@aRustyDev ya está trabajando en esto.
Desde el 5/1/2026.
Evaluación
Este issue todavía no se ha evaluado.
Descripción
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
- Add Meilisearch for search
- Configure Ingress authentication
- Deploy with Helm chart
- Lenguaje dominante
- Rust
- Estrellas
- 0
- Forks
- 1
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de aRustyDev/mdbook-htmx
-
feat(ci): Implement cross-repo-validate compliance for docs syncQuizá libre de nuevo @aRustyDev la tomó hace 283 días y no hay ningún pull request abierto. Abiertoci enhancement
aRustyDev/mdbook-htmx#58 · 1 comentario · 1 asignado ·
-
docs(htmx): Explain how HTMX worksQuizá libre de nuevo @aRustyDev la tomó hace 285 días y no hay ningún pull request abierto. Abierto
aRustyDev/mdbook-htmx#48 · 3 comentarios · 1 asignado ·
-
docs(mdbook-htmx): Parent Issue for documentationQuizá libre de nuevo @aRustyDev la tomó hace 286 días y no hay ningún pull request abierto. Abiertodocumentation
aRustyDev/mdbook-htmx#47 · 1 asignado ·
-
docs(examples): Secure Self-Hosted Meilisearch via CloudflareQuizá libre de nuevo @aRustyDev la tomó hace 286 días y no hay ningún pull request abierto. Abiertodocumentation
aRustyDev/mdbook-htmx#46 · 1 asignado ·
-
docs(examples): Kubernetes with MeilisearchQuizá libre de nuevo @aRustyDev la tomó hace 286 días y no hay ningún pull request abierto. Abiertodocumentation
aRustyDev/mdbook-htmx#45 · 1 asignado ·
Todos los issues de aRustyDev/mdbook-htmx
Issues similares
-
documentation P2
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
Los mantenedores suelen responder en 1 día
-
bug good first issue priority:high
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
Konfirm-xyz/konfirm-contracts#163 ·
Los mantenedores suelen responder en 1 día
-
area:gc-repack-output bug factory:dogfood factory:triaged priority:p3 type:bug type:ux
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
gitbutlerapp/grit#1161 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
Los mantenedores suelen responder en 1 día
-
feature performance
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
lance-format/lance#10137 ·
Los mantenedores suelen responder en 2 días