Add role-based filtering and imporve code

This commit is contained in:
Urtzi Alfaro
2025-10-15 16:12:49 +02:00
parent 96ad5c6692
commit 8f9e9a7edc
158 changed files with 11033 additions and 1544 deletions

View File

@@ -19,14 +19,14 @@ spec:
spec:
serviceAccountName: demo-session-sa
containers:
- name: demo-session
- name: demo-session-service
image: bakery/demo-session-service:latest
ports:
- containerPort: 8000
name: http
env:
- name: SERVICE_NAME
value: "demo-session"
value: "demo-session-service"
- name: DEMO_SESSION_DATABASE_URL
valueFrom:
secretKeyRef:
@@ -82,3 +82,14 @@ spec:
port: 8000
initialDelaySeconds: 10
periodSeconds: 10
startupProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 30
initContainers:
- name: wait-for-redis
image: busybox:1.36
command: ['sh', '-c', 'until nc -z redis-service 6379; do echo waiting for redis; sleep 2; done']

View File

@@ -0,0 +1,177 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: grafana-dashboards
namespace: monitoring
data:
gateway-metrics.json: |
{
"dashboard": {
"title": "Bakery IA - Gateway Metrics",
"tags": ["bakery-ia", "gateway"],
"timezone": "browser",
"panels": [
{
"id": 1,
"title": "Request Rate by Endpoint",
"type": "graph",
"gridPos": {"x": 0, "y": 0, "w": 12, "h": 8},
"targets": [{
"expr": "rate(http_requests_total{service=\"gateway\"}[5m])",
"legendFormat": "{{method}} {{endpoint}}"
}]
},
{
"id": 2,
"title": "P95 Request Latency",
"type": "graph",
"gridPos": {"x": 12, "y": 0, "w": 12, "h": 8},
"targets": [{
"expr": "histogram_quantile(0.95, rate(http_request_duration_seconds_bucket{service=\"gateway\"}[5m]))",
"legendFormat": "{{endpoint}} p95"
}]
},
{
"id": 3,
"title": "Error Rate (5xx)",
"type": "graph",
"gridPos": {"x": 0, "y": 8, "w": 12, "h": 8},
"targets": [{
"expr": "rate(http_requests_total{service=\"gateway\",status_code=~\"5..\"}[5m])",
"legendFormat": "{{endpoint}} errors"
}]
},
{
"id": 4,
"title": "Active Requests",
"type": "stat",
"gridPos": {"x": 12, "y": 8, "w": 6, "h": 4},
"targets": [{
"expr": "sum(rate(http_requests_total{service=\"gateway\"}[1m]))"
}]
},
{
"id": 5,
"title": "Authentication Success Rate",
"type": "stat",
"gridPos": {"x": 18, "y": 8, "w": 6, "h": 4},
"targets": [{
"expr": "rate(gateway_auth_responses_total[5m]) / rate(gateway_auth_requests_total[5m]) * 100"
}]
}
],
"refresh": "10s",
"schemaVersion": 16,
"version": 1
}
}
services-overview.json: |
{
"dashboard": {
"title": "Bakery IA - Services Overview",
"tags": ["bakery-ia", "services"],
"timezone": "browser",
"panels": [
{
"id": 1,
"title": "Request Rate by Service",
"type": "graph",
"gridPos": {"x": 0, "y": 0, "w": 12, "h": 8},
"targets": [{
"expr": "sum by (service) (rate(http_requests_total[5m]))",
"legendFormat": "{{service}}"
}]
},
{
"id": 2,
"title": "P99 Latency by Service",
"type": "graph",
"gridPos": {"x": 12, "y": 0, "w": 12, "h": 8},
"targets": [{
"expr": "histogram_quantile(0.99, sum by (service, le) (rate(http_request_duration_seconds_bucket[5m])))",
"legendFormat": "{{service}} p99"
}]
},
{
"id": 3,
"title": "Error Rate by Service",
"type": "graph",
"gridPos": {"x": 0, "y": 8, "w": 24, "h": 8},
"targets": [{
"expr": "sum by (service) (rate(http_requests_total{status_code=~\"5..\"}[5m]))",
"legendFormat": "{{service}}"
}]
},
{
"id": 4,
"title": "Service Health Status",
"type": "table",
"gridPos": {"x": 0, "y": 16, "w": 24, "h": 8},
"targets": [{
"expr": "up{job=\"bakery-services\"}",
"format": "table",
"instant": true
}],
"transformations": [{
"id": "organize",
"options": {
"excludeByName": {},
"indexByName": {},
"renameByName": {
"service": "Service Name",
"Value": "Status"
}
}
}]
}
],
"refresh": "30s",
"schemaVersion": 16,
"version": 1
}
}
circuit-breakers.json: |
{
"dashboard": {
"title": "Bakery IA - Circuit Breakers",
"tags": ["bakery-ia", "reliability"],
"timezone": "browser",
"panels": [
{
"id": 1,
"title": "Circuit Breaker States",
"type": "stat",
"gridPos": {"x": 0, "y": 0, "w": 24, "h": 4},
"targets": [{
"expr": "circuit_breaker_state",
"legendFormat": "{{service}} - {{state}}"
}]
},
{
"id": 2,
"title": "Circuit Breaker Trips",
"type": "graph",
"gridPos": {"x": 0, "y": 4, "w": 12, "h": 8},
"targets": [{
"expr": "rate(circuit_breaker_opened_total[5m])",
"legendFormat": "{{service}}"
}]
},
{
"id": 3,
"title": "Rejected Requests",
"type": "graph",
"gridPos": {"x": 12, "y": 4, "w": 12, "h": 8},
"targets": [{
"expr": "rate(circuit_breaker_rejected_total[5m])",
"legendFormat": "{{service}}"
}]
}
],
"refresh": "10s",
"schemaVersion": 16,
"version": 1
}
}

