Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ API_KEY_CACHE_TTL=300
RATE_LIMIT_ENABLED=true

# Redis Configuration
# Deployment mode: standalone (default), cluster, or sentinel
REDIS_MODE=standalone
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
Expand All @@ -42,6 +44,33 @@ REDIS_MAX_CONNECTIONS=20
REDIS_SOCKET_TIMEOUT=5
REDIS_SOCKET_CONNECT_TIMEOUT=5

# Optional key prefix — useful when sharing a Redis instance across environments
# All keys will be stored as <prefix><key> (e.g. "prod:sessions:abc")
REDIS_KEY_PREFIX=

# Redis Cluster Mode (REDIS_MODE=cluster)
# Comma-separated list of host:port pairs for cluster startup nodes
# REDIS_CLUSTER_NODES=node1:6379,node2:6379,node3:6379

# Redis Sentinel Mode (REDIS_MODE=sentinel)
# Comma-separated list of host:port pairs for Sentinel instances
# REDIS_SENTINEL_NODES=sentinel1:26379,sentinel2:26379,sentinel3:26379
# REDIS_SENTINEL_MASTER=mymaster
# REDIS_SENTINEL_PASSWORD=

# Redis TLS/SSL Configuration
# Required for most managed Redis services (GCP Memorystore, AWS ElastiCache, Azure Cache)
REDIS_TLS_ENABLED=false
# REDIS_TLS_CA_CERT_FILE=/path/to/ca.crt
# REDIS_TLS_CERT_FILE=/path/to/client.crt
# REDIS_TLS_KEY_FILE=/path/to/client.key
# REDIS_TLS_INSECURE=false
# Hostname verification is off by default because managed Redis services
# and Redis Cluster mode expose node IPs that don't match cert CN/SAN.
# The CA certificate chain is still fully verified. Enable hostname
# checking when your Redis server hostnames match certificate CN/SAN.
# REDIS_TLS_CHECK_HOSTNAME=false

# MinIO/S3 Configuration
MINIO_ENDPOINT=localhost:9000
MINIO_ACCESS_KEY=minioadmin
Expand Down Expand Up @@ -144,6 +173,37 @@ METRICS_ARCHIVE_RETENTION_DAYS=90
ENABLE_NETWORK_ISOLATION=true
ENABLE_FILESYSTEM_ISOLATION=true

# Kubernetes Execution Configuration
# Execution mode: 'agent' (default, recommended) or 'nsenter' (legacy)
# agent: Executor-agent binary runs inside the main container.
# No nsenter, no capabilities, no privilege escalation.
# Compatible with GKE Sandbox (gVisor) and restricted Pod Security Standards.
# nsenter: Sidecar uses nsenter to enter the main container's mount namespace.
# Requires shareProcessNamespace, SYS_PTRACE/SYS_ADMIN/SYS_CHROOT caps,
# and allowPrivilegeEscalation: true. NOT compatible with GKE Sandbox.
K8S_EXECUTION_MODE=agent
# K8S_EXECUTOR_PORT=9090 # Port for the executor-agent HTTP server (agent mode only)

# Sidecar image — must match the execution mode:
# agent mode: aronmuon/kubecoderun-sidecar-agent:latest (default)
# nsenter mode: aronmuon/kubecoderun-sidecar-nsenter:latest
# K8S_SIDECAR_IMAGE=aronmuon/kubecoderun-sidecar-agent:latest

# Image pull policy for execution pods (Always, IfNotPresent, Never)
# K8S_IMAGE_PULL_POLICY=Always

# Image pull secrets for private container registries (comma-separated secret names)
# These Kubernetes secrets must already exist in the execution namespace.
# Leave empty or unset if not using private registries.
# K8S_IMAGE_PULL_SECRETS=my-registry-secret,another-secret

# GKE Sandbox (gVisor) Configuration
# Requires K8S_EXECUTION_MODE=agent (nsenter is incompatible with gVisor)
# GKE_SANDBOX_ENABLED=false
# GKE_SANDBOX_RUNTIME_CLASS=gvisor
# GKE_SANDBOX_NODE_SELECTOR={}
# GKE_SANDBOX_CUSTOM_TOLERATIONS=[]

