Skip to content
Open
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
9 changes: 7 additions & 2 deletions .github/workflows/deploy-cloud.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ jobs:
sed -i "s|__CUBE_PUBLIC_URL__|${{ secrets.CUBE_PUBLIC_URL }}|g" docker/.env
sed -i "s|__CUBE_INTERNAL_AGENT_URL__|${{ secrets.CUBE_INTERNAL_AGENT_URL }}|g" docker/.env

# Replace Google OAuth placeholders
sed -i "s|__SMQ_GOOGLE_CLIENT_ID__|${{ secrets.SMQ_GOOGLE_CLIENT_ID }}|g" docker/.env
sed -i "s|__SMQ_GOOGLE_CLIENT_SECRET__|${{ secrets.SMQ_GOOGLE_CLIENT_SECRET }}|g" docker/.env
sed -i "s|__SMQ_GOOGLE_STATE__|${{ secrets.SMQ_GOOGLE_STATE }}|g" docker/.env

# Replace Traefik configuration placeholders
sed -i "s|__TRAEFIK_HTTP_PORT__|${{ secrets.TRAEFIK_HTTP_PORT }}|g" docker/.env
sed -i "s|__TRAEFIK_HTTPS_PORT__|${{ secrets.TRAEFIK_HTTPS_PORT }}|g" docker/.env
Expand All @@ -111,10 +116,10 @@ jobs:
docker compose -f docker/compose.yaml --profile cloud pull 2>&1

echo "Stopping existing services"
make down-cloud 2>&1
docker compose -f docker/compose.yaml --profile cloud down 2>&1

echo "Starting cloud services"
make up-cloud 2>&1
docker compose -f docker/compose.yaml --profile cloud up -d 2>&1

echo "Waiting for services to start (30 seconds)..."
sleep 30
Expand Down
85 changes: 25 additions & 60 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -155,28 +155,36 @@ up-vllm: config-vllm
@echo "Starting Cube with vLLM backend..."
docker compose -f docker/compose.yaml --profile vllm up -d

.PHONY: disable-atls
disable-atls:
@echo "Disabling attested TLS for local development..."
@sed -i 's|^UV_CUBE_AGENT_CLIENT_CERT=.*|UV_CUBE_AGENT_CLIENT_CERT=|' docker/.env
@sed -i 's|^UV_CUBE_AGENT_CLIENT_KEY=.*|UV_CUBE_AGENT_CLIENT_KEY=|' docker/.env
@sed -i 's|^UV_CUBE_AGENT_SERVER_CA_CERTS=.*|UV_CUBE_AGENT_SERVER_CA_CERTS=|' docker/.env
@sed -i 's|^UV_CUBE_AGENT_ATTESTED_TLS=.*|UV_CUBE_AGENT_ATTESTED_TLS=false|' docker/.env
@sed -i 's|^UV_CUBE_AGENT_ATTESTATION_POLICY=.*|UV_CUBE_AGENT_ATTESTATION_POLICY=|' docker/.env
@echo "✓ Attested TLS disabled"

.PHONY: up
up: enable-guardrails config-backend config-cloud-local
up: config-local enable-guardrails config-backend disable-atls
ifeq ($(AI_BACKEND),vllm)
@$(MAKE) up-vllm
else
@$(MAKE) up-ollama
endif

.PHONY: up-disable-guardrails
up-disable-guardrails: disable-guardrails config-backend config-cloud-local
up-disable-guardrails: config-cloud-local disable-guardrails config-backend disable-atls
ifeq ($(AI_BACKEND),vllm)
@$(MAKE) up-vllm
else
@$(MAKE) up-ollama
endif

