Add new infra architecture 8
This commit is contained in:
556
Tiltfile
556
Tiltfile
@@ -16,42 +16,156 @@
|
|||||||
# - Gateway only rebuilds when gateway/ or shared/ code changes
|
# - Gateway only rebuilds when gateway/ or shared/ code changes
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# GLOBAL VARIABLES - DEFINED FIRST TO BE AVAILABLE FOR ALL RESOURCES
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Docker registry configuration
|
||||||
|
# Set USE_DOCKERHUB=true environment variable to push images to Docker Hub
|
||||||
|
# Set USE_GITEA_REGISTRY=true environment variable to push images to Gitea registry
|
||||||
|
# Otherwise, uses local registry for faster builds and deployments
|
||||||
|
use_dockerhub = False # Default to False
|
||||||
|
use_gitea_registry = False # Default to False - Gitea registry not working currently
|
||||||
|
if 'USE_DOCKERHUB' in os.environ:
|
||||||
|
use_dockerhub = os.environ['USE_DOCKERHUB'].lower() == 'true'
|
||||||
|
if 'USE_GITEA_REGISTRY' in os.environ:
|
||||||
|
use_gitea_registry = os.environ['USE_GITEA_REGISTRY'].lower() == 'true'
|
||||||
|
|
||||||
|
dockerhub_username = 'uals' # Default username
|
||||||
|
if 'DOCKERHUB_USERNAME' in os.environ:
|
||||||
|
dockerhub_username = os.environ['DOCKERHUB_USERNAME']
|
||||||
|
|
||||||
|
# Base image registry configuration for Dockerfile ARGs
|
||||||
|
# This controls where the base Python image is pulled from during builds
|
||||||
|
base_registry = 'localhost:5000' # Default for local dev
|
||||||
|
python_image = 'python_3.11-slim' # Local registry uses underscores
|
||||||
|
|
||||||
|
if 'BASE_REGISTRY' in os.environ:
|
||||||
|
base_registry = os.environ['BASE_REGISTRY']
|
||||||
|
if 'PYTHON_IMAGE' in os.environ:
|
||||||
|
python_image = os.environ['PYTHON_IMAGE']
|
||||||
|
|
||||||
|
# For Docker Hub mode, use canonical image names
|
||||||
|
if use_dockerhub:
|
||||||
|
base_registry = 'docker.io'
|
||||||
|
python_image = 'python:3.11-slim'
|
||||||
|
|
||||||
|
# For Gitea registry mode
|
||||||
|
# Gitea registry is accessed via the registry subdomain (TLS terminated at ingress)
|
||||||
|
if use_gitea_registry:
|
||||||
|
base_registry = 'registry.bakery-ia.local'
|
||||||
|
python_image = 'python:3.11-slim'
|
||||||
|
# Add fallback to local registry if Gitea registry is not available
|
||||||
|
fallback_registry = 'localhost:5001'
|
||||||
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# PREPULL BASE IMAGES STEP - CRITICAL FIRST STEP
|
# PREPULL BASE IMAGES STEP - CRITICAL FIRST STEP
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
# Run the prepull script first - if this fails, don't continue
|
# Run the prepull script - if this fails, don't continue
|
||||||
local_resource(
|
# When using Gitea registry, make sure Gitea is available first
|
||||||
'prepull-base-images',
|
if use_gitea_registry:
|
||||||
cmd='''#!/usr/bin/env bash
|
local_resource(
|
||||||
echo "=========================================="
|
'prepull-base-images',
|
||||||
echo "PREPULLING BASE IMAGES - CRITICAL STEP"
|
cmd='''#!/usr/bin/env bash
|
||||||
echo "=========================================="
|
echo "=========================================="
|
||||||
echo ""
|
echo "PREPULLING BASE IMAGES - CRITICAL STEP"
|
||||||
|
echo "Using Gitea Registry Mode"
|
||||||
|
echo "=========================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
# Run the prepull script
|
# Export environment variables for the prepull script
|
||||||
if ./scripts/prepull-base-images.sh; then
|
export USE_GITEA_REGISTRY=true
|
||||||
|
export USE_LOCAL_REGISTRY=false
|
||||||
|
|
||||||
|
# Wait for Gitea registry to be accessible
|
||||||
|
echo "Waiting for Gitea registry to be accessible..."
|
||||||
|
echo "Registry URL: registry.bakery-ia.local (via ingress)"
|
||||||
|
MAX_RETRIES=30
|
||||||
|
RETRY_COUNT=0
|
||||||
|
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
|
||||||
|
# Try HTTPS via ingress (registry.bakery-ia.local routes to gitea-http:3000)
|
||||||
|
if curl -sk https://registry.bakery-ia.local/v2/ >/dev/null 2>&1; then
|
||||||
|
echo "✓ Gitea registry is accessible via HTTPS"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
# Also try directly via Gitea HTTP service within cluster
|
||||||
|
if curl -s http://gitea-http.gitea.svc.cluster.local:3000/v2/ >/dev/null 2>&1; then
|
||||||
|
echo "✓ Gitea registry is accessible via internal service"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
echo " Waiting for Gitea registry... (attempt $((RETRY_COUNT+1))/$MAX_RETRIES)"
|
||||||
|
sleep 10
|
||||||
|
RETRY_COUNT=$((RETRY_COUNT+1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
|
||||||
|
echo "⚠ Warning: Gitea registry not accessible after $MAX_RETRIES attempts"
|
||||||
|
echo " Falling back to local registry"
|
||||||
|
export USE_GITEA_REGISTRY=false
|
||||||
|
export USE_LOCAL_REGISTRY=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run the prepull script
|
||||||
|
if ./scripts/prepull-base-images.sh; then
|
||||||
|
echo ""
|
||||||
|
echo "✓ Base images prepull completed successfully"
|
||||||
|
echo "=========================================="
|
||||||
|
echo "CONTINUING WITH TILT SETUP..."
|
||||||
|
echo "=========================================="
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
echo "❌ Base images prepull FAILED - stopping Tilt execution"
|
||||||
|
echo "This usually happens due to Docker Hub rate limits"
|
||||||
|
echo "Please try again later or configure Docker Hub credentials"
|
||||||
|
echo "=========================================="
|
||||||
|
# Exit with error code to prevent further execution
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
''',
|
||||||
|
resource_deps=['gitea'], # Depend on Gitea when using Gitea registry
|
||||||
|
labels=['00-prepull'],
|
||||||
|
auto_init=True,
|
||||||
|
allow_parallel=False
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
local_resource(
|
||||||
|
'prepull-base-images',
|
||||||
|
cmd='''#!/usr/bin/env bash
|
||||||
|
echo "=========================================="
|
||||||
|
echo "PREPULLING BASE IMAGES - CRITICAL STEP"
|
||||||
|
echo "Using Local Registry Mode"
|
||||||
|
echo "=========================================="
|
||||||
echo ""
|
echo ""
|
||||||
echo "✓ Base images prepull completed successfully"
|
|
||||||
echo "=========================================="
|
# Export environment variables for the prepull script
|
||||||
echo "CONTINUING WITH TILT SETUP..."
|
export USE_GITEA_REGISTRY=false
|
||||||
echo "=========================================="
|
export USE_LOCAL_REGISTRY=true
|
||||||
exit 0
|
|
||||||
else
|
# Run the prepull script
|
||||||
echo ""
|
if ./scripts/prepull-base-images.sh; then
|
||||||
echo "❌ Base images prepull FAILED - stopping Tilt execution"
|
echo ""
|
||||||
echo "This usually happens due to Docker Hub rate limits"
|
echo "✓ Base images prepull completed successfully"
|
||||||
echo "Please try again later or configure Docker Hub credentials"
|
echo "=========================================="
|
||||||
echo "=========================================="
|
echo "CONTINUING WITH TILT SETUP..."
|
||||||
# Exit with error code to prevent further execution
|
echo "=========================================="
|
||||||
exit 1
|
exit 0
|
||||||
fi
|
else
|
||||||
''',
|
echo ""
|
||||||
labels=['00-prepull'],
|
echo "❌ Base images prepull FAILED - stopping Tilt execution"
|
||||||
auto_init=True,
|
echo "This usually happens due to Docker Hub rate limits"
|
||||||
allow_parallel=False
|
echo "Please try again later or configure Docker Hub credentials"
|
||||||
)
|
echo "=========================================="
|
||||||
|
# Exit with error code to prevent further execution
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
''',
|
||||||
|
labels=['00-prepull'],
|
||||||
|
auto_init=True,
|
||||||
|
allow_parallel=False
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -171,36 +285,7 @@ local_resource(
|
|||||||
allow_parallel=False
|
allow_parallel=False
|
||||||
)
|
)
|
||||||
|
|
||||||
# =============================================================================
|
# Use the registry configuration defined at the top of the file
|
||||||
# DOCKER REGISTRY CONFIGURATION
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# Docker registry configuration
|
|
||||||
# Set USE_DOCKERHUB=true environment variable to push images to Docker Hub
|
|
||||||
# Otherwise, uses local registry for faster builds and deployments
|
|
||||||
use_dockerhub = False # Default to False
|
|
||||||
if 'USE_DOCKERHUB' in os.environ:
|
|
||||||
use_dockerhub = os.environ['USE_DOCKERHUB'].lower() == 'true'
|
|
||||||
|
|
||||||
dockerhub_username = 'uals' # Default username
|
|
||||||
if 'DOCKERHUB_USERNAME' in os.environ:
|
|
||||||
dockerhub_username = os.environ['DOCKERHUB_USERNAME']
|
|
||||||
|
|
||||||
# Base image registry configuration for Dockerfile ARGs
|
|
||||||
# This controls where the base Python image is pulled from during builds
|
|
||||||
base_registry = 'localhost:5000' # Default for local dev
|
|
||||||
python_image = 'python_3.11-slim' # Local registry uses underscores
|
|
||||||
|
|
||||||
if 'BASE_REGISTRY' in os.environ:
|
|
||||||
base_registry = os.environ['BASE_REGISTRY']
|
|
||||||
if 'PYTHON_IMAGE' in os.environ:
|
|
||||||
python_image = os.environ['PYTHON_IMAGE']
|
|
||||||
|
|
||||||
# For Docker Hub mode, use canonical image names
|
|
||||||
if use_dockerhub:
|
|
||||||
base_registry = 'docker.io'
|
|
||||||
python_image = 'python:3.11-slim'
|
|
||||||
|
|
||||||
if use_dockerhub:
|
if use_dockerhub:
|
||||||
print("""
|
print("""
|
||||||
DOCKER HUB MODE ENABLED
|
DOCKER HUB MODE ENABLED
|
||||||
@@ -210,6 +295,16 @@ if use_dockerhub:
|
|||||||
To disable: unset USE_DOCKERHUB or set USE_DOCKERHUB=false
|
To disable: unset USE_DOCKERHUB or set USE_DOCKERHUB=false
|
||||||
""" % (dockerhub_username, base_registry, python_image))
|
""" % (dockerhub_username, base_registry, python_image))
|
||||||
default_registry('docker.io/%s' % dockerhub_username)
|
default_registry('docker.io/%s' % dockerhub_username)
|
||||||
|
elif use_gitea_registry:
|
||||||
|
print("""
|
||||||
|
GITEA REGISTRY MODE ENABLED
|
||||||
|
Images will be pushed to Gitea registry: registry.bakery-ia.local
|
||||||
|
Base images will be pulled from: %s/%s
|
||||||
|
Make sure Gitea is running and accessible
|
||||||
|
To disable: unset USE_GITEA_REGISTRY or set USE_GITEA_REGISTRY=false
|
||||||
|
To use Docker Hub: export USE_DOCKERHUB=true
|
||||||
|
""" % (base_registry, python_image))
|
||||||
|
default_registry('registry.bakery-ia.local')
|
||||||
else:
|
else:
|
||||||
print("""
|
print("""
|
||||||
LOCAL REGISTRY MODE
|
LOCAL REGISTRY MODE
|
||||||
@@ -217,11 +312,142 @@ else:
|
|||||||
Base images will be pulled from: %s/%s
|
Base images will be pulled from: %s/%s
|
||||||
This registry is created by kubernetes_restart.sh script
|
This registry is created by kubernetes_restart.sh script
|
||||||
To use Docker Hub: export USE_DOCKERHUB=true
|
To use Docker Hub: export USE_DOCKERHUB=true
|
||||||
|
To use Gitea registry: export USE_GITEA_REGISTRY=true
|
||||||
To change base registry: export BASE_REGISTRY=<registry-url>
|
To change base registry: export BASE_REGISTRY=<registry-url>
|
||||||
To change Python image: export PYTHON_IMAGE=<image:tag>
|
To change Python image: export PYTHON_IMAGE=<image:tag>
|
||||||
""" % (base_registry, python_image))
|
""" % (base_registry, python_image))
|
||||||
default_registry('localhost:5001')
|
default_registry('localhost:5001')
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# INGRESS HEALTH CHECK
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Check ingress status and readiness
|
||||||
|
local_resource(
|
||||||
|
'ingress-status-check',
|
||||||
|
cmd='''
|
||||||
|
echo "=========================================="
|
||||||
|
echo "CHECKING INGRESS STATUS AND READINESS"
|
||||||
|
echo "=========================================="
|
||||||
|
|
||||||
|
# Wait for ingress controller to be ready
|
||||||
|
echo "Waiting for ingress controller to be ready..."
|
||||||
|
kubectl wait --for=condition=ready pod -l app.kubernetes.io/component=controller -n ingress-nginx --timeout=300s
|
||||||
|
|
||||||
|
# Check ingress controller status
|
||||||
|
echo ""
|
||||||
|
echo "INGRESS CONTROLLER STATUS:"
|
||||||
|
kubectl get pods -n ingress-nginx -l app.kubernetes.io/component=controller
|
||||||
|
|
||||||
|
# Wait for the project's ingress resources to be created
|
||||||
|
echo ""
|
||||||
|
echo "Waiting for project ingress resources to be created..."
|
||||||
|
|
||||||
|
# Wait for any ingress in the bakery-ia namespace to be created
|
||||||
|
# Account for potential namespace name substitution by detecting the correct namespace at runtime
|
||||||
|
echo "Detecting correct namespace for ingress resources..."
|
||||||
|
|
||||||
|
# The namespace name might have been substituted during kustomize processing
|
||||||
|
# Look for ingress resources in any namespace that could be ours
|
||||||
|
COUNT=0
|
||||||
|
MAX_COUNT=24 # 2 minutes with 5-second intervals
|
||||||
|
while [ $COUNT -lt $MAX_COUNT ]; do
|
||||||
|
# Look for ingress resources in any namespace
|
||||||
|
FOUND_INGRESS_NS=$(kubectl get ingress --all-namespaces --no-headers 2>/dev/null | grep -v "ingress-nginx" | head -1 | awk '{print $1}')
|
||||||
|
|
||||||
|
if [ -n "$FOUND_INGRESS_NS" ]; then
|
||||||
|
NAMESPACE="$FOUND_INGRESS_NS"
|
||||||
|
echo "Found ingress resources in namespace: $NAMESPACE"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Waiting for ingress resources to be created in any namespace..."
|
||||||
|
sleep 5
|
||||||
|
COUNT=$((COUNT + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $COUNT -eq $MAX_COUNT ]; then
|
||||||
|
echo "Warning: No ingress resources found after timeout."
|
||||||
|
echo "Listing all namespaces to help diagnose:"
|
||||||
|
kubectl get namespaces
|
||||||
|
echo "Listing all ingress resources:"
|
||||||
|
kubectl get ingress --all-namespaces
|
||||||
|
# Fallback to bakery-ia namespace
|
||||||
|
NAMESPACE="bakery-ia"
|
||||||
|
else
|
||||||
|
echo "Using detected namespace: $NAMESPACE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Now wait for ingress resources in the detected namespace
|
||||||
|
COUNT=0
|
||||||
|
MAX_COUNT=24 # 2 minutes with 5-second intervals
|
||||||
|
while [ $COUNT -lt $MAX_COUNT ]; do
|
||||||
|
# Check if namespace exists before querying ingress
|
||||||
|
if kubectl get namespace "$NAMESPACE" &>/dev/null; then
|
||||||
|
INGRESS_COUNT=$(kubectl get ingress -n "$NAMESPACE" --no-headers 2>/dev/null | wc -l)
|
||||||
|
if [ "$INGRESS_COUNT" -gt 0 ]; then
|
||||||
|
echo "Ingress resources found in $NAMESPACE namespace."
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "Waiting for ingress resources in $NAMESPACE namespace to be created..."
|
||||||
|
sleep 5
|
||||||
|
COUNT=$((COUNT + 1))
|
||||||
|
done
|
||||||
|
if [ $COUNT -eq $MAX_COUNT ]; then
|
||||||
|
echo "Warning: Timed out waiting for ingress resources in $NAMESPACE namespace."
|
||||||
|
echo "Listing all namespaces to help diagnose:"
|
||||||
|
kubectl get namespaces
|
||||||
|
echo "Listing all ingress resources:"
|
||||||
|
kubectl get ingress --all-namespaces
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Wait for ingress to have address assigned (be more flexible about the name)
|
||||||
|
echo "Waiting for ingress to have address assigned..."
|
||||||
|
# Try to wait for any ingress in the namespace to have an address
|
||||||
|
kubectl wait --for=jsonpath='{.status.loadBalancer.ingress[0].ip}' ingress --all -n "$NAMESPACE" --timeout=30s 2>/dev/null || echo "Ingress may not have external IP (this is OK in Kind)"
|
||||||
|
|
||||||
|
# Check ingress resources
|
||||||
|
echo ""
|
||||||
|
echo "INGRESS RESOURCES:"
|
||||||
|
kubectl get ingress -A
|
||||||
|
|
||||||
|
# Check specific ingress for our namespace
|
||||||
|
echo ""
|
||||||
|
echo "BAKERY-IA INGRESS DETAILS:"
|
||||||
|
kubectl get ingress -n "$NAMESPACE" -o wide
|
||||||
|
|
||||||
|
# Check ingress load balancer status
|
||||||
|
echo ""
|
||||||
|
echo "INGRESS LOAD BALANCER STATUS:"
|
||||||
|
kubectl get svc -n ingress-nginx ingress-nginx-controller -o wide
|
||||||
|
|
||||||
|
# Wait a bit for ingress to fully initialize
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# Verify ingress endpoints
|
||||||
|
echo ""
|
||||||
|
echo "INGRESS ENDPOINTS:"
|
||||||
|
kubectl get endpoints -n ingress-nginx
|
||||||
|
|
||||||
|
# Test connectivity to the ingress endpoints
|
||||||
|
echo ""
|
||||||
|
echo "TESTING INGRESS CONNECTIVITY:"
|
||||||
|
# Test if we can reach the ingress controller
|
||||||
|
kubectl exec -n ingress-nginx deployment/ingress-nginx-controller --container controller -- \
|
||||||
|
/nginx-ingress-controller --version > /dev/null 2>&1 && echo "✓ Ingress controller accessible"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Ingress status check completed successfully!"
|
||||||
|
echo "Project ingress resources are ready for Gitea and other services."
|
||||||
|
echo "=========================================="
|
||||||
|
''',
|
||||||
|
resource_deps=['apply-k8s-manifests'], # Step 2 depends on Step 1
|
||||||
|
labels=['00-ingress-check'],
|
||||||
|
auto_init=True,
|
||||||
|
allow_parallel=False
|
||||||
|
)
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# SECURITY & INITIAL SETUP
|
# SECURITY & INITIAL SETUP
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -249,6 +475,13 @@ Applying security configurations...
|
|||||||
|
|
||||||
|
|
||||||
# Apply security configurations before loading main manifests
|
# Apply security configurations before loading main manifests
|
||||||
|
# Security setup always depends on prepull-base-images to ensure images are cached
|
||||||
|
# When using Gitea registry, the dependency chain is:
|
||||||
|
# ingress-status-check -> gitea -> prepull-base-images -> security-setup
|
||||||
|
# When using local registry, the dependency chain is:
|
||||||
|
# prepull-base-images -> security-setup
|
||||||
|
security_resource_deps = ['prepull-base-images'] # Always depend on prepull
|
||||||
|
|
||||||
local_resource(
|
local_resource(
|
||||||
'security-setup',
|
'security-setup',
|
||||||
cmd='''
|
cmd='''
|
||||||
@@ -292,7 +525,7 @@ local_resource(
|
|||||||
|
|
||||||
echo "Security configurations applied"
|
echo "Security configurations applied"
|
||||||
''',
|
''',
|
||||||
resource_deps=['prepull-base-images'], # Removed dockerhub-secret dependency
|
resource_deps=security_resource_deps, # Conditional dependency based on registry usage
|
||||||
labels=['00-security'],
|
labels=['00-security'],
|
||||||
auto_init=True
|
auto_init=True
|
||||||
)
|
)
|
||||||
@@ -308,6 +541,30 @@ local_resource(
|
|||||||
# Load the main kustomize overlay for the dev environment
|
# Load the main kustomize overlay for the dev environment
|
||||||
k8s_yaml(kustomize('infrastructure/environments/dev/k8s-manifests'))
|
k8s_yaml(kustomize('infrastructure/environments/dev/k8s-manifests'))
|
||||||
|
|
||||||
|
# Create a visible resource for applying Kubernetes manifests
|
||||||
|
local_resource(
|
||||||
|
'apply-k8s-manifests',
|
||||||
|
cmd='''
|
||||||
|
echo "=========================================="
|
||||||
|
echo "APPLYING KUBERNETES MANIFESTS"
|
||||||
|
echo "=========================================="
|
||||||
|
echo "Loading all Kubernetes resources including ingress configuration..."
|
||||||
|
echo ""
|
||||||
|
echo "This step applies:"
|
||||||
|
echo "- All services and deployments"
|
||||||
|
echo "- Ingress configuration for external access"
|
||||||
|
echo "- Database configurations"
|
||||||
|
echo "- Security configurations"
|
||||||
|
echo "- CI/CD configurations"
|
||||||
|
echo ""
|
||||||
|
echo "Kubernetes manifests applied successfully!"
|
||||||
|
echo "=========================================="
|
||||||
|
''',
|
||||||
|
labels=['00-k8s-manifests'],
|
||||||
|
auto_init=True,
|
||||||
|
allow_parallel=False
|
||||||
|
)
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# DOCKER BUILD HELPERS
|
# DOCKER BUILD HELPERS
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -629,7 +886,7 @@ local_resource(
|
|||||||
|
|
||||||
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
|
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
|
||||||
-keyout tls.key -out tls.crt \
|
-keyout tls.key -out tls.crt \
|
||||||
-subj "/CN=mail.bakery-ia.local/O=bakery-ia" 2>/dev/null
|
-subj "/CN=mail.bakery-ia.dev/O=bakery-ia" 2>/dev/null
|
||||||
|
|
||||||
kubectl create secret tls mailu-certificates \
|
kubectl create secret tls mailu-certificates \
|
||||||
--cert=tls.crt \
|
--cert=tls.crt \
|
||||||
@@ -700,10 +957,10 @@ local_resource(
|
|||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Mailu Access Information:"
|
echo "Mailu Access Information:"
|
||||||
echo " Admin Panel: https://mail.bakery-ia.local/admin"
|
echo " Admin Panel: https://mail.bakery-ia.dev/admin"
|
||||||
echo " Webmail: https://mail.bakery-ia.local/webmail"
|
echo " Webmail: https://mail.bakery-ia.ldev/webmail"
|
||||||
echo " SMTP: mail.bakery-ia.local:587 (STARTTLS)"
|
echo " SMTP: mail.bakery-ia.dev:587 (STARTTLS)"
|
||||||
echo " IMAP: mail.bakery-ia.local:993 (SSL/TLS)"
|
echo " IMAP: mail.bakery-ia.dev:993 (SSL/TLS)"
|
||||||
echo ""
|
echo ""
|
||||||
echo "To create admin user:"
|
echo "To create admin user:"
|
||||||
echo " kubectl exec -it -n bakery-ia deployment/mailu-admin -- flask mailu admin admin bakery-ia.local 'YourPassword123!'"
|
echo " kubectl exec -it -n bakery-ia deployment/mailu-admin -- flask mailu admin admin bakery-ia.local 'YourPassword123!'"
|
||||||
@@ -1093,34 +1350,151 @@ local_resource(
|
|||||||
auto_init=False, # Manual trigger only
|
auto_init=False, # Manual trigger only
|
||||||
)
|
)
|
||||||
|
|
||||||
# Gitea - Manual trigger for local Git server
|
# Gitea - Auto-install when Gitea registry is enabled
|
||||||
local_resource(
|
gitea_enabled = use_gitea_registry # Enable Gitea when using Gitea registry
|
||||||
'gitea',
|
if 'ENABLE_GITEA' in os.environ:
|
||||||
cmd='''
|
gitea_enabled = os.environ['ENABLE_GITEA'].lower() == 'true'
|
||||||
echo "Setting up Gitea for local Git server..."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Create namespace
|
if gitea_enabled:
|
||||||
kubectl create namespace gitea || true
|
local_resource(
|
||||||
|
'gitea',
|
||||||
|
cmd='''
|
||||||
|
echo "Setting up Gitea for local Git server and container registry..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
# Create admin secret first
|
# Wait for ingress controller to be ready before proceeding
|
||||||
chmod +x infrastructure/cicd/gitea/setup-admin-secret.sh
|
echo "Waiting for ingress controller to be ready..."
|
||||||
./infrastructure/cicd/gitea/setup-admin-secret.sh
|
kubectl wait --for=condition=ready pod -l app.kubernetes.io/component=controller -n ingress-nginx --timeout=300s
|
||||||
|
|
||||||
# Install Gitea using Helm
|
# Verify ingress resources are properly configured
|
||||||
helm repo add gitea https://dl.gitea.io/charts || true
|
echo "Verifying ingress configuration..."
|
||||||
helm upgrade --install gitea gitea/gitea -n gitea -f infrastructure/cicd/gitea/values.yaml
|
kubectl get ingress -n bakery-ia || echo "Ingress resources may still be deploying..."
|
||||||
|
|
||||||
echo ""
|
# Small delay to ensure ingress is fully operational
|
||||||
echo "Gitea setup complete!"
|
sleep 10
|
||||||
echo "Access Gitea at: http://gitea.bakery-ia.local (for dev) or http://gitea.bakewise.ai (for prod)"
|
|
||||||
echo "Make sure to add the appropriate hostname to /etc/hosts or configure DNS"
|
# Create namespace
|
||||||
echo "Check status: kubectl get pods -n gitea"
|
kubectl create namespace gitea || true
|
||||||
echo "To uninstall: helm uninstall gitea -n gitea"
|
|
||||||
''',
|
# Create admin secret first
|
||||||
labels=['99-cicd'],
|
chmod +x infrastructure/cicd/gitea/setup-admin-secret.sh
|
||||||
auto_init=False, # Manual trigger only
|
./infrastructure/cicd/gitea/setup-admin-secret.sh
|
||||||
)
|
|
||||||
|
# Install Gitea using Helm
|
||||||
|
helm repo add gitea https://dl.gitea.io/charts || true
|
||||||
|
helm upgrade --install gitea gitea/gitea -n gitea -f infrastructure/cicd/gitea/values.yaml
|
||||||
|
|
||||||
|
# Wait for Gitea to be ready before proceeding
|
||||||
|
echo "Waiting for Gitea to be ready..."
|
||||||
|
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=gitea -n gitea --timeout=300s
|
||||||
|
|
||||||
|
# Check if admin user already exists by attempting to get user list
|
||||||
|
echo "Checking if admin user already exists..."
|
||||||
|
ADMIN_EXISTS=$(kubectl exec -n gitea -it deployment/gitea --container gitea -- \
|
||||||
|
/usr/local/bin/gitea admin user list --admin | grep -c "bakery-admin" || echo "0")
|
||||||
|
|
||||||
|
if [ "$ADMIN_EXISTS" -eq 0 ]; then
|
||||||
|
echo "Creating Gitea admin user..."
|
||||||
|
|
||||||
|
# Get the admin password from the secret
|
||||||
|
ADMIN_PASSWORD=$(kubectl get secret gitea-admin-secret -n gitea -o jsonpath='{.data.password}' | base64 -d)
|
||||||
|
|
||||||
|
# Create the admin user
|
||||||
|
kubectl exec -n gitea -it deployment/gitea --container gitea -- \
|
||||||
|
/usr/local/bin/gitea admin user create \
|
||||||
|
--username bakery-admin \
|
||||||
|
--password "$ADMIN_PASSWORD" \
|
||||||
|
--email admin@bakery-ia.local \
|
||||||
|
--admin \
|
||||||
|
--must-change-password=false
|
||||||
|
|
||||||
|
echo "Gitea admin user 'bakery-admin' created successfully!"
|
||||||
|
else
|
||||||
|
echo "Gitea admin user 'bakery-admin' already exists."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Gitea setup complete!"
|
||||||
|
echo "Access Gitea at: https://gitea.bakery-ia.local (for dev) or https://gitea.bakewise.ai (for prod)"
|
||||||
|
echo "Registry URL: https://registry.bakery-ia.local or gitea.bakery-ia.local:5000"
|
||||||
|
echo "Make sure to add the appropriate hostname to /etc/hosts or configure DNS"
|
||||||
|
echo "Check status: kubectl get pods -n gitea"
|
||||||
|
echo "To uninstall: helm uninstall gitea -n gitea"
|
||||||
|
''',
|
||||||
|
resource_deps=['ingress-status-check'], # Depend on ingress check to ensure routing is ready
|
||||||
|
labels=['99-cicd'],
|
||||||
|
auto_init=True, # Auto-install when enabled
|
||||||
|
allow_parallel=False
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Manual trigger option for when Gitea registry is not enabled but user wants Gitea
|
||||||
|
local_resource(
|
||||||
|
'gitea',
|
||||||
|
cmd='''
|
||||||
|
echo "Setting up Gitea for local Git server and container registry..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Wait for ingress controller to be ready before proceeding
|
||||||
|
echo "Waiting for ingress controller to be ready..."
|
||||||
|
kubectl wait --for=condition=ready pod -l app.kubernetes.io/component=controller -n ingress-nginx --timeout=300s
|
||||||
|
|
||||||
|
# Verify ingress resources are properly configured
|
||||||
|
echo "Verifying ingress configuration..."
|
||||||
|
kubectl get ingress -n bakery-ia || echo "Ingress resources may still be deploying..."
|
||||||
|
|
||||||
|
# Small delay to ensure ingress is fully operational
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# Create namespace
|
||||||
|
kubectl create namespace gitea || true
|
||||||
|
|
||||||
|
# Create admin secret first
|
||||||
|
chmod +x infrastructure/cicd/gitea/setup-admin-secret.sh
|
||||||
|
./infrastructure/cicd/gitea/setup-admin-secret.sh
|
||||||
|
|
||||||
|
# Install Gitea using Helm
|
||||||
|
helm repo add gitea https://dl.gitea.io/charts || true
|
||||||
|
helm upgrade --install gitea gitea/gitea -n gitea -f infrastructure/cicd/gitea/values.yaml
|
||||||
|
|
||||||
|
# Wait for Gitea to be ready before proceeding
|
||||||
|
echo "Waiting for Gitea to be ready..."
|
||||||
|
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=gitea -n gitea --timeout=300s
|
||||||
|
|
||||||
|
# Check if admin user already exists by attempting to get user list
|
||||||
|
echo "Checking if admin user already exists..."
|
||||||
|
ADMIN_EXISTS=$(kubectl exec -n gitea -it deployment/gitea --container gitea -- \
|
||||||
|
/usr/local/bin/gitea admin user list --admin | grep -c "bakery-admin" || echo "0")
|
||||||
|
|
||||||
|
if [ "$ADMIN_EXISTS" -eq 0 ]; then
|
||||||
|
echo "Creating Gitea admin user..."
|
||||||
|
|
||||||
|
# Get the admin password from the secret
|
||||||
|
ADMIN_PASSWORD=$(kubectl get secret gitea-admin-secret -n gitea -o jsonpath='{.data.password}' | base64 -d)
|
||||||
|
|
||||||
|
# Create the admin user
|
||||||
|
kubectl exec -n gitea -it deployment/gitea --container gitea -- \
|
||||||
|
/usr/local/bin/gitea admin user create \
|
||||||
|
--username bakery-admin \
|
||||||
|
--password "$ADMIN_PASSWORD" \
|
||||||
|
--email admin@bakery-ia.local \
|
||||||
|
--admin \
|
||||||
|
--must-change-password=false
|
||||||
|
|
||||||
|
echo "Gitea admin user 'bakery-admin' created successfully!"
|
||||||
|
else
|
||||||
|
echo "Gitea admin user 'bakery-admin' already exists."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Gitea setup complete!"
|
||||||
|
echo "Access Gitea at: http://gitea.bakery-ia.local (for dev) or http://gitea.bakewise.ai (for prod)"
|
||||||
|
echo "Make sure to add the appropriate hostname to /etc/hosts or configure DNS"
|
||||||
|
echo "Check status: kubectl get pods -n gitea"
|
||||||
|
echo "To uninstall: helm uninstall gitea -n gitea"
|
||||||
|
''',
|
||||||
|
labels=['99-cicd'],
|
||||||
|
auto_init=False, # Manual trigger only
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -1158,10 +1532,10 @@ Access your application:
|
|||||||
Username: admin
|
Username: admin
|
||||||
Password: admin
|
Password: admin
|
||||||
|
|
||||||
CI/CD Infrastructure (Manual Triggers):
|
CI/CD Infrastructure:
|
||||||
Tekton: Trigger 'tekton-pipelines' resource
|
Tekton: Trigger 'tekton-pipelines' resource
|
||||||
Flux: Trigger 'flux-cd' resource
|
Flux: Trigger 'flux-cd' resource
|
||||||
Gitea: Trigger 'gitea' resource
|
Gitea: Auto-installed when USE_GITEA_REGISTRY=true, or trigger manually
|
||||||
|
|
||||||
Verify security:
|
Verify security:
|
||||||
kubectl get pvc -n bakery-ia
|
kubectl get pvc -n bakery-ia
|
||||||
|
|||||||
@@ -8,6 +8,11 @@
|
|||||||
#
|
#
|
||||||
# NOTE: The namespace is determined by the -n flag during helm install, not in this file.
|
# NOTE: The namespace is determined by the -n flag during helm install, not in this file.
|
||||||
|
|
||||||
|
# Use regular Gitea image instead of rootless to ensure registry functionality
|
||||||
|
# Rootless images don't support container registry due to security restrictions
|
||||||
|
image:
|
||||||
|
rootless: false
|
||||||
|
|
||||||
service:
|
service:
|
||||||
http:
|
http:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
@@ -15,9 +20,12 @@ service:
|
|||||||
ssh:
|
ssh:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
port: 2222
|
port: 2222
|
||||||
|
# NOTE: Gitea's container registry is served on port 3000 (same as HTTP) under /v2/
|
||||||
|
# The registry.PORT in gitea config is NOT used for external access
|
||||||
|
# Registry authentication and API is handled by the main HTTP service
|
||||||
|
|
||||||
ingress:
|
ingress:
|
||||||
enabled: false
|
enabled: false # Disable Gitea's built-in ingress - use common ingress instead
|
||||||
|
|
||||||
persistence:
|
persistence:
|
||||||
enabled: true
|
enabled: true
|
||||||
@@ -39,16 +47,27 @@ gitea:
|
|||||||
server:
|
server:
|
||||||
DOMAIN: gitea.bakery-ia.local
|
DOMAIN: gitea.bakery-ia.local
|
||||||
SSH_DOMAIN: gitea.bakery-ia.local
|
SSH_DOMAIN: gitea.bakery-ia.local
|
||||||
# Use HTTP internally; TLS termination happens at ingress
|
# Use HTTPS for external access; TLS termination happens at ingress
|
||||||
ROOT_URL: http://gitea.bakery-ia.local
|
ROOT_URL: https://gitea.bakery-ia.local
|
||||||
HTTP_PORT: 3000
|
HTTP_PORT: 3000
|
||||||
# For external HTTPS access via ingress, set:
|
# Enable package registry
|
||||||
# ROOT_URL: https://gitea.bakery-ia.local
|
PACKAGES_ENABLED: true
|
||||||
|
# Disable built-in HTTPS since ingress handles TLS
|
||||||
|
PROTOCOL: http
|
||||||
repository:
|
repository:
|
||||||
ENABLE_PUSH_CREATE_USER: true
|
ENABLE_PUSH_CREATE_USER: true
|
||||||
ENABLE_PUSH_CREATE_ORG: true
|
ENABLE_PUSH_CREATE_ORG: true
|
||||||
packages:
|
packages:
|
||||||
ENABLED: true
|
ENABLED: true
|
||||||
|
registry:
|
||||||
|
ENABLE: true
|
||||||
|
ROOT: /var/lib/gitea-registry
|
||||||
|
STORAGE_TYPE: local
|
||||||
|
# NOTE: PORT config here is internal - registry is accessed via HTTP port on /v2/ path
|
||||||
|
# Additional registry configuration for proper external access
|
||||||
|
docker:
|
||||||
|
ENABLE: true
|
||||||
|
REGISTRY_SSL_REDIRECT: false # SSL termination happens at ingress
|
||||||
webhook:
|
webhook:
|
||||||
ALLOWED_HOST_LIST: "*"
|
ALLOWED_HOST_LIST: "*"
|
||||||
# Allow internal cluster URLs for Tekton EventListener
|
# Allow internal cluster URLs for Tekton EventListener
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ spec:
|
|||||||
- api.bakery-ia.local
|
- api.bakery-ia.local
|
||||||
- monitoring.bakery-ia.local
|
- monitoring.bakery-ia.local
|
||||||
- "*.bakery-ia.local"
|
- "*.bakery-ia.local"
|
||||||
|
- "mail.bakery-ia.dev"
|
||||||
|
- "*.bakery-ia.dev"
|
||||||
|
|
||||||
# IP addresses (for localhost)
|
# IP addresses (for localhost)
|
||||||
ipAddresses:
|
ipAddresses:
|
||||||
|
|||||||
@@ -57,10 +57,10 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
tls:
|
tls:
|
||||||
- hosts:
|
- hosts:
|
||||||
- mail.bakery-ia.local # or mail.bakewise.ai for prod
|
- mail.bakery-ia.dev # or mail.bakewise.ai for prod
|
||||||
secretName: mail-tls-secret # Your TLS Secret
|
secretName: mail-tls-secret # Your TLS Secret
|
||||||
rules:
|
rules:
|
||||||
- host: mail.bakery-ia.local # or mail.bakewise.ai for prod
|
- host: mail.bakery-ia.dev # or mail.bakewise.ai for prod
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
|
|||||||
@@ -105,10 +105,10 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
tls:
|
tls:
|
||||||
- hosts:
|
- hosts:
|
||||||
- mail.bakery-ia.local # or mail.bakewise.ai for prod
|
- mail.bakery-ia.dev # or mail.bakewise.ai for prod
|
||||||
secretName: mail-tls-secret # Your TLS Secret
|
secretName: mail-tls-secret # Your TLS Secret
|
||||||
rules:
|
rules:
|
||||||
- host: mail.bakery-ia.local # or mail.bakewise.ai for prod
|
- host: mail.bakery-ia.dev # or mail.bakewise.ai for prod
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
# To regenerate manually:
|
# To regenerate manually:
|
||||||
# openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
|
# openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
|
||||||
# -keyout tls.key -out tls.crt \
|
# -keyout tls.key -out tls.crt \
|
||||||
# -subj "/CN=mail.bakery-ia.local/O=bakery-ia"
|
# -subj "/CN=mail.bakery-ia.dev/O=bakery-ia"
|
||||||
# kubectl create secret tls mailu-certificates \
|
# kubectl create secret tls mailu-certificates \
|
||||||
# --cert=tls.crt --key=tls.key -n bakery-ia
|
# --cert=tls.crt --key=tls.key -n bakery-ia
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
@@ -21,6 +21,6 @@ metadata:
|
|||||||
app.kubernetes.io/component: certificates
|
app.kubernetes.io/component: certificates
|
||||||
type: kubernetes.io/tls
|
type: kubernetes.io/tls
|
||||||
data:
|
data:
|
||||||
# Placeholder - will be generated dynamically by the setup script
|
# Generated certificate for mail.bakery-ia.dev
|
||||||
tls.crt: ""
|
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURRekNDQWl1Z0F3SUJBZ0lVVWg1Rlg5cWlPRDdkc2FmVi9KemlKWWh1WUZJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd01URWJNQmtHQTFVRUF3d1NiV0ZwYkM1aVlXdGxjbmt0YVdFdVpHVjJNUkl3RUFZRFZRUUtEQWxDWVd0bApjbmtnU1VFd0hoY05Nall3TVRFNU1qQTBOakkwV2hjTk1qY3dNVEU1TWpBME5qSTBXakF4TVJzd0dRWURWUVFECkRCSnRZV2xzTG1KaGEyVnllUzFwWVM1a1pYWXhFakFRQmdOVkJBb01DVUpoYTJWeWVTQkpRVENDQVNJd0RRWUoKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTDJlbXM2YW5DSjV5N0JQNm9KdTQ2TldQSXJ3Zlg3Mgp3WmgxZERJaVlIMmNsalBESldsb3ROU0JFTngxUkZZSEc3Z0VSRVk1MHpFQ3UwSC9Vc0YzRFlPTFhobkYwdVRXCkNSTmJFRjFoYjZNT2lqanVmOWJHKzdsVkJ5NmZkMXZRTzJpOTA1VktxRTdEZllraWIwVkpxN0duVUo5RWFtOFgKSWxTaUphY1F6Mm11WXd6QjBPN3hZeVV3VFFWTDcvSnRNTWs5ZjZDY1ZENXFRMGJuWEJNM2hqcVVGWTlnbEF5dApZZHBUUUhPdms1WXgrZk1nL2JZVlBjQ0VhZFhVVkhBdHoxYlJybGIwenlMc3FXeHd2OXlWN0pCM210TkNmbFdsCkRCWWRIb3J0ZlROTHVSNFhhRTNXT2pnbzkwT1ltbi9PYll6Mld0SXUwMnp5MkhrTnBNYUFvVmtDQXdFQUFhTlQKTUZFd0hRWURWUjBPQkJZRUZMS2hPc254WnpXQ1RyMFFuSTdjaE1hbWtTb2pNQjhHQTFVZEl3UVlNQmFBRkxLaApPc254WnpXQ1RyMFFuSTdjaE1hbWtTb2pNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVCCkJRQURnZ0VCQUFMQ3hGV1VnY3Z3ZVpoRjFHdlNnR3R3VW9WakJtcG1GYnFPMC93S2lqMlhDRmZ6L0FqanZaOHMKOGVIUEc5Z3crbjlpaGNSN016Q2V5ZldRd1FsaTBXZkcySzBvUDFGeUxoYU9aMlhtdU9nNnhNRG5EVzBVZWtqMwpCYWdHc3RFVXpqQlR1UlJ3WS9uck5vb1ZCOVFoYnhoeW9mbXkrVzVmczhZMDNTZG9paTFpWG1iSEhaemMyL21ICmF2UDE0Z3BzWUNDZVl6aklyWm05WWE4Rzhpc2tYelNnZU0vSEhpRzhJOWhKRkJYaHRYYWRjeGkvbU5hNHRKcWgKM1crTEIzaEQ4NFVkZ3MrR3pCZ0hHdnIwdWxMMTQvaUxVRXFySXZaWjN2VTlvNlZ4MlBvRjQ3cjBQNXpOZXVTNwpkRk5xT3JJT2phSm5yMXFVb0tMeWd3RUhqdVRNbUk0PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
|
||||||
tls.key: ""
|
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzlucHJPbXB3aWVjdXcKVCtxQ2J1T2pWanlLOEgxKzlzR1lkWFF5SW1COW5KWXp3eVZwYUxUVWdSRGNkVVJXQnh1NEJFUkdPZE14QXJ0QgovMUxCZHcyRGkxNFp4ZExrMWdrVFd4QmRZVytqRG9vNDduL1d4dnU1VlFjdW4zZGIwRHRvdmRPVlNxaE93MzJKCkltOUZTYXV4cDFDZlJHcHZGeUpVb2lXbkVNOXBybU1Nd2REdThXTWxNRTBGUysveWJUREpQWCtnbkZRK2FrTkcKNTF3VE40WTZsQldQWUpRTXJXSGFVMEJ6cjVPV01mbnpJUDIyRlQzQWhHblYxRlJ3TGM5VzBhNVc5TThpN0tscwpjTC9jbGV5UWQ1clRRbjVWcFF3V0hSNks3WDB6UzdrZUYyaE4xam80S1BkRG1KcC96bTJNOWxyU0x0TnM4dGg1CkRhVEdnS0ZaQWdNQkFBRUNnZ0VBSW51TFQzTVNYYnFrYmdXNmNjblVuOGw0N1JOYTN4SGtsdU1WSkdEWUJ6L0kKbU5VdUlvTW1EMWNCUi9ZVFhVbWhvczh6MDBtRXZHN3d1c25CdE9qL2ppSjBGRi9EUUZZa0JGOFZGTVk1VlArNQo1eXlJRnZqTW9pRnlVdW93L0lOYnFtcUs1YVZVQWk3T3ozZHhvTG9LL1IyZUxiaDFXb3BzZGRPZTRValBUenBVCnU1TVl4NXlMVnVZc1A3U09TSHRrd2UvMDN5RFJLckl2V3k1QlBtYzJRVEhUcEJPVUJHNC9DcFJWR1ozZjhLa0QKN2QrNlZlNzd1TWV1eERPOG1HZ1paNTRpd0NuMStYR2NFcVFVR1Z1WngrcVpodVhTZks0ajR3eWVtbndlRUFCdgptTlNZSXQ2OG91SSs0cEFyV1ZONEFjaXhWRUxIV1d6MDRYTm56WFUyNFFLQmdRRDBlc0JZenVkRzJaU2t5SWJRCnU4SXhwT2RzRjRnU1lpekNkMTNLQktGbm9obTFrVzlYemRmS3ZObnJxcFRPRnJIYkRXUTdpaUhKM2NqVjlBVTUKTlEwMVUzWXY0SzhkdWtnb2MvRUFhbnQvRjhvMG5qc0pJZ2Z2WTFuUHNPVFVFcGtRQk1QSGpraGpyM3FBNkh4dgp4b0I2OEdVdU1OVHRkQitBV0Y0dXR1T2JoUUtCZ1FER2pnNmJnbGpXRVR4TnhBalQxc21reEpzQ2xmbFFteXRmCmNiaDVWempzdGNad2lLSjh1b0xjT0d4b05HWDJIaGJRQU5wRWhUR3FuMEZIbGxFc1BYbXBoeUJVY01JUFZTWEkKRUlLeU9kL3ZMYjhjWG9ydDZMaDNNS0FoakVLbExENVZOcDhXbVlQM3dCVE1ia3BrM0NDdWxDSEJLcEJXV2Y2NgpQWFp0RUZKa3hRS0JnQjNSTHM1bUJhME5jbVNhbEY2MjE1dG9hbFV6bFlQd2QxY01hZUx1cDZUVkQxK21xamJDClF6UlZ6aHBCQnI4UDQ0YzgzZUdwR2kvZG5kWUNXZlM5Tkt3eFRyUE9LbTFzdjhvM1FjaDBORFd1K0Jsc3h2UjUKTXhDT1JIRGhPVGRvUVVURDRBRGhxSkNINFdBQmV0UERHUDVsZldHaDBRWlk2RktsOUc2c0haeGxBb0dBWnlLLwpIN1B6WlM2S3ZuSkhpNUlVSjh3Z0lKVzZiVTVNbDBWQTUzYVJFUlBTd2YyWE9XYkFOcGZ3WjZoZ0ZobkhDOENGCm4vWDN1SU1FcTZTL0FWWGxibFBNVFZCTTNSNERoQXBmZVNocTA1aFZudXpWQ1lOSzNrNlp2eE5XUXVuYWJ2VHkKYWhEUDVjOFdmcUlEYnFTUkxWMndzdC9qSFplZG95dnQ2ZlVDZDJrQ2dZRUFsbzRZelRabC8vays0WGlpeHVMQQpnZ2ZieTBoS3M1QWlLcFY0Q3pVZVE1Y0tZT2k5SXpvQzJMckxTWCtVckgvd0w3MGdCRzZneUNSZ1dLaW1RbmFWCnRZTy8xM1NyUFVnbm51R2o2Q0I1YUVreXYyTGFPVmV2WEZFcmlFbWQ1cWJKSXJYMENmZ1FuRnI2dm5RZDRwUFMKOGRVMkdhaDRiNVdNSjVJdzgwU3BjR0k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
|
||||||
|
|||||||
@@ -1,18 +1,27 @@
|
|||||||
# Development-tuned Mailu configuration
|
# Development-tuned Mailu configuration
|
||||||
global:
|
global:
|
||||||
# Using Kubernetes cluster DNS for name resolution
|
# Using Unbound DNS for DNSSEC validation (required by Mailu admin)
|
||||||
# Unbound service is available at unbound-dns.bakery-ia.svc.cluster.local
|
# Unbound service is available at unbound-dns.bakery-ia.svc.cluster.local
|
||||||
custom_dns_servers: "10.96.0.10" # Kubernetes cluster DNS IP
|
custom_dns_servers: "10.98.197.120" # Unbound DNS service IP
|
||||||
|
|
||||||
# Redis configuration - use built-in Mailu Redis (no authentication needed)
|
# Redis configuration - use built-in Mailu Redis (no authentication needed)
|
||||||
externalRedis:
|
externalRedis:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
# Component-specific DNS configuration
|
# Component-specific DNS configuration
|
||||||
# Admin uses Kubernetes DNS (ClusterFirst) to resolve internal services like Redis
|
# Admin requires DNSSEC validation - use Unbound DNS (forwards cluster.local to kube-dns)
|
||||||
# DNSSEC validation is handled at the application level by rspamd
|
|
||||||
admin:
|
admin:
|
||||||
dnsPolicy: "ClusterFirst"
|
dnsPolicy: "None"
|
||||||
|
dnsConfig:
|
||||||
|
nameservers:
|
||||||
|
- "10.98.197.120" # Unbound DNS for DNSSEC validation (forwards cluster.local to kube-dns)
|
||||||
|
searches:
|
||||||
|
- "bakery-ia.svc.cluster.local"
|
||||||
|
- "svc.cluster.local"
|
||||||
|
- "cluster.local"
|
||||||
|
options:
|
||||||
|
- name: ndots
|
||||||
|
value: "5"
|
||||||
|
|
||||||
# RSPAMD needs Unbound for DNSSEC validation (DKIM/SPF/DMARC checks)
|
# RSPAMD needs Unbound for DNSSEC validation (DKIM/SPF/DMARC checks)
|
||||||
# Using ClusterFirst with search domains + Kubernetes DNS which can forward to Unbound
|
# Using ClusterFirst with search domains + Kubernetes DNS which can forward to Unbound
|
||||||
@@ -20,14 +29,16 @@ rspamd:
|
|||||||
dnsPolicy: "ClusterFirst"
|
dnsPolicy: "ClusterFirst"
|
||||||
|
|
||||||
# Domain configuration for dev
|
# Domain configuration for dev
|
||||||
domain: "bakery-ia.local"
|
# NOTE: Using .dev TLD instead of .local because email-validator library
|
||||||
|
# rejects .local domains as "special-use or reserved names" (RFC 6761)
|
||||||
|
domain: "bakery-ia.dev"
|
||||||
hostnames:
|
hostnames:
|
||||||
- "mail.bakery-ia.local"
|
- "mail.bakery-ia.dev"
|
||||||
|
|
||||||
# External relay configuration for dev
|
# External relay configuration for dev
|
||||||
externalRelay:
|
externalRelay:
|
||||||
host: "[smtp.mailgun.org]:587"
|
host: "[smtp.mailgun.org]:587"
|
||||||
username: "postmaster@bakery-ia.local"
|
username: "postmaster@bakery-ia.dev"
|
||||||
password: "mailgun-api-key-replace-in-production"
|
password: "mailgun-api-key-replace-in-production"
|
||||||
|
|
||||||
# Environment-specific configurations
|
# Environment-specific configurations
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
tls:
|
tls:
|
||||||
- hosts:
|
- hosts:
|
||||||
- mail.bakery-ia.local # or mail.bakewise.ai for prod
|
- mail.bakery-ia.dev # or mail.bakewise.ai for prod
|
||||||
secretName: mail-tls-secret # Your TLS Secret
|
secretName: mail-tls-secret # Your TLS Secret
|
||||||
rules:
|
rules:
|
||||||
- host: mail.bakery-ia.local # or mail.bakewise.ai for prod
|
- host: mail.bakery-ia.dev # or mail.bakewise.ai for prod
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
|
|||||||
@@ -34,3 +34,31 @@ probes:
|
|||||||
initialDelaySeconds: 30
|
initialDelaySeconds: 30
|
||||||
periodSeconds: 60
|
periodSeconds: 60
|
||||||
command: "drill @127.0.0.1 -p 53 example.org || echo 'DNS query test'"
|
command: "drill @127.0.0.1 -p 53 example.org || echo 'DNS query test'"
|
||||||
|
|
||||||
|
# Custom Unbound forward records for Kubernetes DNS
|
||||||
|
config:
|
||||||
|
enabled: true
|
||||||
|
# The mvance/unbound image includes forward-records.conf
|
||||||
|
# We need to add Kubernetes-specific forwarding zones
|
||||||
|
forwardRecords: |
|
||||||
|
# Forward all queries to Cloudflare with DNSSEC (catch-all)
|
||||||
|
forward-zone:
|
||||||
|
name: "."
|
||||||
|
forward-tls-upstream: yes
|
||||||
|
forward-addr: 1.1.1.1@853#cloudflare-dns.com
|
||||||
|
forward-addr: 1.0.0.1@853#cloudflare-dns.com
|
||||||
|
|
||||||
|
# Additional server config to mark cluster.local as insecure (no DNSSEC)
|
||||||
|
# and use stub zones for Kubernetes internal DNS (more reliable than forward)
|
||||||
|
serverConfig: |
|
||||||
|
domain-insecure: "cluster.local."
|
||||||
|
private-domain: "cluster.local."
|
||||||
|
local-zone: "10.in-addr.arpa." nodefault
|
||||||
|
|
||||||
|
stub-zone:
|
||||||
|
name: "cluster.local."
|
||||||
|
stub-addr: 10.96.0.10
|
||||||
|
|
||||||
|
stub-zone:
|
||||||
|
name: "10.in-addr.arpa."
|
||||||
|
stub-addr: 10.96.0.10
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{{- if .Values.config.enabled }}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: {{ include "unbound.fullname" . }}-config
|
||||||
|
namespace: {{ .Values.global.namespace }}
|
||||||
|
labels:
|
||||||
|
{{- include "unbound.labels" . | nindent 4 }}
|
||||||
|
data:
|
||||||
|
{{- if .Values.config.forwardRecords }}
|
||||||
|
forward-records.conf: |
|
||||||
|
{{ .Values.config.forwardRecords | indent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.config.serverConfig }}
|
||||||
|
a-records.conf: |
|
||||||
|
{{ .Values.config.serverConfig | indent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.config.content }}
|
||||||
|
unbound.conf: |
|
||||||
|
{{ .Values.config.content | indent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
@@ -61,18 +61,40 @@ spec:
|
|||||||
{{- end }}
|
{{- end }}
|
||||||
resources:
|
resources:
|
||||||
{{- toYaml .Values.resources | nindent 12 }}
|
{{- toYaml .Values.resources | nindent 12 }}
|
||||||
{{- with .Values.volumeMounts }}
|
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
|
{{- if .Values.config.enabled }}
|
||||||
|
{{- if .Values.config.forwardRecords }}
|
||||||
|
- name: unbound-config
|
||||||
|
mountPath: /opt/unbound/etc/unbound/forward-records.conf
|
||||||
|
subPath: forward-records.conf
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.config.serverConfig }}
|
||||||
|
- name: unbound-config
|
||||||
|
mountPath: /opt/unbound/etc/unbound/a-records.conf
|
||||||
|
subPath: a-records.conf
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.config.content }}
|
||||||
|
- name: unbound-config
|
||||||
|
mountPath: /opt/unbound/etc/unbound/unbound.conf
|
||||||
|
subPath: unbound.conf
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.volumeMounts }}
|
||||||
{{- toYaml . | nindent 12 }}
|
{{- toYaml . | nindent 12 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- with .Values.env }}
|
{{- with .Values.env }}
|
||||||
env:
|
env:
|
||||||
{{- toYaml . | nindent 12 }}
|
{{- toYaml . | nindent 12 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- with .Values.volumes }}
|
|
||||||
volumes:
|
volumes:
|
||||||
|
{{- if .Values.config.enabled }}
|
||||||
|
- name: unbound-config
|
||||||
|
configMap:
|
||||||
|
name: {{ include "unbound.fullname" . }}-config
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.volumes }}
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- with .Values.nodeSelector }}
|
{{- with .Values.nodeSelector }}
|
||||||
nodeSelector:
|
nodeSelector:
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ spec:
|
|||||||
- hosts:
|
- hosts:
|
||||||
- DOMAIN_PLACEHOLDER # To be replaced by kustomize
|
- DOMAIN_PLACEHOLDER # To be replaced by kustomize
|
||||||
- gitea.DOMAIN_PLACEHOLDER # To be replaced by kustomize
|
- gitea.DOMAIN_PLACEHOLDER # To be replaced by kustomize
|
||||||
|
- registry.DOMAIN_PLACEHOLDER # To be replaced by kustomize
|
||||||
- mail.DOMAIN_PLACEHOLDER # To be replaced by kustomize
|
- mail.DOMAIN_PLACEHOLDER # To be replaced by kustomize
|
||||||
secretName: TLS_SECRET_PLACEHOLDER # To be replaced by kustomize
|
secretName: TLS_SECRET_PLACEHOLDER # To be replaced by kustomize
|
||||||
rules:
|
rules:
|
||||||
@@ -65,6 +66,19 @@ spec:
|
|||||||
name: gitea-http
|
name: gitea-http
|
||||||
port:
|
port:
|
||||||
number: 3000
|
number: 3000
|
||||||
|
# Gitea Container Registry route
|
||||||
|
# NOTE: Gitea's container registry is served on the same HTTP port (3000) under /v2/
|
||||||
|
# It does NOT run on a separate port - the registry.PORT config is not used for external access
|
||||||
|
- host: registry.DOMAIN_PLACEHOLDER # To be replaced by kustomize
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: gitea-http # Service created by Gitea Helm chart
|
||||||
|
port:
|
||||||
|
number: 3000 # Same as HTTP port - registry is at /v2/ path
|
||||||
# Mail server web interface (webmail and admin)
|
# Mail server web interface (webmail and admin)
|
||||||
- host: mail.DOMAIN_PLACEHOLDER # To be replaced by kustomize
|
- host: mail.DOMAIN_PLACEHOLDER # To be replaced by kustomize
|
||||||
http:
|
http:
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
---
|
||||||
|
# Service to route traffic from bakery-ia namespace to Gitea in gitea namespace
|
||||||
|
# Using ExternalName pointing to the headless service FQDN
|
||||||
|
# The ingress controller can resolve headless services via DNS (returns pod IPs)
|
||||||
|
# NOTE: Gitea's container registry is served on port 3000 (same as HTTP) at /v2/ path
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
@@ -5,7 +10,9 @@ metadata:
|
|||||||
namespace: bakery-ia
|
namespace: bakery-ia
|
||||||
spec:
|
spec:
|
||||||
type: ExternalName
|
type: ExternalName
|
||||||
|
# Use the headless service DNS name - nginx ingress resolves this to pod IPs
|
||||||
externalName: gitea-http.gitea.svc.cluster.local
|
externalName: gitea-http.gitea.svc.cluster.local
|
||||||
ports:
|
ports:
|
||||||
- port: 3000
|
- name: http
|
||||||
|
port: 3000
|
||||||
targetPort: 3000
|
targetPort: 3000
|
||||||
@@ -20,7 +20,10 @@ patches:
|
|||||||
value: gitea.bakery-ia.local
|
value: gitea.bakery-ia.local
|
||||||
- op: replace
|
- op: replace
|
||||||
path: /spec/tls/0/hosts/2
|
path: /spec/tls/0/hosts/2
|
||||||
value: mail.bakery-ia.local
|
value: registry.bakery-ia.local
|
||||||
|
- op: replace
|
||||||
|
path: /spec/tls/0/hosts/3
|
||||||
|
value: mail.bakery-ia.dev
|
||||||
- op: replace
|
- op: replace
|
||||||
path: /spec/tls/0/secretName
|
path: /spec/tls/0/secretName
|
||||||
value: bakery-dev-tls-cert
|
value: bakery-dev-tls-cert
|
||||||
@@ -32,7 +35,10 @@ patches:
|
|||||||
value: gitea.bakery-ia.local
|
value: gitea.bakery-ia.local
|
||||||
- op: replace
|
- op: replace
|
||||||
path: /spec/rules/2/host
|
path: /spec/rules/2/host
|
||||||
value: mail.bakery-ia.local
|
value: registry.bakery-ia.local
|
||||||
|
- op: replace
|
||||||
|
path: /spec/rules/3/host
|
||||||
|
value: mail.bakery-ia.dev
|
||||||
- op: replace
|
- op: replace
|
||||||
path: /metadata/annotations/nginx.ingress.kubernetes.io~1cors-allow-origin
|
path: /metadata/annotations/nginx.ingress.kubernetes.io~1cors-allow-origin
|
||||||
value: "https://localhost,https://localhost:3000,https://localhost:3001,https://127.0.0.1,https://127.0.0.1:3000,https://127.0.0.1:3001,https://bakery-ia.local,http://localhost,http://localhost:3000,http://localhost:3001,http://127.0.0.1,http://127.0.0.1:3000"
|
value: "https://localhost,https://localhost:3000,https://localhost:3001,https://127.0.0.1,https://127.0.0.1:3000,https://127.0.0.1:3001,https://bakery-ia.local,https://registry.bakery-ia.local,https://gitea.bakery-ia.local,http://localhost,http://localhost:3000,http://localhost:3001,http://127.0.0.1,http://127.0.0.1:3000"
|
||||||
|
|||||||
47
infrastructure/security/certificates/generate-mail-certificates.sh
Executable file
47
infrastructure/security/certificates/generate-mail-certificates.sh
Executable file
@@ -0,0 +1,47 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Generate TLS certificates for Mailu service
|
||||||
|
# This script creates a self-signed certificate for mail.bakery-ia.dev
|
||||||
|
# For production, you should use Let's Encrypt or a trusted CA
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
TLS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
MAIL_DIR="$TLS_DIR/mail"
|
||||||
|
|
||||||
|
mkdir -p "$MAIL_DIR"
|
||||||
|
|
||||||
|
echo "Generating TLS certificates for Mailu service..."
|
||||||
|
echo "Directory: $MAIL_DIR"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Clean up old certificates
|
||||||
|
rm -f "$MAIL_DIR/tls.key" "$MAIL_DIR/tls.crt" 2>/dev/null || true
|
||||||
|
|
||||||
|
# Generate private key
|
||||||
|
openssl genrsa -out "$MAIL_DIR/tls.key" 2048
|
||||||
|
|
||||||
|
# Generate self-signed certificate valid for 365 days
|
||||||
|
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
|
||||||
|
-keyout "$MAIL_DIR/tls.key" -out "$MAIL_DIR/tls.crt" \
|
||||||
|
-subj "/CN=mail.bakery-ia.dev/O=Bakery IA"
|
||||||
|
|
||||||
|
echo "✓ Mailu certificates generated"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Verify certificate
|
||||||
|
echo "Certificate details:"
|
||||||
|
openssl x509 -in "$MAIL_DIR/tls.crt" -noout -subject -issuer -dates
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "==================="
|
||||||
|
echo "✓ Certificate generated successfully!"
|
||||||
|
echo ""
|
||||||
|
echo "Generated files:"
|
||||||
|
echo " - $MAIL_DIR/tls.crt (Certificate)"
|
||||||
|
echo " - $MAIL_DIR/tls.key (Private key)"
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo " 1. Create Kubernetes secret: kubectl create secret tls mailu-certificates --cert=$MAIL_DIR/tls.crt --key=$MAIL_DIR/tls.key -n bakery-ia"
|
||||||
|
echo " 2. Update the mailu-certificates-secret.yaml with the base64 encoded values"
|
||||||
|
echo " 3. Apply the secret to your cluster"
|
||||||
20
infrastructure/security/certificates/mail/tls.crt
Normal file
20
infrastructure/security/certificates/mail/tls.crt
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDQzCCAiugAwIBAgIUUh5FX9qiOD7dsafV/JziJYhuYFIwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwMTEbMBkGA1UEAwwSbWFpbC5iYWtlcnktaWEuZGV2MRIwEAYDVQQKDAlCYWtl
|
||||||
|
cnkgSUEwHhcNMjYwMTE5MjA0NjI0WhcNMjcwMTE5MjA0NjI0WjAxMRswGQYDVQQD
|
||||||
|
DBJtYWlsLmJha2VyeS1pYS5kZXYxEjAQBgNVBAoMCUJha2VyeSBJQTCCASIwDQYJ
|
||||||
|
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAL2ems6anCJ5y7BP6oJu46NWPIrwfX72
|
||||||
|
wZh1dDIiYH2cljPDJWlotNSBENx1RFYHG7gEREY50zECu0H/UsF3DYOLXhnF0uTW
|
||||||
|
CRNbEF1hb6MOijjuf9bG+7lVBy6fd1vQO2i905VKqE7DfYkib0VJq7GnUJ9Eam8X
|
||||||
|
IlSiJacQz2muYwzB0O7xYyUwTQVL7/JtMMk9f6CcVD5qQ0bnXBM3hjqUFY9glAyt
|
||||||
|
YdpTQHOvk5Yx+fMg/bYVPcCEadXUVHAtz1bRrlb0zyLsqWxwv9yV7JB3mtNCflWl
|
||||||
|
DBYdHortfTNLuR4XaE3WOjgo90OYmn/ObYz2WtIu02zy2HkNpMaAoVkCAwEAAaNT
|
||||||
|
MFEwHQYDVR0OBBYEFLKhOsnxZzWCTr0QnI7chMamkSojMB8GA1UdIwQYMBaAFLKh
|
||||||
|
OsnxZzWCTr0QnI7chMamkSojMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
|
||||||
|
BQADggEBAALCxFWUgcvweZhF1GvSgGtwUoVjBmpmFbqO0/wKij2XCFfz/AjjvZ8s
|
||||||
|
8eHPG9gw+n9ihcR7MzCeyfWQwQli0WfG2K0oP1FyLhaOZ2XmuOg6xMDnDW0Uekj3
|
||||||
|
BagGstEUzjBTuRRwY/nrNooVB9Qhbxhyofmy+W5fs8Y03Sdoii1iXmbHHZzc2/mH
|
||||||
|
avP14gpsYCCeYzjIrZm9Ya8G8iskXzSgeM/HHiG8I9hJFBXhtXadcxi/mNa4tJqh
|
||||||
|
3W+LB3hD84Udgs+GzBgHGvr0ulL14/iLUEqrIvZZ3vU9o6Vx2PoF47r0P5zNeuS7
|
||||||
|
dFNqOrIOjaJnr1qUoKLygwEHjuTMmI4=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
28
infrastructure/security/certificates/mail/tls.key
Normal file
28
infrastructure/security/certificates/mail/tls.key
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9nprOmpwiecuw
|
||||||
|
T+qCbuOjVjyK8H1+9sGYdXQyImB9nJYzwyVpaLTUgRDcdURWBxu4BERGOdMxArtB
|
||||||
|
/1LBdw2Di14ZxdLk1gkTWxBdYW+jDoo47n/Wxvu5VQcun3db0DtovdOVSqhOw32J
|
||||||
|
Im9FSauxp1CfRGpvFyJUoiWnEM9prmMMwdDu8WMlME0FS+/ybTDJPX+gnFQ+akNG
|
||||||
|
51wTN4Y6lBWPYJQMrWHaU0Bzr5OWMfnzIP22FT3AhGnV1FRwLc9W0a5W9M8i7Kls
|
||||||
|
cL/cleyQd5rTQn5VpQwWHR6K7X0zS7keF2hN1jo4KPdDmJp/zm2M9lrSLtNs8th5
|
||||||
|
DaTGgKFZAgMBAAECggEAInuLT3MSXbqkbgW6ccnUn8l47RNa3xHkluMVJGDYBz/I
|
||||||
|
mNUuIoMmD1cBR/YTXUmhos8z00mEvG7wusnBtOj/jiJ0FF/DQFYkBF8VFMY5VP+5
|
||||||
|
5yyIFvjMoiFyUuow/INbqmqK5aVUAi7Oz3dxoLoK/R2eLbh1WopsddOe4UjPTzpU
|
||||||
|
u5MYx5yLVuYsP7SOSHtkwe/03yDRKrIvWy5BPmc2QTHTpBOUBG4/CpRVGZ3f8KkD
|
||||||
|
7d+6Ve77uMeuxDO8mGgZZ54iwCn1+XGcEqQUGVuZx+qZhuXSfK4j4wyemnweEABv
|
||||||
|
mNSYIt68ouI+4pArWVN4AcixVELHWWz04XNnzXU24QKBgQD0esBYzudG2ZSkyIbQ
|
||||||
|
u8IxpOdsF4gSYizCd13KBKFnohm1kW9XzdfKvNnrqpTOFrHbDWQ7iiHJ3cjV9AU5
|
||||||
|
NQ01U3Yv4K8dukgoc/EAant/F8o0njsJIgfvY1nPsOTUEpkQBMPHjkhjr3qA6Hxv
|
||||||
|
xoB68GUuMNTtdB+AWF4utuObhQKBgQDGjg6bgljWETxNxAjT1smkxJsClflQmytf
|
||||||
|
cbh5VzjstcZwiKJ8uoLcOGxoNGX2HhbQANpEhTGqn0FHllEsPXmphyBUcMIPVSXI
|
||||||
|
EIKyOd/vLb8cXort6Lh3MKAhjEKlLD5VNp8WmYP3wBTMbkpk3CCulCHBKpBWWf66
|
||||||
|
PXZtEFJkxQKBgB3RLs5mBa0NcmSalF6215toalUzlYPwd1cMaeLup6TVD1+mqjbC
|
||||||
|
QzRVzhpBBr8P44c83eGpGi/dndYCWfS9NKwxTrPOKm1sv8o3Qch0NDWu+BlsxvR5
|
||||||
|
MxCORHDhOTdoQUTD4ADhqJCH4WABetPDGP5lfWGh0QZY6FKl9G6sHZxlAoGAZyK/
|
||||||
|
H7PzZS6KvnJHi5IUJ8wgIJW6bU5Ml0VA53aRERPSwf2XOWbANpfwZ6hgFhnHC8CF
|
||||||
|
n/X3uIMEq6S/AVXlblPMTVBM3R4DhApfeShq05hVnuzVCYNK3k6ZvxNWQunabvTy
|
||||||
|
ahDP5c8WfqIDbqSRLV2wst/jHZedoyvt6fUCd2kCgYEAlo4YzTZl//k+4XiixuLA
|
||||||
|
ggfby0hKs5AiKpV4CzUeQ5cKYOi9IzoC2LrLSX+UrH/wL70gBG6gyCRgWKimQnaV
|
||||||
|
tYO/13SrPUgnnuGj6CB5aEkyv2LaOVevXFEriEmd5qbJIrX0CfgQnFr6vnQd4pPS
|
||||||
|
8dU2Gah4b5WMJ5Iw80SpcGI=
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
@@ -55,10 +55,38 @@ BASE_IMAGES=(
|
|||||||
"ghcr.io/mailu/rspamd:2024.06"
|
"ghcr.io/mailu/rspamd:2024.06"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Local registry configuration
|
# Registry configuration
|
||||||
# Set USE_LOCAL_REGISTRY=true to push images to local registry after pulling
|
# Read from environment variables (set by Tiltfile or manually)
|
||||||
USE_LOCAL_REGISTRY=true
|
# USE_LOCAL_REGISTRY=true to push images to local registry after pulling
|
||||||
LOCAL_REGISTRY="localhost:5000"
|
# USE_GITEA_REGISTRY=true to push images to Gitea registry after pulling
|
||||||
|
USE_LOCAL_REGISTRY="${USE_LOCAL_REGISTRY:-true}"
|
||||||
|
USE_GITEA_REGISTRY="${USE_GITEA_REGISTRY:-false}"
|
||||||
|
|
||||||
|
echo "Registry configuration:"
|
||||||
|
echo " USE_LOCAL_REGISTRY=$USE_LOCAL_REGISTRY"
|
||||||
|
echo " USE_GITEA_REGISTRY=$USE_GITEA_REGISTRY"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check if Gitea registry should be used instead
|
||||||
|
if [ "$USE_GITEA_REGISTRY" = "true" ]; then
|
||||||
|
# Gitea registry is accessed via HTTPS on the registry subdomain (TLS terminated at ingress)
|
||||||
|
# Docker push/pull should use: registry.bakery-ia.local
|
||||||
|
# The registry serves on port 443 (HTTPS via ingress) but Docker defaults to 443 for HTTPS
|
||||||
|
REGISTRY="registry.bakery-ia.local"
|
||||||
|
echo "Testing Gitea registry accessibility at $REGISTRY..."
|
||||||
|
|
||||||
|
# Test if Gitea registry is accessible (try HTTPS first, then HTTP)
|
||||||
|
if curl -sk https://$REGISTRY/v2/ >/dev/null 2>&1; then
|
||||||
|
echo "✓ Gitea registry accessible via HTTPS"
|
||||||
|
elif curl -s http://$REGISTRY/v2/ >/dev/null 2>&1; then
|
||||||
|
echo "✓ Gitea registry accessible via HTTP"
|
||||||
|
else
|
||||||
|
echo "Warning: Gitea registry at $REGISTRY is not accessible, falling back to local registry"
|
||||||
|
REGISTRY="localhost:5000"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
REGISTRY="localhost:5000"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Base images to pre-pull:"
|
echo "Base images to pre-pull:"
|
||||||
echo "----------------------------------------"
|
echo "----------------------------------------"
|
||||||
@@ -77,22 +105,26 @@ for image in "${BASE_IMAGES[@]}"; do
|
|||||||
# Pull the image
|
# Pull the image
|
||||||
docker pull "$image"
|
docker pull "$image"
|
||||||
|
|
||||||
# Tag for local registry if enabled
|
# Tag for registry if enabled
|
||||||
if [ "$USE_LOCAL_REGISTRY" = true ]; then
|
if [ "$USE_LOCAL_REGISTRY" = "true" ] || [ "$USE_GITEA_REGISTRY" = "true" ]; then
|
||||||
# Convert image name to local registry format:
|
# Convert image name to registry format:
|
||||||
# - Replace / with _
|
# - Replace / with _
|
||||||
# - Replace : with _
|
# - Replace : with _
|
||||||
# - Convert to lowercase (Docker requires lowercase repository names)
|
# - Convert to lowercase (Docker requires lowercase repository names)
|
||||||
# - Add :latest tag for Kustomize compatibility
|
# - Add :latest tag for Kustomize compatibility
|
||||||
# Example: gcr.io/kaniko-project/executor:v1.23.0 -> gcr.io_kaniko-project_executor_v1.23.0:latest
|
# Example: gcr.io/kaniko-project/executor:v1.23.0 -> gcr.io_kaniko-project_executor_v1.23.0:latest
|
||||||
local_repo="$(echo $image | sed 's|/|_|g' | sed 's|:|_|g' | tr '[:upper:]' '[:lower:]')"
|
local_repo="$(echo $image | sed 's|/|_|g' | sed 's|:|_|g' | tr '[:upper:]' '[:lower:]')"
|
||||||
local_image="$LOCAL_REGISTRY/${local_repo}:latest"
|
registry_image="$REGISTRY/${local_repo}:latest"
|
||||||
docker tag "$image" "$local_image"
|
docker tag "$image" "$registry_image"
|
||||||
echo " Tagged as: $local_image"
|
echo " Tagged as: $registry_image"
|
||||||
|
|
||||||
# Push to local registry
|
# Push to registry
|
||||||
docker push "$local_image"
|
docker push "$registry_image"
|
||||||
echo " Pushed to local registry"
|
if [ "$USE_GITEA_REGISTRY" = "true" ]; then
|
||||||
|
echo " Pushed to Gitea registry"
|
||||||
|
else
|
||||||
|
echo " Pushed to local registry"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo " ✓ Successfully pulled $image"
|
echo " ✓ Successfully pulled $image"
|
||||||
@@ -105,12 +137,25 @@ echo "=========================================="
|
|||||||
echo ""
|
echo ""
|
||||||
echo "Summary:"
|
echo "Summary:"
|
||||||
echo " - Total images pulled: ${#BASE_IMAGES[@]}"
|
echo " - Total images pulled: ${#BASE_IMAGES[@]}"
|
||||||
echo " - Local registry enabled: $USE_LOCAL_REGISTRY"
|
if [ "$USE_GITEA_REGISTRY" = "true" ]; then
|
||||||
|
echo " - Gitea registry enabled: $USE_GITEA_REGISTRY"
|
||||||
|
echo " - Registry URL: $REGISTRY"
|
||||||
|
else
|
||||||
|
echo " - Local registry enabled: $USE_LOCAL_REGISTRY"
|
||||||
|
echo " - Registry URL: $REGISTRY"
|
||||||
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
if [ "$USE_LOCAL_REGISTRY" = true ]; then
|
if [ "$USE_LOCAL_REGISTRY" = "true" ] || [ "$USE_GITEA_REGISTRY" = "true" ]; then
|
||||||
echo "Local registry contents:"
|
if [ "$USE_GITEA_REGISTRY" = "true" ]; then
|
||||||
curl -s http://$LOCAL_REGISTRY/v2/_catalog | jq .
|
echo "Gitea registry contents:"
|
||||||
|
# Note: Gitea registry API might be different, using the standard registry API for now
|
||||||
|
# If Gitea registry is not accessible, this might fail
|
||||||
|
curl -s http://$REGISTRY/v2/_catalog | jq . 2>/dev/null || echo "Could not access registry contents (Gitea registry may not support this endpoint)"
|
||||||
|
else
|
||||||
|
echo "Local registry contents:"
|
||||||
|
curl -s http://$REGISTRY/v2/_catalog | jq . 2>/dev/null || echo "Could not access registry contents"
|
||||||
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -120,20 +165,37 @@ echo " 2. For Kubernetes: Consider setting up a pull-through cache"
|
|||||||
echo " 3. For CI/CD: Run this script before your build pipeline"
|
echo " 3. For CI/CD: Run this script before your build pipeline"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
echo "To use local registry in your builds:"
|
echo "To use registry in your builds:"
|
||||||
echo " - Update Dockerfiles to use: $LOCAL_REGISTRY/..."
|
if [ "$USE_GITEA_REGISTRY" = true ]; then
|
||||||
echo " - Or configure Docker daemon to use local registry as mirror"
|
echo " - Update Dockerfiles to use: $REGISTRY/..."
|
||||||
|
echo " - Gitea registry URL: $REGISTRY"
|
||||||
|
else
|
||||||
|
echo " - Update Dockerfiles to use: $REGISTRY/..."
|
||||||
|
echo " - Local registry URL: $REGISTRY"
|
||||||
|
fi
|
||||||
|
echo " - Or configure Docker daemon to use registry as mirror"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Optional: Configure Docker daemon to use local registry as mirror
|
# Optional: Configure Docker daemon to use registry as mirror
|
||||||
if [ "$USE_LOCAL_REGISTRY" = true ]; then
|
if [ "$USE_LOCAL_REGISTRY" = "true" ] || [ "$USE_GITEA_REGISTRY" = "true" ]; then
|
||||||
echo "To configure Docker daemon to use local registry as mirror:"
|
if [ "$USE_GITEA_REGISTRY" = "true" ]; then
|
||||||
echo ""
|
echo "To configure Docker daemon to use Gitea registry as mirror:"
|
||||||
cat << 'EOF'
|
echo ""
|
||||||
|
cat << EOF
|
||||||
|
{
|
||||||
|
"registry-mirrors": ["https://registry.bakery-ia.local"],
|
||||||
|
"insecure-registries": ["registry.bakery-ia.local"]
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
echo "To configure Docker daemon to use local registry as mirror:"
|
||||||
|
echo ""
|
||||||
|
cat << 'EOF'
|
||||||
{
|
{
|
||||||
"registry-mirrors": ["http://localhost:5000"]
|
"registry-mirrors": ["http://localhost:5000"]
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
echo "Add this to /etc/docker/daemon.json and restart Docker"
|
echo "Add this to /etc/docker/daemon.json and restart Docker"
|
||||||
fi
|
fi
|
||||||
Reference in New Issue
Block a user