# WAN Network Access Configuration
# When enabled, execution containers can access the public internet
# but are blocked from accessing host, other containers, and private networks
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ jobs:
uses: ./.github/workflows/docker-build-reusable.yml
secrets: inherit
with:
image_name: kubecoderun-sidecar
image_name: kubecoderun-sidecar-agent
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears you are no longer building sidecar-nsenter?

dockerfile: docker/sidecar/Dockerfile
context: docker/sidecar
image_tag: ${{ needs.changes.outputs.image_tag }}
Expand Down Expand Up @@ -344,7 +344,7 @@ jobs:
uses: ./.github/workflows/docker-retag-reusable.yml
secrets: inherit
with:
image_name: kubecoderun-sidecar
image_name: kubecoderun-sidecar-agent
new_tag: ${{ needs.changes.outputs.image_tag }}
previous_tag: ${{ needs.changes.outputs.previous_tag }}

Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,5 @@ config/local.py

# Hatch auto-generated version file
_version.py

.pdm-python
231 changes: 231 additions & 0 deletions docker-compose.redis-cluster-tls.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
# Redis Cluster with TLS for integration testing
#
# This mimics a production GCP Memorystore Redis Cluster setup:
# - 6-node cluster (3 masters + 3 replicas) with TLS enabled
# - No authentication (no password)
# - Server-side TLS with CA verification (no mutual TLS / no client certs)
# - Accessible on localhost ports 6380-6385 (TLS)
#
# Usage:
# docker compose -f docker-compose.redis-cluster-tls.yml up -d
#
# Test with:
# redis-cli -c -p 6380 --tls --cacert tests/tls-certs/ca.crt CLUSTER INFO

services:
redis-tls-node-0:
image: redis:7-alpine
container_name: redis-tls-cluster-0
ports:
- "127.0.0.1:6380:6380"
- "127.0.0.1:16380:16380"
volumes:
- redis-tls-cluster-0:/data
- ./tests/tls-certs:/tls:ro
command: >
redis-server
--port 0
--tls-port 6380
--tls-cert-file /tls/redis.crt
--tls-key-file /tls/redis.key
--tls-ca-cert-file /tls/ca.crt
--tls-auth-clients no
--tls-replication yes
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--appendonly yes
--bind 0.0.0.0
--protected-mode no
healthcheck:
test: ["CMD", "redis-cli", "-p", "6380", "--tls", "--cert", "/tls/redis.crt", "--key", "/tls/redis.key", "--cacert", "/tls/ca.crt", "ping"]
interval: 5s
timeout: 3s
retries: 10

redis-tls-node-1:
image: redis:7-alpine
container_name: redis-tls-cluster-1
ports:
- "127.0.0.1:6381:6381"
- "127.0.0.1:16381:16381"
volumes:
- redis-tls-cluster-1:/data
- ./tests/tls-certs:/tls:ro
command: >
redis-server
--port 0
--tls-port 6381
--tls-cert-file /tls/redis.crt
--tls-key-file /tls/redis.key
--tls-ca-cert-file /tls/ca.crt
--tls-auth-clients no
--tls-replication yes
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--appendonly yes
--bind 0.0.0.0
--protected-mode no
healthcheck:
test: ["CMD", "redis-cli", "-p", "6381", "--tls", "--cert", "/tls/redis.crt", "--key", "/tls/redis.key", "--cacert", "/tls/ca.crt", "ping"]
interval: 5s
timeout: 3s
retries: 10

redis-tls-node-2:
image: redis:7-alpine
container_name: redis-tls-cluster-2
ports:
- "127.0.0.1:6382:6382"
- "127.0.0.1:16382:16382"
volumes:
- redis-tls-cluster-2:/data
- ./tests/tls-certs:/tls:ro
command: >
redis-server
--port 0
--tls-port 6382
--tls-cert-file /tls/redis.crt
--tls-key-file /tls/redis.key
--tls-ca-cert-file /tls/ca.crt
--tls-auth-clients no
--tls-replication yes
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--appendonly yes
--bind 0.0.0.0
--protected-mode no
healthcheck:
test: ["CMD", "redis-cli", "-p", "6382", "--tls", "--cert", "/tls/redis.crt", "--key", "/tls/redis.key", "--cacert", "/tls/ca.crt", "ping"]
interval: 5s
timeout: 3s
retries: 10