.PHONY: config-cloud-local
config-cloud-local:
@echo "Configuring cloud deployment for local environment..."
@cp docker/.env docker/.env.backup 2>/dev/null || true
@cp docker/traefik/dynamic.toml docker/traefik/dynamic.toml.backup 2>/dev/null || true
@cp docker/config.json docker/config.json.backup 2>/dev/null || true
.PHONY: config-local
config-local:
@echo "Configuring for local development..."
@git checkout -- docker/.env docker/traefik/dynamic.toml docker/config.json 2>/dev/null || true
@sed -i 's|__SMQ_EMAIL_HOST__|localhost|g' docker/.env
@sed -i 's|__SMQ_EMAIL_PORT__|1025|g' docker/.env
@sed -i 's|__SMQ_EMAIL_USERNAME__|test|g' docker/.env
Expand All @@ -189,67 +197,27 @@ config-cloud-local:
@sed -i 's|__SMQ_GOOGLE_CLIENT_SECRET__||g' docker/.env
@sed -i 's|__SMQ_GOOGLE_STATE__||g' docker/.env
@sed -i 's|__CUBE_PUBLIC_URL__|localhost|g' docker/.env
@sed -i 's|^TRAEFIK_HTTP_PORT=.*|TRAEFIK_HTTP_PORT=49210|g' docker/.env
@sed -i 's|^TRAEFIK_HTTPS_PORT=.*|TRAEFIK_HTTPS_PORT=49211|g' docker/.env
@sed -i 's|^TRAEFIK_DASHBOARD_PORT=.*|TRAEFIK_DASHBOARD_PORT=49212|g' docker/.env
@sed -i 's|^TRAEFIK_HTTP_PORT=.*|TRAEFIK_HTTP_PORT=80|g' docker/.env
@sed -i 's|^TRAEFIK_HTTPS_PORT=.*|TRAEFIK_HTTPS_PORT=443|g' docker/.env
@sed -i 's|^TRAEFIK_DASHBOARD_PORT=.*|TRAEFIK_DASHBOARD_PORT=8080|g' docker/.env
@echo "✓ Configured with local defaults"

.PHONY: restore-cloud-config
restore-cloud-config:
@echo "Restoring cloud deployment placeholders..."
@if [ -f docker/.env.backup ]; then \
mv docker/.env.backup docker/.env; \
echo "✓ Restored .env"; \
fi
@if [ -f docker/traefik/dynamic.toml.backup ]; then \
mv docker/traefik/dynamic.toml.backup docker/traefik/dynamic.toml; \
echo "✓ Restored dynamic.toml"; \
fi
@if [ -f docker/config.json.backup ]; then \
mv docker/config.json.backup docker/config.json; \
echo "✓ Restored config.json"; \
fi

.PHONY: up-cloud
up-cloud: config-cloud-local
@echo "Starting Cube Cloud services with local configuration..."
@mkdir -p docker/traefik/ssl/certs docker/traefik/letsencrypt
@if [ ! -f docker/traefik/ssl/certs/acme.json ]; then \
printf '{}' > docker/traefik/ssl/certs/acme.json; \
chmod 600 docker/traefik/ssl/certs/acme.json; \
echo "✓ Created acme.json"; \
fi
docker compose -f docker/compose.yaml --profile cloud up -d
@echo ""
@echo "=== Cube Cloud Services Started ==="
@echo " - UI: http://localhost:49210/"
@echo " - Proxy API: http://localhost:49210/proxy"
@echo " - Traefik Dashboard: http://localhost:49212"
@echo ""
@echo "Note: Run 'make restore-cloud-config' to restore placeholders after stopping"
.PHONY: restore-config
restore-config:
@echo "Restoring configuration placeholders..."
@git checkout -- docker/.env docker/traefik/dynamic.toml docker/config.json 2>/dev/null && \
echo "✓ Restored from git" || echo "⚠ git restore failed, files may not be tracked"

.PHONY: down
down:
@echo "Stopping all Cube services..."
docker compose -f docker/compose.yaml down

.PHONY: down-cloud
down-cloud:
@echo "Stopping Cube Cloud services..."
docker compose -f docker/compose.yaml --profile cloud down
@$(MAKE) restore-cloud-config

