Add Kong config generator for production API keys
Build and Push Docker Image / build (push) Successful in 1m36s
Details
Build and Push Docker Image / build (push) Successful in 1m36s
Details
Kong's declarative config doesn't support env vars, so API keys must be embedded in kong.yml. Added generate-kong-config.sh script and integrated it into deploy.sh to automatically generate kong.yml from .env values. Run ./scripts/generate-kong-config.sh once after setting up .env, then docker compose up -d will work correctly. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
d0545e8aa7
commit
4f78be3943
207
deploy.sh
207
deploy.sh
|
|
@ -141,6 +141,206 @@ generate_secrets() {
|
||||||
log_info "Copy these values to your .env file"
|
log_info "Copy these values to your .env file"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Generate Kong configuration with API keys from .env
|
||||||
|
generate_kong_config() {
|
||||||
|
log_info "Generating Kong configuration..."
|
||||||
|
|
||||||
|
# Load environment variables
|
||||||
|
if [ -f .env ]; then
|
||||||
|
export $(grep -v '^#' .env | grep -E '^(ANON_KEY|SERVICE_ROLE_KEY)=' | xargs)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$ANON_KEY" ] || [ -z "$SERVICE_ROLE_KEY" ]; then
|
||||||
|
log_error "ANON_KEY and SERVICE_ROLE_KEY must be set in .env"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat > supabase/docker/kong.yml << KONG_EOF
|
||||||
|
_format_version: "2.1"
|
||||||
|
_transform: true
|
||||||
|
|
||||||
|
consumers:
|
||||||
|
- username: ANON
|
||||||
|
keyauth_credentials:
|
||||||
|
- key: ${ANON_KEY}
|
||||||
|
- username: SERVICE_ROLE
|
||||||
|
keyauth_credentials:
|
||||||
|
- key: ${SERVICE_ROLE_KEY}
|
||||||
|
|
||||||
|
acls:
|
||||||
|
- consumer: ANON
|
||||||
|
group: anon
|
||||||
|
- consumer: SERVICE_ROLE
|
||||||
|
group: admin
|
||||||
|
|
||||||
|
services:
|
||||||
|
- name: auth-verify-redirect
|
||||||
|
url: http://portal:3000/auth/verify
|
||||||
|
routes:
|
||||||
|
- name: auth-verify-redirect
|
||||||
|
strip_path: false
|
||||||
|
paths:
|
||||||
|
- /auth/verify
|
||||||
|
preserve_host: false
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
|
||||||
|
- name: auth-v1-open
|
||||||
|
url: http://auth:9999/verify
|
||||||
|
routes:
|
||||||
|
- name: auth-v1-open
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /auth/v1/verify
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
|
||||||
|
- name: auth-v1-open-callback
|
||||||
|
url: http://auth:9999/callback
|
||||||
|
routes:
|
||||||
|
- name: auth-v1-open-callback
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /auth/v1/callback
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
|
||||||
|
- name: auth-v1-open-authorize
|
||||||
|
url: http://auth:9999/authorize
|
||||||
|
routes:
|
||||||
|
- name: auth-v1-open-authorize
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /auth/v1/authorize
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
|
||||||
|
- name: auth-v1
|
||||||
|
url: http://auth:9999/
|
||||||
|
routes:
|
||||||
|
- name: auth-v1
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /auth/v1/
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
- name: key-auth
|
||||||
|
config:
|
||||||
|
hide_credentials: false
|
||||||
|
- name: acl
|
||||||
|
config:
|
||||||
|
hide_groups_header: true
|
||||||
|
allow:
|
||||||
|
- admin
|
||||||
|
- anon
|
||||||
|
|
||||||
|
- name: rest-v1
|
||||||
|
url: http://rest:3000/
|
||||||
|
routes:
|
||||||
|
- name: rest-v1
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /rest/v1/
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
- name: key-auth
|
||||||
|
config:
|
||||||
|
hide_credentials: false
|
||||||
|
- name: acl
|
||||||
|
config:
|
||||||
|
hide_groups_header: true
|
||||||
|
allow:
|
||||||
|
- admin
|
||||||
|
- anon
|
||||||
|
|
||||||
|
- name: realtime-v1-ws
|
||||||
|
url: http://realtime:4000/socket
|
||||||
|
routes:
|
||||||
|
- name: realtime-v1-ws
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /realtime/v1/websocket
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
- name: key-auth
|
||||||
|
config:
|
||||||
|
hide_credentials: false
|
||||||
|
- name: acl
|
||||||
|
config:
|
||||||
|
hide_groups_header: true
|
||||||
|
allow:
|
||||||
|
- admin
|
||||||
|
- anon
|
||||||
|
|
||||||
|
- name: realtime-v1
|
||||||
|
url: http://realtime:4000/
|
||||||
|
routes:
|
||||||
|
- name: realtime-v1
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /realtime/v1/
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
- name: key-auth
|
||||||
|
config:
|
||||||
|
hide_credentials: false
|
||||||
|
- name: acl
|
||||||
|
config:
|
||||||
|
hide_groups_header: true
|
||||||
|
allow:
|
||||||
|
- admin
|
||||||
|
- anon
|
||||||
|
|
||||||
|
- name: storage-v1-public
|
||||||
|
url: http://storage:5000/object/public
|
||||||
|
routes:
|
||||||
|
- name: storage-v1-public
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /storage/v1/object/public
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
|
||||||
|
- name: storage-v1
|
||||||
|
url: http://storage:5000/
|
||||||
|
routes:
|
||||||
|
- name: storage-v1
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /storage/v1/
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
- name: key-auth
|
||||||
|
config:
|
||||||
|
hide_credentials: false
|
||||||
|
- name: acl
|
||||||
|
config:
|
||||||
|
hide_groups_header: true
|
||||||
|
allow:
|
||||||
|
- admin
|
||||||
|
- anon
|
||||||
|
|
||||||
|
- name: meta
|
||||||
|
url: http://meta:8080/
|
||||||
|
routes:
|
||||||
|
- name: meta
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /pg/
|
||||||
|
plugins:
|
||||||
|
- name: key-auth
|
||||||
|
config:
|
||||||
|
hide_credentials: false
|
||||||
|
- name: acl
|
||||||
|
config:
|
||||||
|
hide_groups_header: true
|
||||||
|
allow:
|
||||||
|
- admin
|
||||||
|
KONG_EOF
|
||||||
|
|
||||||
|
log_info "Kong configuration generated with production API keys"
|
||||||
|
}
|
||||||
|
|
||||||
# Deploy/start services
|
# Deploy/start services
|
||||||
deploy() {
|
deploy() {
|
||||||
log_info "Deploying Monaco USA Portal..."
|
log_info "Deploying Monaco USA Portal..."
|
||||||
|
|
@ -151,8 +351,11 @@ deploy() {
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Build and start
|
# Generate Kong config with production API keys
|
||||||
docker compose -f $COMPOSE_FILE -p $PROJECT_NAME build --no-cache portal
|
generate_kong_config
|
||||||
|
|
||||||
|
# Pull latest portal image and start all services
|
||||||
|
docker compose -f $COMPOSE_FILE -p $PROJECT_NAME pull portal
|
||||||
docker compose -f $COMPOSE_FILE -p $PROJECT_NAME up -d
|
docker compose -f $COMPOSE_FILE -p $PROJECT_NAME up -d
|
||||||
|
|
||||||
log_info "Deployment complete!"
|
log_info "Deployment complete!"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,218 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Generate Kong configuration with production API keys
|
||||||
|
# Usage: ./scripts/generate-kong-config.sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Load environment variables if .env exists
|
||||||
|
if [ -f .env ]; then
|
||||||
|
export $(grep -v '^#' .env | xargs)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check required variables
|
||||||
|
if [ -z "$ANON_KEY" ] || [ -z "$SERVICE_ROLE_KEY" ]; then
|
||||||
|
echo "Error: ANON_KEY and SERVICE_ROLE_KEY must be set in .env"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the Kong configuration
|
||||||
|
cat > supabase/docker/kong.yml << KONG_EOF
|
||||||
|
_format_version: "2.1"
|
||||||
|
_transform: true
|
||||||
|
|
||||||
|
###
|
||||||
|
### Consumers / Users
|
||||||
|
###
|
||||||
|
consumers:
|
||||||
|
- username: ANON
|
||||||
|
keyauth_credentials:
|
||||||
|
- key: ${ANON_KEY}
|
||||||
|
- username: SERVICE_ROLE
|
||||||
|
keyauth_credentials:
|
||||||
|
- key: ${SERVICE_ROLE_KEY}
|
||||||
|
|
||||||
|
###
|
||||||
|
### Access Control Lists
|
||||||
|
###
|
||||||
|
acls:
|
||||||
|
- consumer: ANON
|
||||||
|
group: anon
|
||||||
|
- consumer: SERVICE_ROLE
|
||||||
|
group: admin
|
||||||
|
|
||||||
|
###
|
||||||
|
### API Routes
|
||||||
|
###
|
||||||
|
services:
|
||||||
|
## Redirect /auth/verify to SvelteKit app for email links
|
||||||
|
- name: auth-verify-redirect
|
||||||
|
url: http://portal:3000/auth/verify
|
||||||
|
routes:
|
||||||
|
- name: auth-verify-redirect
|
||||||
|
strip_path: false
|
||||||
|
paths:
|
||||||
|
- /auth/verify
|
||||||
|
preserve_host: false
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
|
||||||
|
## Auth Service (GoTrue)
|
||||||
|
- name: auth-v1-open
|
||||||
|
url: http://auth:9999/verify
|
||||||
|
routes:
|
||||||
|
- name: auth-v1-open
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /auth/v1/verify
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
|
||||||
|
- name: auth-v1-open-callback
|
||||||
|
url: http://auth:9999/callback
|
||||||
|
routes:
|
||||||
|
- name: auth-v1-open-callback
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /auth/v1/callback
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
|
||||||
|
- name: auth-v1-open-authorize
|
||||||
|
url: http://auth:9999/authorize
|
||||||
|
routes:
|
||||||
|
- name: auth-v1-open-authorize
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /auth/v1/authorize
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
|
||||||
|
- name: auth-v1
|
||||||
|
url: http://auth:9999/
|
||||||
|
routes:
|
||||||
|
- name: auth-v1
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /auth/v1/
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
- name: key-auth
|
||||||
|
config:
|
||||||
|
hide_credentials: false
|
||||||
|
- name: acl
|
||||||
|
config:
|
||||||
|
hide_groups_header: true
|
||||||
|
allow:
|
||||||
|
- admin
|
||||||
|
- anon
|
||||||
|
|
||||||
|
## REST Service (PostgREST)
|
||||||
|
- name: rest-v1
|
||||||
|
url: http://rest:3000/
|
||||||
|
routes:
|
||||||
|
- name: rest-v1
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /rest/v1/
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
- name: key-auth
|
||||||
|
config:
|
||||||
|
hide_credentials: false
|
||||||
|
- name: acl
|
||||||
|
config:
|
||||||
|
hide_groups_header: true
|
||||||
|
allow:
|
||||||
|
- admin
|
||||||
|
- anon
|
||||||
|
|
||||||
|
## Realtime Service
|
||||||
|
- name: realtime-v1-ws
|
||||||
|
url: http://realtime:4000/socket
|
||||||
|
routes:
|
||||||
|
- name: realtime-v1-ws
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /realtime/v1/websocket
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
- name: key-auth
|
||||||
|
config:
|
||||||
|
hide_credentials: false
|
||||||
|
- name: acl
|
||||||
|
config:
|
||||||
|
hide_groups_header: true
|
||||||
|
allow:
|
||||||
|
- admin
|
||||||
|
- anon
|
||||||
|
|
||||||
|
- name: realtime-v1
|
||||||
|
url: http://realtime:4000/
|
||||||
|
routes:
|
||||||
|
- name: realtime-v1
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /realtime/v1/
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
- name: key-auth
|
||||||
|
config:
|
||||||
|
hide_credentials: false
|
||||||
|
- name: acl
|
||||||
|
config:
|
||||||
|
hide_groups_header: true
|
||||||
|
allow:
|
||||||
|
- admin
|
||||||
|
- anon
|
||||||
|
|
||||||
|
## Storage Service - Public objects (no auth required)
|
||||||
|
- name: storage-v1-public
|
||||||
|
url: http://storage:5000/object/public
|
||||||
|
routes:
|
||||||
|
- name: storage-v1-public
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /storage/v1/object/public
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
|
||||||
|
## Storage Service - All other operations (auth required)
|
||||||
|
- name: storage-v1
|
||||||
|
url: http://storage:5000/
|
||||||
|
routes:
|
||||||
|
- name: storage-v1
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /storage/v1/
|
||||||
|
plugins:
|
||||||
|
- name: cors
|
||||||
|
- name: key-auth
|
||||||
|
config:
|
||||||
|
hide_credentials: false
|
||||||
|
- name: acl
|
||||||
|
config:
|
||||||
|
hide_groups_header: true
|
||||||
|
allow:
|
||||||
|
- admin
|
||||||
|
- anon
|
||||||
|
|
||||||
|
## PostgreSQL Meta (for Studio)
|
||||||
|
- name: meta
|
||||||
|
url: http://meta:8080/
|
||||||
|
routes:
|
||||||
|
- name: meta
|
||||||
|
strip_path: true
|
||||||
|
paths:
|
||||||
|
- /pg/
|
||||||
|
plugins:
|
||||||
|
- name: key-auth
|
||||||
|
config:
|
||||||
|
hide_credentials: false
|
||||||
|
- name: acl
|
||||||
|
config:
|
||||||
|
hide_groups_header: true
|
||||||
|
allow:
|
||||||
|
- admin
|
||||||
|
KONG_EOF
|
||||||
|
|
||||||
|
echo "Kong configuration generated at supabase/docker/kong.yml"
|
||||||
Loading…
Reference in New Issue