docs(examples): Kubernetes Basic Deployment
@aRustyDev ci sta già lavorando.
Dal 5/1/2026.
Valutazione
Questa issue non è ancora stata valutata.
Descrizione
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
- Lingua principale
- Rust
- Stelle
- 0
- Fork
- 1
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di aRustyDev/mdbook-htmx
-
feat(ci): Implement cross-repo-validate compliance for docs syncForse di nuovo libera @aRustyDev l’ha presa 283 giorni fa e non c’è nessuna pull request aperta. Apertaci enhancement
aRustyDev/mdbook-htmx#58 · 1 commento · 1 assegnatario ·
-
docs(htmx): Explain how HTMX worksForse di nuovo libera @aRustyDev l’ha presa 285 giorni fa e non c’è nessuna pull request aperta. Aperta
aRustyDev/mdbook-htmx#48 · 3 commenti · 1 assegnatario ·
-
docs(mdbook-htmx): Parent Issue for documentationForse di nuovo libera @aRustyDev l’ha presa 285 giorni fa e non c’è nessuna pull request aperta. Apertadocumentation
aRustyDev/mdbook-htmx#47 · 1 assegnatario ·
-
docs(examples): Secure Self-Hosted Meilisearch via CloudflareForse di nuovo libera @aRustyDev l’ha presa 285 giorni fa e non c’è nessuna pull request aperta. Apertadocumentation
aRustyDev/mdbook-htmx#46 · 1 assegnatario ·
-
docs(examples): Kubernetes with MeilisearchForse di nuovo libera @aRustyDev l’ha presa 285 giorni fa e non c’è nessuna pull request aperta. Apertadocumentation
aRustyDev/mdbook-htmx#45 · 1 assegnatario ·
Tutte le issue di aRustyDev/mdbook-htmx
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno
-
[Bug] ComponentType classifies 0x8A8A-0xEAEA as GREASE; mls-extensions §7.5 makes them private useAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
I maintainer di solito rispondono entro 1 giorno
-
The book has a Nix install section that chelis.ch lacks, and it names two of the three systemsApertaarea:ecosystem documentation
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
Chelis-Lang/chelis#3866 ·
I maintainer di solito rispondono entro 1 giorno
-
[安卓Feature]: 数字键盘左侧符号区域大小优化Apertaenhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
metasequoiaime/msime#8620 ·
I maintainer di solito rispondono entro 1 giorno
-
agent-detection macos p2 triaged
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
I maintainer di solito rispondono entro 1 giorno