.PHONY: down-volumes
down-volumes:
@echo "Stopping all Cube services and removing volumes..."
docker compose -f docker/compose.yaml down -v

.PHONY: down-cloud-volumes
down-cloud-volumes:
@echo "Stopping Cube Cloud services and removing volumes..."
docker compose -f docker/compose.yaml --profile cloud down -v
@$(MAKE) restore-cloud-config

.PHONY: restart
restart: down up

Expand All @@ -259,9 +227,6 @@ restart-ollama: down up-ollama
.PHONY: restart-vllm
restart-vllm: down up-vllm

.PHONY: restart-cloud
restart-cloud: down-cloud up-cloud

.PHONY: logs
logs:
docker compose -f docker/compose.yaml logs -f
Expand Down Expand Up @@ -345,7 +310,7 @@ help:
@echo ""
@echo "Cloud Configuration Commands:"
@echo " config-cloud-local Configure cloud deployment with localhost defaults"
@echo " restore-cloud-config Restore placeholder values in cloud config files"
@echo " restore-config Restore placeholder values in config files"
@echo ""
@echo "Logs:"
@echo " logs Show all logs"
Expand Down
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,17 @@ Cube AI uses TEEs to protect user data and AI models from unauthorized access. T
# Local development with vLLM
make up-vllm

# Cloud deployment (configures traefik for cloud ports)
make up-cloud

# Stop services
make down

# Stop services and remove volumes
# Stop services and remove volumes (includes all profiles)
make down-volumes
```

**Local Development Access:**
- Traefik Gateway: https://localhost (ports 80/443)
- All services accessible through Traefik reverse proxy

3. **Get your authentication token**

All API requests require JWT authentication. Once services are running, obtain a token:
Expand Down Expand Up @@ -188,9 +189,16 @@ Cube AI uses TEEs to protect user data and AI models from unauthorized access. T

Cube AI exposes all services through a Traefik reverse proxy. All protected endpoints require the `Authorization: Bearer <token>` header with a valid JWT token.

**Local Development Access:**
- Via Traefik HTTPS: `https://localhost` (port 443)

**Cloud Deployment Access:**
- Via Traefik HTTPS: `https://your-domain.com`

### Proxy Endpoints (OpenAI-Compatible)

**Base URL:** `https://localhost/proxy/`
**Base URL (Local):** `https://localhost/proxy/`
**Base URL (Cloud):** `https://your-domain.com/proxy/`

Replace `{domainID}` with your domain ID from the Getting Started section.

Expand Down Expand Up @@ -231,7 +239,8 @@ curl -k https://localhost/proxy/YOUR_DOMAIN_ID/api/tags \

### Auth Endpoints

**Base URL:** `https://localhost/users`
**Base URL (Local):** `https://localhost/users`
**Base URL (Cloud):** `https://your-domain.com/users`

| Method | Path | Description |
|--------|-------------------------------|----------------------------------------|
Expand All @@ -254,7 +263,8 @@ curl -ksSiX POST https://localhost/users/tokens/issue \

### Domains Endpoints

**Base URL:** `https://localhost/domains`
**Base URL (Local):** `https://localhost/domains`
**Base URL (Cloud):** `https://your-domain.com/domains`

| Method | Path | Description |
|--------|-------------------------------|----------------------------------------|
Expand Down
2 changes: 2 additions & 0 deletions docker/.env
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ SMQ_AUTH_SECRET_KEY="ZA4vBf79fy6mrvQD2XnMqc4vNB9WDz"
SMQ_AUTH_ACCESS_TOKEN_DURATION="1h"
SMQ_AUTH_REFRESH_TOKEN_DURATION="24h"
SMQ_AUTH_INVITATION_DURATION="168h"
SMQ_AUTH_LOGIN_TOKEN_DURATION=
SMQ_AUTH_ADAPTER_INSTANCE_ID=
SMQ_AUTH_URL=http://auth:8189
SMQ_AUTH_KEYS_ALGORITHM="EdDSA"
Expand Down Expand Up @@ -248,6 +249,7 @@ UV_CUBE_UI_LLM_DEFAULT_MODEL=tinyllama:1.1b

