Add base kubernetes support 5
This commit is contained in:
@@ -35,35 +35,8 @@ COPY nginx.conf /etc/nginx/conf.d/
|
|||||||
# Copy built application from builder stage
|
# Copy built application from builder stage
|
||||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||||
|
|
||||||
# Create a script to substitute environment variables at runtime
|
# Copy and setup environment substitution script
|
||||||
COPY <<'EOF' /docker-entrypoint.d/30-substitute-env.sh
|
COPY substitute-env.sh /docker-entrypoint.d/30-substitute-env.sh
|
||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Handle VITE_API_URL specially to preserve empty values
|
|
||||||
# If VITE_API_URL is unset, use default; if empty, preserve empty; otherwise use value
|
|
||||||
if [ -z "${VITE_API_URL+x}" ]; then
|
|
||||||
export VITE_API_URL="/api"
|
|
||||||
elif [ -z "$VITE_API_URL" ]; then
|
|
||||||
# If VITE_API_URL is explicitly set to empty string, use relative API path
|
|
||||||
export VITE_API_URL="/api"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Default values for other environment variables
|
|
||||||
export VITE_APP_TITLE=${VITE_APP_TITLE:-"PanIA Dashboard"}
|
|
||||||
export VITE_APP_VERSION=${VITE_APP_VERSION:-"1.0.0"}
|
|
||||||
|
|
||||||
# Create a runtime configuration file that can be loaded by the frontend
|
|
||||||
cat > /usr/share/nginx/html/runtime-config.js << EOL
|
|
||||||
window.__RUNTIME_CONFIG__ = {
|
|
||||||
VITE_API_URL: '${VITE_API_URL}',
|
|
||||||
VITE_APP_TITLE: '${VITE_APP_TITLE}',
|
|
||||||
VITE_APP_VERSION: '${VITE_APP_VERSION}'
|
|
||||||
};
|
|
||||||
EOL
|
|
||||||
|
|
||||||
echo "Runtime configuration created with API URL: ${VITE_API_URL}"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Make the script executable
|
# Make the script executable
|
||||||
RUN chmod +x /docker-entrypoint.d/30-substitute-env.sh
|
RUN chmod +x /docker-entrypoint.d/30-substitute-env.sh
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class ApiClient {
|
|||||||
config: AxiosRequestConfig;
|
config: AxiosRequestConfig;
|
||||||
}> = [];
|
}> = [];
|
||||||
|
|
||||||
constructor(baseURL: string = getApiUrl() + '/api/v1') {
|
constructor(baseURL: string = getApiUrl() + '/v1') {
|
||||||
this.baseURL = baseURL;
|
this.baseURL = baseURL;
|
||||||
|
|
||||||
this.client = axios.create({
|
this.client = axios.create({
|
||||||
|
|||||||
26
frontend/substitute-env.sh
Normal file
26
frontend/substitute-env.sh
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Handle VITE_API_URL specially to preserve empty values
|
||||||
|
# If VITE_API_URL is unset, use default; if empty, preserve empty; otherwise use value
|
||||||
|
if [ -z "${VITE_API_URL+x}" ]; then
|
||||||
|
export VITE_API_URL="/api"
|
||||||
|
elif [ -z "$VITE_API_URL" ]; then
|
||||||
|
# If VITE_API_URL is explicitly set to empty string, use relative API path
|
||||||
|
export VITE_API_URL="/api"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Default values for other environment variables
|
||||||
|
export VITE_APP_TITLE=${VITE_APP_TITLE:-"PanIA Dashboard"}
|
||||||
|
export VITE_APP_VERSION=${VITE_APP_VERSION:-"1.0.0"}
|
||||||
|
|
||||||
|
# Create a runtime configuration file that can be loaded by the frontend
|
||||||
|
cat > /usr/share/nginx/html/runtime-config.js << EOL
|
||||||
|
window.__RUNTIME_CONFIG__ = {
|
||||||
|
VITE_API_URL: '${VITE_API_URL}',
|
||||||
|
VITE_APP_TITLE: '${VITE_APP_TITLE}',
|
||||||
|
VITE_APP_VERSION: '${VITE_APP_VERSION}'
|
||||||
|
};
|
||||||
|
EOL
|
||||||
|
|
||||||
|
echo "Runtime configuration created with API URL: ${VITE_API_URL}"
|
||||||
@@ -19,9 +19,33 @@ spec:
|
|||||||
app.kubernetes.io/name: alert-processor-service
|
app.kubernetes.io/name: alert-processor-service
|
||||||
app.kubernetes.io/component: worker
|
app.kubernetes.io/component: worker
|
||||||
spec:
|
spec:
|
||||||
|
initContainers:
|
||||||
|
- name: wait-for-rabbitmq
|
||||||
|
image: busybox:1.36
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
echo "Waiting for RabbitMQ to be ready..."
|
||||||
|
until nc -z $RABBITMQ_HOST $RABBITMQ_PORT; do
|
||||||
|
echo "RabbitMQ not ready yet, waiting..."
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
echo "RabbitMQ is ready!"
|
||||||
|
env:
|
||||||
|
- name: RABBITMQ_HOST
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: bakery-config
|
||||||
|
key: RABBITMQ_HOST
|
||||||
|
- name: RABBITMQ_PORT
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: bakery-config
|
||||||
|
key: RABBITMQ_PORT
|
||||||
containers:
|
containers:
|
||||||
- name: alert-processor-service
|
- name: alert-processor-service
|
||||||
image: bakery/alert-processor:latest
|
image: bakery/alert-processor:f246381-dirty
|
||||||
env:
|
env:
|
||||||
- name: ENVIRONMENT
|
- name: ENVIRONMENT
|
||||||
valueFrom:
|
valueFrom:
|
||||||
@@ -110,8 +134,28 @@ spec:
|
|||||||
key: NOTIFICATION_SERVICE_URL
|
key: NOTIFICATION_SERVICE_URL
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
memory: "256Mi"
|
memory: "128Mi"
|
||||||
cpu: "100m"
|
cpu: "50m"
|
||||||
limits:
|
limits:
|
||||||
memory: "512Mi"
|
memory: "256Mi"
|
||||||
cpu: "500m"
|
cpu: "200m"
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- python
|
||||||
|
- -c
|
||||||
|
- "import sys; sys.exit(0)"
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
livenessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- python
|
||||||
|
- -c
|
||||||
|
- "import sys; sys.exit(0)"
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
@@ -8,10 +8,8 @@ metadata:
|
|||||||
app.kubernetes.io/component: ingress
|
app.kubernetes.io/component: ingress
|
||||||
annotations:
|
annotations:
|
||||||
# Kind-specific nginx ingress controller annotations
|
# Kind-specific nginx ingress controller annotations
|
||||||
nginx.ingress.kubernetes.io/rewrite-target: /
|
|
||||||
nginx.ingress.kubernetes.io/ssl-redirect: "false"
|
nginx.ingress.kubernetes.io/ssl-redirect: "false"
|
||||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
|
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
|
||||||
nginx.ingress.kubernetes.io/use-regex: "true"
|
|
||||||
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
|
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
|
||||||
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
|
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
|
||||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
|
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
|
||||||
@@ -76,3 +74,20 @@ spec:
|
|||||||
name: prometheus-service
|
name: prometheus-service
|
||||||
port:
|
port:
|
||||||
number: 9090
|
number: 9090
|
||||||
|
- host: localhost
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: frontend-service
|
||||||
|
port:
|
||||||
|
number: 3000
|
||||||
|
- path: /api
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: gateway-service
|
||||||
|
port:
|
||||||
|
number: 8000
|
||||||
26
kind-config.yaml
Normal file
26
kind-config.yaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
kind: Cluster
|
||||||
|
apiVersion: kind.x-k8s.io/v1alpha4
|
||||||
|
name: bakery-ia-local
|
||||||
|
nodes:
|
||||||
|
- role: control-plane
|
||||||
|
image: kindest/node:v1.29.0
|
||||||
|
kubeadmConfigPatches:
|
||||||
|
- |
|
||||||
|
kind: InitConfiguration
|
||||||
|
nodeRegistration:
|
||||||
|
kubeletExtraArgs:
|
||||||
|
node-labels: "ingress-ready=true"
|
||||||
|
extraPortMappings:
|
||||||
|
- containerPort: 80
|
||||||
|
hostPort: 80
|
||||||
|
protocol: TCP
|
||||||
|
- containerPort: 443
|
||||||
|
hostPort: 443
|
||||||
|
protocol: TCP
|
||||||
|
- containerPort: 30080
|
||||||
|
hostPort: 30080
|
||||||
|
protocol: TCP
|
||||||
|
- role: worker
|
||||||
|
image: kindest/node:v1.29.0
|
||||||
|
- role: worker
|
||||||
|
image: kindest/node:v1.29.0
|
||||||
@@ -761,8 +761,8 @@ class InventoryService:
|
|||||||
if ingredient_data.reorder_point <= ingredient_data.low_stock_threshold:
|
if ingredient_data.reorder_point <= ingredient_data.low_stock_threshold:
|
||||||
raise ValueError("Reorder point must be greater than low stock threshold")
|
raise ValueError("Reorder point must be greater than low stock threshold")
|
||||||
|
|
||||||
if ingredient_data.requires_freezing and ingredient_data.requires_refrigeration:
|
# Storage requirements validation moved to stock level (not ingredient level)
|
||||||
raise ValueError("Item cannot require both freezing and refrigeration")
|
# This is now handled in stock creation/update validation
|
||||||
|
|
||||||
# Add more validations as needed
|
# Add more validations as needed
|
||||||
pass
|
pass
|
||||||
@@ -55,7 +55,7 @@ class BaseServiceSettings(BaseSettings):
|
|||||||
# REDIS CONFIGURATION
|
# REDIS CONFIGURATION
|
||||||
# ================================================================
|
# ================================================================
|
||||||
|
|
||||||
REDIS_URL: str = os.getenv("REDIS_URL", "redis://redis:6379")
|
REDIS_URL: str = os.getenv("REDIS_URL", "redis://redis-service:6379")
|
||||||
REDIS_DB: int = int(os.getenv("REDIS_DB", "0"))
|
REDIS_DB: int = int(os.getenv("REDIS_DB", "0"))
|
||||||
REDIS_MAX_CONNECTIONS: int = int(os.getenv("REDIS_MAX_CONNECTIONS", "50"))
|
REDIS_MAX_CONNECTIONS: int = int(os.getenv("REDIS_MAX_CONNECTIONS", "50"))
|
||||||
REDIS_RETRY_ON_TIMEOUT: bool = True
|
REDIS_RETRY_ON_TIMEOUT: bool = True
|
||||||
|
|||||||
147
skaffold.yaml
Normal file
147
skaffold.yaml
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
apiVersion: skaffold/v2beta28
|
||||||
|
kind: Config
|
||||||
|
metadata:
|
||||||
|
name: bakery-ia-local
|
||||||
|
|
||||||
|
build:
|
||||||
|
local:
|
||||||
|
push: false
|
||||||
|
artifacts:
|
||||||
|
# Gateway
|
||||||
|
- image: bakery/gateway
|
||||||
|
context: .
|
||||||
|
docker:
|
||||||
|
dockerfile: gateway/Dockerfile
|
||||||
|
|
||||||
|
# Frontend
|
||||||
|
- image: bakery/dashboard
|
||||||
|
context: ./frontend
|
||||||
|
docker:
|
||||||
|
dockerfile: Dockerfile.kubernetes
|
||||||
|
|
||||||
|
# Microservices
|
||||||
|
- image: bakery/auth-service
|
||||||
|
context: .
|
||||||
|
docker:
|
||||||
|
dockerfile: services/auth/Dockerfile
|
||||||
|
|
||||||
|
- image: bakery/tenant-service
|
||||||
|
context: .
|
||||||
|
docker:
|
||||||
|
dockerfile: services/tenant/Dockerfile
|
||||||
|
|
||||||
|
- image: bakery/training-service
|
||||||
|
context: .
|
||||||
|
docker:
|
||||||
|
dockerfile: services/training/Dockerfile
|
||||||
|
|
||||||
|
- image: bakery/forecasting-service
|
||||||
|
context: .
|
||||||
|
docker:
|
||||||
|
dockerfile: services/forecasting/Dockerfile
|
||||||
|
|
||||||
|
- image: bakery/sales-service
|
||||||
|
context: .
|
||||||
|
docker:
|
||||||
|
dockerfile: services/sales/Dockerfile
|
||||||
|
|
||||||
|
- image: bakery/external-service
|
||||||
|
context: .
|
||||||
|
docker:
|
||||||
|
dockerfile: services/external/Dockerfile
|
||||||
|
|
||||||
|
- image: bakery/notification-service
|
||||||
|
context: .
|
||||||
|
docker:
|
||||||
|
dockerfile: services/notification/Dockerfile
|
||||||
|
|
||||||
|
- image: bakery/inventory-service
|
||||||
|
context: .
|
||||||
|
docker:
|
||||||
|
dockerfile: services/inventory/Dockerfile
|
||||||
|
|
||||||
|
- image: bakery/recipes-service
|
||||||
|
context: .
|
||||||
|
docker:
|
||||||
|
dockerfile: services/recipes/Dockerfile
|
||||||
|
|
||||||
|
- image: bakery/suppliers-service
|
||||||
|
context: .
|
||||||
|
docker:
|
||||||
|
dockerfile: services/suppliers/Dockerfile
|
||||||
|
|
||||||
|
- image: bakery/pos-service
|
||||||
|
context: .
|
||||||
|
docker:
|
||||||
|
dockerfile: services/pos/Dockerfile
|
||||||
|
|
||||||
|
- image: bakery/orders-service
|
||||||
|
context: .
|
||||||
|
docker:
|
||||||
|
dockerfile: services/orders/Dockerfile
|
||||||
|
|
||||||
|
- image: bakery/production-service
|
||||||
|
context: .
|
||||||
|
docker:
|
||||||
|
dockerfile: services/production/Dockerfile
|
||||||
|
|
||||||
|
- image: bakery/alert-processor
|
||||||
|
context: .
|
||||||
|
docker:
|
||||||
|
dockerfile: services/alert_processor/Dockerfile
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
kustomize:
|
||||||
|
paths:
|
||||||
|
- infrastructure/kubernetes/overlays/dev
|
||||||
|
|
||||||
|
portForward:
|
||||||
|
- resourceType: service
|
||||||
|
resourceName: frontend-service
|
||||||
|
namespace: bakery-ia
|
||||||
|
port: 3000
|
||||||
|
localPort: 3000
|
||||||
|
- resourceType: service
|
||||||
|
resourceName: gateway-service
|
||||||
|
namespace: bakery-ia
|
||||||
|
port: 8000
|
||||||
|
localPort: 8000
|
||||||
|
|
||||||
|
profiles:
|
||||||
|
- name: dev
|
||||||
|
build:
|
||||||
|
local:
|
||||||
|
push: false
|
||||||
|
tagPolicy:
|
||||||
|
gitCommit: {}
|
||||||
|
deploy:
|
||||||
|
kustomize:
|
||||||
|
paths:
|
||||||
|
- infrastructure/kubernetes/overlays/dev
|
||||||
|
|
||||||
|
- name: debug
|
||||||
|
build:
|
||||||
|
local:
|
||||||
|
push: false
|
||||||
|
tagPolicy:
|
||||||
|
sha256: {}
|
||||||
|
deploy:
|
||||||
|
kustomize:
|
||||||
|
paths:
|
||||||
|
- infrastructure/kubernetes/overlays/dev
|
||||||
|
portForward:
|
||||||
|
- resourceType: service
|
||||||
|
resourceName: frontend-service
|
||||||
|
namespace: bakery-ia
|
||||||
|
port: 3000
|
||||||
|
localPort: 3000
|
||||||
|
- resourceType: service
|
||||||
|
resourceName: gateway-service
|
||||||
|
namespace: bakery-ia
|
||||||
|
port: 8000
|
||||||
|
localPort: 8000
|
||||||
|
- resourceType: service
|
||||||
|
resourceName: auth-service
|
||||||
|
namespace: bakery-ia
|
||||||
|
port: 8000
|
||||||
|
localPort: 8001
|
||||||
Reference in New Issue
Block a user