View File

@@ -0,0 +1,146 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: grafana-datasources
namespace: monitoring
data:
prometheus.yaml: |
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: false
---
apiVersion: v1
kind: ConfigMap
metadata:
name: grafana-dashboards-config
namespace: monitoring
data:
dashboards.yaml: |
apiVersion: 1
providers:
- name: 'default'
orgId: 1
folder: 'Bakery IA'
type: file
disableDeletion: false
updateIntervalSeconds: 10
allowUiUpdates: true
options:
path: /var/lib/grafana/dashboards
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana
namespace: monitoring
labels:
app: grafana
spec:
replicas: 1
selector:
matchLabels:
app: grafana
template:
metadata:
labels:
app: grafana
spec:
containers:
- name: grafana
image: grafana/grafana:10.2.2
ports:
- containerPort: 3000
name: http
env:
- name: GF_SECURITY_ADMIN_USER
value: admin
- name: GF_SECURITY_ADMIN_PASSWORD
value: admin
- name: GF_SERVER_ROOT_URL
value: "http://monitoring.bakery-ia.local/grafana"
- name: GF_SERVER_SERVE_FROM_SUB_PATH
value: "true"
- name: GF_AUTH_ANONYMOUS_ENABLED
value: "false"
- name: GF_INSTALL_PLUGINS
value: ""
volumeMounts:
- name: grafana-storage
mountPath: /var/lib/grafana
- name: grafana-datasources
mountPath: /etc/grafana/provisioning/datasources
- name: grafana-dashboards-config
mountPath: /etc/grafana/provisioning/dashboards
- name: grafana-dashboards
mountPath: /var/lib/grafana/dashboards
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: grafana-storage
persistentVolumeClaim:
claimName: grafana-storage
- name: grafana-datasources
configMap:
name: grafana-datasources
- name: grafana-dashboards-config
configMap:
name: grafana-dashboards-config
- name: grafana-dashboards
configMap:
name: grafana-dashboards
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: grafana-storage
namespace: monitoring
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: Service
metadata:
name: grafana
namespace: monitoring
labels:
app: grafana
spec:
type: ClusterIP
ports:
- port: 3000
targetPort: 3000
protocol: TCP
name: http
selector:
app: grafana

View File