# UI Attestation Configuration
CUBE_AI_ATTESTATION_URL=http://cube-proxy:${UV_CUBE_PROXY_PORT}
CUBE_AI_PROXY_URL=http://cube-proxy:${UV_CUBE_PROXY_PORT}

## Guardrails DB
UV_GUARDRAILS_DB_HOST=cube-guardrails-db
Expand Down
16 changes: 0 additions & 16 deletions docker/supermq-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -424,22 +424,6 @@ services:
SMQ_AUTH_GRPC_CLIENT_CERT: ${SMQ_AUTH_GRPC_CLIENT_CERT:+/auth-grpc-client.crt}
SMQ_AUTH_GRPC_CLIENT_KEY: ${SMQ_AUTH_GRPC_CLIENT_KEY:+/auth-grpc-client.key}
SMQ_AUTH_GRPC_SERVER_CA_CERTS: ${SMQ_AUTH_GRPC_SERVER_CA_CERTS:+/auth-grpc-server-ca.crt}
SMQ_GROUPS_GRPC_URL: ${SMQ_GROUPS_GRPC_URL}
SMQ_GROUPS_GRPC_TIMEOUT: ${SMQ_GROUPS_GRPC_TIMEOUT}
SMQ_GROUPS_GRPC_CLIENT_CERT: ${SMQ_GROUPS_GRPC_CLIENT_CERT:+/groups-grpc-client.crt}
SMQ_GROUPS_GRPC_CLIENT_KEY: ${SMQ_GROUPS_GRPC_CLIENT_KEY:+/groups-grpc-client.key}
SMQ_GROUPS_GRPC_SERVER_CA_CERTS: ${SMQ_GROUPS_GRPC_SERVER_CA_CERTS:+/groups-grpc-server-ca.crt}
SMQ_CHANNELS_URL: ${SMQ_CHANNELS_URL}
SMQ_CHANNELS_GRPC_URL: ${SMQ_CHANNELS_GRPC_URL}
SMQ_CHANNELS_GRPC_TIMEOUT: ${SMQ_CHANNELS_GRPC_TIMEOUT}
SMQ_CHANNELS_GRPC_CLIENT_CERT: ${SMQ_CHANNELS_GRPC_CLIENT_CERT:+/channels-grpc-client.crt}
SMQ_CHANNELS_GRPC_CLIENT_KEY: ${SMQ_CHANNELS_GRPC_CLIENT_KEY:+/channels-grpc-client.key}
SMQ_CHANNELS_GRPC_SERVER_CA_CERTS: ${SMQ_CHANNELS_GRPC_SERVER_CA_CERTS:+/channels-grpc-server-ca.crt}
SMQ_CLIENTS_GRPC_URL: ${SMQ_CLIENTS_GRPC_URL}
SMQ_CLIENTS_GRPC_TIMEOUT: ${SMQ_CLIENTS_GRPC_TIMEOUT}
SMQ_CLIENTS_GRPC_CLIENT_CERT: ${SMQ_CLIENTS_GRPC_CLIENT_CERT:+/clients-grpc-client.crt}
SMQ_CLIENTS_GRPC_CLIENT_KEY: ${SMQ_CLIENTS_GRPC_CLIENT_KEY:+/clients-grpc-client.key}
SMQ_CLIENTS_GRPC_R_CA_CERTS: ${SMQ_CLIENTS_GRPC_SERVER_CA_CERTS:+/clients-grpc-server-ca.crt}
SMQ_AUTH_KEYS_ALGORITHM: ${SMQ_AUTH_KEYS_ALGORITHM}
SMQ_AUTH_JWKS_URL: ${SMQ_AUTH_JWKS_URL}
SMQ_JAEGER_URL: ${SMQ_JAEGER_URL}
Expand Down