redis-tls-node-3:
image: redis:7-alpine
container_name: redis-tls-cluster-3
ports:
- "127.0.0.1:6383:6383"
- "127.0.0.1:16383:16383"
volumes:
- redis-tls-cluster-3:/data
- ./tests/tls-certs:/tls:ro
command: >
redis-server
--port 0
--tls-port 6383
--tls-cert-file /tls/redis.crt
--tls-key-file /tls/redis.key
--tls-ca-cert-file /tls/ca.crt
--tls-auth-clients no
--tls-replication yes
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--appendonly yes
--bind 0.0.0.0
--protected-mode no
healthcheck:
test: ["CMD", "redis-cli", "-p", "6383", "--tls", "--cert", "/tls/redis.crt", "--key", "/tls/redis.key", "--cacert", "/tls/ca.crt", "ping"]
interval: 5s
timeout: 3s
retries: 10

redis-tls-node-4:
image: redis:7-alpine
container_name: redis-tls-cluster-4
ports:
- "127.0.0.1:6384:6384"
- "127.0.0.1:16384:16384"
volumes:
- redis-tls-cluster-4:/data
- ./tests/tls-certs:/tls:ro
command: >
redis-server
--port 0
--tls-port 6384
--tls-cert-file /tls/redis.crt
--tls-key-file /tls/redis.key
--tls-ca-cert-file /tls/ca.crt
--tls-auth-clients no
--tls-replication yes
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--appendonly yes
--bind 0.0.0.0
--protected-mode no
healthcheck:
test: ["CMD", "redis-cli", "-p", "6384", "--tls", "--cert", "/tls/redis.crt", "--key", "/tls/redis.key", "--cacert", "/tls/ca.crt", "ping"]
interval: 5s
timeout: 3s
retries: 10

redis-tls-node-5:
image: redis:7-alpine
container_name: redis-tls-cluster-5
ports:
- "127.0.0.1:6385:6385"
- "127.0.0.1:16385:16385"
volumes:
- redis-tls-cluster-5:/data
- ./tests/tls-certs:/tls:ro
command: >
redis-server
--port 0
--tls-port 6385
--tls-cert-file /tls/redis.crt
--tls-key-file /tls/redis.key
--tls-ca-cert-file /tls/ca.crt
--tls-auth-clients no
--tls-replication yes
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--appendonly yes
--bind 0.0.0.0
--protected-mode no
healthcheck:
test: ["CMD", "redis-cli", "-p", "6385", "--tls", "--cert", "/tls/redis.crt", "--key", "/tls/redis.key", "--cacert", "/tls/ca.crt", "ping"]
interval: 5s
timeout: 3s
retries: 10

# Initializer: creates TLS cluster from the 6 nodes
redis-tls-cluster-init:
image: redis:7-alpine
container_name: redis-tls-cluster-init
volumes:
- ./tests/tls-certs:/tls:ro
depends_on:
redis-tls-node-0:
condition: service_healthy
redis-tls-node-1:
condition: service_healthy
redis-tls-node-2:
condition: service_healthy
redis-tls-node-3:
condition: service_healthy
redis-tls-node-4:
condition: service_healthy
redis-tls-node-5:
condition: service_healthy
restart: "no"
entrypoint:
- sh
- -c
- |
echo 'Creating Redis TLS Cluster...' &&
redis-cli --cluster create redis-tls-node-0:6380 redis-tls-node-1:6381 redis-tls-node-2:6382 redis-tls-node-3:6383 redis-tls-node-4:6384 redis-tls-node-5:6385 --cluster-replicas 1 --cluster-yes --tls --cert /tls/redis.crt --key /tls/redis.key --cacert /tls/ca.crt &&
echo 'Redis TLS Cluster created successfully' &&
redis-cli -h redis-tls-node-0 -p 6380 --tls --cert /tls/redis.crt --key /tls/redis.key --cacert /tls/ca.crt CLUSTER INFO

volumes:
redis-tls-cluster-0:
redis-tls-cluster-1:
redis-tls-cluster-2:
redis-tls-cluster-3:
redis-tls-cluster-4:
redis-tls-cluster-5:
Loading