@@ -0,0 +1,35 @@
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: monitoring-ingress
namespace: monitoring
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host: monitoring.bakery-ia.local
http:
paths:
- path: /grafana(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: grafana
port:
number: 3000
- path: /prometheus(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: prometheus
port:
number: 9090
- path: /jaeger(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: jaeger-query
port:
number: 16686

View File

@@ -0,0 +1,190 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jaeger
namespace: monitoring
labels:
app: jaeger
spec:
replicas: 1
selector:
matchLabels:
app: jaeger
template:
metadata:
labels:
app: jaeger
spec:
containers:
- name: jaeger
image: jaegertracing/all-in-one:1.51
env:
- name: COLLECTOR_ZIPKIN_HOST_PORT
value: ":9411"
- name: COLLECTOR_OTLP_ENABLED
value: "true"
- name: SPAN_STORAGE_TYPE
value: "badger"
- name: BADGER_EPHEMERAL
value: "false"
- name: BADGER_DIRECTORY_VALUE
value: "/badger/data"
- name: BADGER_DIRECTORY_KEY
value: "/badger/key"
ports:
- containerPort: 5775
protocol: UDP
name: zipkin-compact
- containerPort: 6831
protocol: UDP
name: jaeger-compact
- containerPort: 6832
protocol: UDP
name: jaeger-binary
- containerPort: 5778
protocol: TCP
name: config-rest
- containerPort: 16686
protocol: TCP
name: query
- containerPort: 14250
protocol: TCP
name: grpc
- containerPort: 14268
protocol: TCP
name: c-tchan-trft
- containerPort: 14269
protocol: TCP
name: admin-http
- containerPort: 9411
protocol: TCP
name: zipkin
- containerPort: 4317
protocol: TCP
name: otlp-grpc
- containerPort: 4318
protocol: TCP
name: otlp-http
volumeMounts:
- name: jaeger-storage
mountPath: /badger
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
livenessProbe:
httpGet:
path: /
port: 14269
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 14269
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: jaeger-storage
persistentVolumeClaim:
claimName: jaeger-storage
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jaeger-storage
namespace: monitoring
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: Service
metadata:
name: jaeger-query
namespace: monitoring
labels:
app: jaeger
spec:
type: ClusterIP
ports:
- port: 16686
targetPort: 16686
protocol: TCP
name: query
selector:
app: jaeger
---
apiVersion: v1
kind: Service
metadata:
name: jaeger-collector
namespace: monitoring
labels:
app: jaeger
spec:
type: ClusterIP
ports:
- port: 14268
targetPort: 14268
protocol: TCP
name: c-tchan-trft
- port: 14250
targetPort: 14250
protocol: TCP
name: grpc
- port: 9411
targetPort: 9411
protocol: TCP
name: zipkin
- port: 4317
targetPort: 4317
protocol: TCP
name: otlp-grpc
- port: 4318
targetPort: 4318
protocol: TCP
name: otlp-http
selector:
app: jaeger
---
apiVersion: v1
kind: Service
metadata:
name: jaeger-agent
namespace: monitoring
labels:
app: jaeger
spec:
type: ClusterIP
clusterIP: None
ports:
- port: 5775
targetPort: 5775
protocol: UDP
name: zipkin-compact
- port: 6831
targetPort: 6831
protocol: UDP
name: jaeger-compact
- port: 6832
targetPort: 6832
protocol: UDP
name: jaeger-binary
- port: 5778
targetPort: 5778
protocol: TCP
name: config-rest
selector:
app: jaeger

View File

@@ -0,0 +1,10 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- prometheus.yaml
- grafana.yaml
- grafana-dashboards.yaml
- jaeger.yaml
- ingress.yaml

View File

@@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: monitoring
labels:
name: monitoring
app.kubernetes.io/part-of: bakery-ia

View File

@@ -0,0 +1,210 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus
namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus
rules:
- apiGroups: [""]
resources:
- nodes
- nodes/proxy
- services
- endpoints
- pods
verbs: ["get", "list", "watch"]
- apiGroups:
- extensions
resources:
- ingresses
verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus
subjects:
- kind: ServiceAccount
name: prometheus
namespace: monitoring
---
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
namespace: monitoring
data:
prometheus.yml: |
global:
scrape_interval: 30s
evaluation_interval: 30s
external_labels:
cluster: 'bakery-ia'
environment: 'production'
scrape_configs:
# Scrape Prometheus itself
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# Scrape all bakery-ia services
- job_name: 'bakery-services'
kubernetes_sd_configs:
- role: pod
namespaces:
names:
- bakery-ia
relabel_configs:
# Only scrape pods with metrics port
- source_labels: [__meta_kubernetes_pod_container_port_name]
action: keep
regex: http
# Add service name label
- source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_name]
target_label: service
# Add component label
- source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_component]
target_label: component
# Add pod name
- source_labels: [__meta_kubernetes_pod_name]
target_label: pod
# Set metrics path
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
# Set scrape port
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
# Scrape Kubernetes nodes
- job_name: 'kubernetes-nodes'
kubernetes_sd_configs:
- role: node
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- target_label: __address__
replacement: kubernetes.default.svc:443
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __metrics_path__
replacement: /api/v1/nodes/${1}/proxy/metrics
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus
namespace: monitoring
labels:
app: prometheus
spec:
replicas: 1
selector:
matchLabels:
app: prometheus
template:
metadata:
labels:
app: prometheus
spec:
serviceAccountName: prometheus
containers:
- name: prometheus
image: prom/prometheus:v2.48.0
args:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=30d'
- '--web.console.libraries=/usr/share/prometheus/console_libraries'
- '--web.console.templates=/usr/share/prometheus/consoles'
- '--web.enable-lifecycle'
ports:
- containerPort: 9090
name: web
volumeMounts:
- name: prometheus-config
mountPath: /etc/prometheus
- name: prometheus-storage
mountPath: /prometheus
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "1"
livenessProbe:
httpGet:
path: /-/healthy
port: 9090
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /-/ready
port: 9090
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: prometheus-config
configMap:
name: prometheus-config
- name: prometheus-storage
persistentVolumeClaim:
claimName: prometheus-storage
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: prometheus-storage
namespace: monitoring
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: v1
kind: Service
metadata:
name: prometheus
namespace: monitoring
labels:
app: prometheus
spec:
type: ClusterIP
ports:
- port: 9090
targetPort: 9090
protocol: TCP
name: web
selector:
app: prometheus

View File

@@ -0,0 +1,158 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nominatim-config
namespace: bakery-ia
labels:
app.kubernetes.io/name: nominatim
app.kubernetes.io/component: geocoding
data:
NOMINATIM_PBF_URL: "http://download.geofabrik.de/europe/spain-latest.osm.pbf"
NOMINATIM_REPLICATION_URL: "https://download.geofabrik.de/europe/spain-updates"
NOMINATIM_IMPORT_STYLE: "address"
NOMINATIM_THREADS: "4"
NOMINATIM_FLATNODE_FILE: "/nominatim-flatnode/flatnode.bin"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nominatim-data
namespace: bakery-ia
labels:
app.kubernetes.io/name: nominatim
app.kubernetes.io/component: geocoding
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nominatim-flatnode
namespace: bakery-ia
labels:
app.kubernetes.io/name: nominatim
app.kubernetes.io/component: geocoding
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nominatim
namespace: bakery-ia
labels:
app.kubernetes.io/name: nominatim
app.kubernetes.io/component: geocoding
app.kubernetes.io/part-of: bakery-ia
spec:
serviceName: nominatim-service
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: nominatim
app.kubernetes.io/component: geocoding
template:
metadata:
labels:
app.kubernetes.io/name: nominatim
app.kubernetes.io/component: geocoding
spec:
containers:
- name: nominatim
image: mediagis/nominatim:4.4
ports:
- containerPort: 8080
name: http
volumeMounts:
- name: nominatim-data
mountPath: /var/lib/postgresql
- name: nominatim-flatnode
mountPath: /nominatim-flatnode
env:
- name: NOMINATIM_PBF_URL
valueFrom:
configMapKeyRef:
name: nominatim-config
key: NOMINATIM_PBF_URL
- name: NOMINATIM_REPLICATION_URL
valueFrom:
configMapKeyRef:
name: nominatim-config
key: NOMINATIM_REPLICATION_URL
- name: NOMINATIM_IMPORT_STYLE
valueFrom:
configMapKeyRef:
name: nominatim-config
key: NOMINATIM_IMPORT_STYLE
- name: NOMINATIM_THREADS
valueFrom:
configMapKeyRef:
name: nominatim-config
key: NOMINATIM_THREADS
- name: NOMINATIM_FLATNODE_FILE
valueFrom:
configMapKeyRef:
name: nominatim-config
key: NOMINATIM_FLATNODE_FILE
resources:
requests:
memory: "2Gi"
cpu: "1"
limits:
memory: "4Gi"
cpu: "2"
livenessProbe:
httpGet:
path: /status
port: 8080
initialDelaySeconds: 120
periodSeconds: 30
timeoutSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /status
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 5
volumes:
- name: nominatim-data
persistentVolumeClaim:
claimName: nominatim-data
- name: nominatim-flatnode
persistentVolumeClaim:
claimName: nominatim-flatnode
---
apiVersion: v1
kind: Service
metadata:
name: nominatim-service
namespace: bakery-ia
labels:
app.kubernetes.io/name: nominatim
app.kubernetes.io/component: geocoding
spec:
selector:
app.kubernetes.io/name: nominatim
app.kubernetes.io/component: geocoding
ports:
- port: 8080
targetPort: 8080
protocol: TCP
name: http
type: ClusterIP

View File

@@ -2,6 +2,7 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: bakery-config
namespace: bakery-ia
labels:
app.kubernetes.io/name: bakery-ia
app.kubernetes.io/component: config
@@ -9,7 +10,7 @@ data:
# ================================================================
# ENVIRONMENT & BUILD SETTINGS
# ================================================================
ENVIRONMENT: "production"
ENVIRONMENT: "development"
DEBUG: "false"
LOG_LEVEL: "INFO"
@@ -323,12 +324,22 @@ data:
VITE_ENVIRONMENT: "production"
# ================================================================
# LOCATION SETTINGS
# LOCATION SETTINGS (Nominatim Geocoding)
# ================================================================
NOMINATIM_SERVICE_URL: "http://nominatim-service:8080"
NOMINATIM_PBF_URL: "http://download.geofabrik.de/europe/spain-latest.osm.pbf"
NOMINATIM_MEMORY_LIMIT: "8G"
NOMINATIM_CPU_LIMIT: "4"
# ================================================================
# DISTRIBUTED TRACING (Jaeger/OpenTelemetry)
# ================================================================
JAEGER_COLLECTOR_ENDPOINT: "http://jaeger-collector.monitoring:4317"
JAEGER_AGENT_HOST: "jaeger-agent.monitoring"
JAEGER_AGENT_PORT: "6831"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://jaeger-collector.monitoring:4317"
OTEL_SERVICE_NAME: "bakery-ia"
# ================================================================
# EXTERNAL DATA SERVICE V2 SETTINGS
# ================================================================

View File

@@ -2,6 +2,7 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: postgres-init-config
namespace: bakery-ia
labels:
app.kubernetes.io/component: database
app.kubernetes.io/part-of: bakery-ia

View File

@@ -0,0 +1,83 @@
apiVersion: batch/v1
kind: Job
metadata:
name: nominatim-init
namespace: bakery-ia
labels:
app.kubernetes.io/name: nominatim-init
app.kubernetes.io/component: data-init
app.kubernetes.io/part-of: bakery-ia
spec:
ttlSecondsAfterFinished: 86400
template:
metadata:
labels:
app.kubernetes.io/name: nominatim-init
app.kubernetes.io/component: data-init
spec:
restartPolicy: OnFailure
containers:
- name: nominatim-import
image: mediagis/nominatim:4.4
command:
- sh
- -c
- |
set -e
echo "Checking if Nominatim database is already initialized..."
if psql -lqt | cut -d \| -f 1 | grep -qw nominatim; then
echo "Nominatim database already exists. Skipping import."
exit 0
fi
echo "Downloading Spain OSM data..."
wget -O /tmp/spain-latest.osm.pbf "${NOMINATIM_PBF_URL}"
echo "Importing OSM data into Nominatim (this may take 30-60 minutes)..."
nominatim import --osm-file /tmp/spain-latest.osm.pbf
echo "Building search indices..."
nominatim refresh --website --importance
echo "Nominatim initialization complete!"
volumeMounts:
- name: nominatim-data
mountPath: /var/lib/postgresql
- name: nominatim-flatnode
mountPath: /nominatim-flatnode
env:
- name: NOMINATIM_PBF_URL
valueFrom:
configMapKeyRef:
name: nominatim-config
key: NOMINATIM_PBF_URL
- name: NOMINATIM_IMPORT_STYLE
valueFrom:
configMapKeyRef:
name: nominatim-config
key: NOMINATIM_IMPORT_STYLE
- name: NOMINATIM_THREADS
valueFrom:
configMapKeyRef:
name: nominatim-config
key: NOMINATIM_THREADS
- name: NOMINATIM_FLATNODE_FILE
valueFrom:
configMapKeyRef:
name: nominatim-config
key: NOMINATIM_FLATNODE_FILE
resources:
requests:
memory: "8Gi"
cpu: "4"
limits:
memory: "16Gi"
cpu: "8"
volumes:
- name: nominatim-data
persistentVolumeClaim:
claimName: nominatim-data
- name: nominatim-flatnode
persistentVolumeClaim:
claimName: nominatim-flatnode

View File

@@ -55,6 +55,10 @@ resources:
- components/databases/rabbitmq.yaml
- components/infrastructure/gateway-service.yaml
# Nominatim geocoding service
- components/nominatim/nominatim.yaml
- jobs/nominatim-init-job.yaml
# Persistent storage
- components/volumes/model-storage-pvc.yaml

View File

@@ -4,13 +4,101 @@ kind: Kustomization
metadata:
name: bakery-ia-dev
namespace: bakery-ia
# Note: Removed global namespace to prevent monitoring namespace conflict
# All base resources already have namespace: bakery-ia defined
resources:
- ../../base
# Monitoring disabled for dev to save resources
# - ../../base/components/monitoring
- dev-ingress.yaml
# Exclude nominatim from dev to save resources
# Using scale to 0 for StatefulSet to prevent pod creation
patches:
# Override specific ConfigMap values for development
- target:
kind: ConfigMap
name: bakery-config
patch: |-
- op: replace
path: /data/ENVIRONMENT
value: "development"
- op: replace
path: /data/DEBUG
value: "true"
- op: replace
path: /data/LOG_LEVEL
value: "DEBUG"
- op: replace
path: /data/AUTO_RELOAD
value: "true"
- op: replace
path: /data/PROFILING_ENABLED
value: "true"
- op: replace
path: /data/MOCK_EXTERNAL_APIS
value: "true"
- op: replace
path: /data/TESTING
value: "false"
- op: replace
path: /data/DOMAIN
value: "localhost"
- op: replace
path: /data/API_DOCS_ENABLED
value: "true"
- op: replace
path: /data/CORS_ORIGINS
value: "http://frontend-service:3000,http://localhost:3000,http://localhost:3001,http://localhost,http://127.0.0.1:3000,http://127.0.0.1:3001,http://bakery-ia.local,https://localhost,https://127.0.0.1"
- op: replace
path: /data/VITE_ENVIRONMENT
value: "development"
- op: replace
path: /data/VITE_API_URL
value: "/api"
- op: replace
path: /data/STRIPE_PUBLISHABLE_KEY
value: "pk_test_your_stripe_publishable_key_here"
- op: replace
path: /data/SQUARE_ENVIRONMENT
value: "sandbox"
- op: replace
path: /data/TOAST_ENVIRONMENT
value: "sandbox"
- op: replace
path: /data/LIGHTSPEED_ENVIRONMENT
value: "sandbox"
- op: replace
path: /data/RATE_LIMIT_ENABLED
value: "false"
- op: replace
path: /data/DB_FORCE_RECREATE
value: "false"
- op: add
path: /data/DEVELOPMENT_MODE
value: "true"
- op: add
path: /data/DEBUG_LOGGING
value: "true"
- op: add
path: /data/SKIP_MIGRATION_VERSION_CHECK
value: "false"
- target:
kind: StatefulSet
name: nominatim
patch: |-
- op: replace
path: /spec/replicas
value: 0
# Suspend nominatim-init job in dev (not needed when nominatim is scaled to 0)
- target:
kind: Job
name: nominatim-init
patch: |-
- op: replace
path: /spec/suspend
value: true
- target:
group: apps
version: v1
@@ -485,43 +573,6 @@ patches:
memory: "1Gi"
cpu: "500m"
configMapGenerator:
- name: bakery-config
behavior: merge
literals:
# Environment & Build Settings
- ENVIRONMENT=development
- DEBUG=true
- LOG_LEVEL=DEBUG
- AUTO_RELOAD=true
- PROFILING_ENABLED=true
- MOCK_EXTERNAL_APIS=true
- TESTING=false
- DOMAIN=localhost
- API_DOCS_ENABLED=true
# CORS Configuration for Development
- CORS_ORIGINS=http://frontend-service:3000,http://localhost:3000,http://localhost:3001,http://localhost,http://127.0.0.1:3000,http://127.0.0.1:3001,http://bakery-ia.local,https://localhost,https://127.0.0.1
# Frontend Development Configuration
- VITE_ENVIRONMENT=development
- VITE_API_URL=/api
# Payment Configuration (Sandbox for dev)
- STRIPE_PUBLISHABLE_KEY=pk_test_your_stripe_publishable_key_here
- SQUARE_ENVIRONMENT=sandbox
- TOAST_ENVIRONMENT=sandbox
- LIGHTSPEED_ENVIRONMENT=sandbox
# Rate Limiting (Disabled for dev)
- RATE_LIMIT_ENABLED=false
# Database (Development mode)
- DB_FORCE_RECREATE=false
- DEVELOPMENT_MODE=true
- DEBUG_LOGGING=true
- SKIP_MIGRATION_VERSION_CHECK=false
secretGenerator:
- name: dev-secrets
literals: