2.0.0 Production-RC
release-tag / release-image (push) Has been cancelled

This commit is contained in:
2026-07-24 07:23:59 +02:00
parent db817eabe4
commit 4e2c648ede
80 changed files with 2793 additions and 8111 deletions
+178
View File
@@ -0,0 +1,178 @@
# Dedicated licensed bulk service. Keep the Service internal unless an authenticated
# API gateway is placed in front of it.
apiVersion: apps/v1
kind: Deployment
metadata:
name: ai-disclosure-bulk
labels:
app.kubernetes.io/name: ai-disclosure-bulk
app.kubernetes.io/version: "2.0.0"
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
selector:
matchLabels:
app.kubernetes.io/name: ai-disclosure-bulk
template:
metadata:
labels:
app.kubernetes.io/name: ai-disclosure-bulk
app.kubernetes.io/version: "2.0.0"
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
prometheus.io/path: /metrics
spec:
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: bulk
image: ghcr.io/REPLACE_ME/ai-disclosure-standard-bulk:2.0.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8080
env:
- name: BASE_URL
value: http://ai-disclosure-bulk
- name: OUTPUT_BASE_URL
value: https://ai.example.org
- name: DEFAULT_LANGUAGE
value: de
- name: SERVICE_MODE
value: bulk
- name: REQUIRE_LICENSE
value: "true"
- name: API_ALLOWED_ORIGIN
value: ""
- name: LICENSE_TOKEN_FILE
value: /run/secrets/license/token
- name: LICENSE_MODE
value: hybrid
- name: LICENSE_SERVER_URL
value: https://licenses.example.org
- name: LICENSE_INSTANCE_ID
valueFrom:
fieldRef:
fieldPath: metadata.uid
- name: LICENSE_CACHE_FILE
value: /data/license-lease.json
- name: BULK_REQUIRE_API_KEY
value: "true"
- name: BULK_API_KEY_FILE
value: /run/secrets/bulk/key
- name: BULK_MAX_ITEMS
value: "500"
- name: BULK_MAX_BODY_BYTES
value: "4194304"
volumeMounts:
- name: license-cache
mountPath: /data
- name: license-token
mountPath: /run/secrets/license
readOnly: true
- name: bulk-api-key
mountPath: /run/secrets/bulk
readOnly: true
resources:
requests:
cpu: 50m
memory: 32Mi
limits:
cpu: "1"
memory: 192Mi
readinessProbe:
httpGet:
path: /readyz
port: http
initialDelaySeconds: 2
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 3
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumes:
- name: license-cache
emptyDir: {}
- name: license-token
secret:
secretName: ai-disclosure-commercial
items:
- key: license-token
path: token
- name: bulk-api-key
secret:
secretName: ai-disclosure-commercial
items:
- key: bulk-api-key
path: key
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: ai-disclosure-bulk
---
apiVersion: v1
kind: Service
metadata:
name: ai-disclosure-bulk
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: ai-disclosure-bulk
ports:
- name: http
port: 80
targetPort: http
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: ai-disclosure-bulk
spec:
minAvailable: 2
selector:
matchLabels:
app.kubernetes.io/name: ai-disclosure-bulk
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: ai-disclosure-bulk
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: ai-disclosure-bulk
minReplicas: 3
maxReplicas: 20
behavior:
scaleDown:
stabilizationWindowSeconds: 300
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 65
+28 -33
View File
@@ -4,6 +4,7 @@ metadata:
name: ai-disclosure
labels:
app.kubernetes.io/name: ai-disclosure
app.kubernetes.io/version: "2.0.0"
spec:
replicas: 3
strategy:
@@ -18,14 +19,20 @@ spec:
metadata:
labels:
app.kubernetes.io/name: ai-disclosure
app.kubernetes.io/version: "2.0.0"
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
prometheus.io/path: /metrics
spec:
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: ghcr.io/REPLACE_ME/ai-disclosure-standard:1.8.0
image: ghcr.io/REPLACE_ME/ai-disclosure-standard:2.0.0
imagePullPolicy: IfNotPresent
ports:
- name: http
@@ -37,42 +44,18 @@ spec:
value: AI Usage Disclosure
- name: CONTACT_URL
value: https://b1tsblog.org/page/ai
- name: SALES_URL
value: https://b1tsblog.org/page/ai
- name: DEFAULT_LANGUAGE
value: de
- name: TRUST_PROXY
value: "false"
- name: LOG_CLIENT_IP
value: "false"
- name: ENABLE_HSTS
value: "true"
- name: METRICS_ENABLED
value: "false"
# Replace the following values before deployment. LEGAL_STRICT
# deliberately prevents accidental public startup with placeholders.
- name: LEGAL_STRICT
value: "true"
- name: LEGAL_NAME
value: REPLACE_ME
- name: LEGAL_ADDRESS
value: REPLACE_ME
- name: LEGAL_EMAIL
value: REPLACE_ME
- name: HOSTING_PROVIDER
value: REPLACE_ME
- name: LOG_RETENTION
value: REPLACE_ME
- name: CONSUMER_DISPUTE_STATUS
value: REPLACE_ME
- name: LICENSE_TOKEN
valueFrom:
secretKeyRef:
name: ai-disclosure-license
key: token
optional: true
- name: SERVICE_MODE
value: full
- name: API_ALLOWED_ORIGIN
value: "*"
- name: LICENSE_TOKEN_FILE
value: /run/secrets/license/token
- name: LICENSE_MODE
value: offline
value: hybrid
- name: LICENSE_SERVER_URL
value: ""
- name: LICENSE_INSTANCE_ID
@@ -81,13 +64,18 @@ spec:
fieldPath: metadata.uid
- name: LICENSE_CACHE_FILE
value: /data/license-lease.json
- name: WHITE_LABEL
value: "false"
volumeMounts:
- name: license-cache
mountPath: /data
- name: license-token
mountPath: /run/secrets/license
readOnly: true
resources:
requests:
cpu: 25m
memory: 24Mi
memory: 32Mi
limits:
cpu: 500m
memory: 128Mi
@@ -115,6 +103,13 @@ spec:
volumes:
- name: license-cache
emptyDir: {}
- name: license-token
secret:
secretName: ai-disclosure-license
optional: true
items:
- key: token
path: token
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
-81
View File
@@ -1,81 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: universal-license-server
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: universal-license-server
template:
metadata:
labels:
app.kubernetes.io/name: universal-license-server
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: server
image: ghcr.io/REPLACE_ME/universal-license-server:1.5.0
ports:
- name: http
containerPort: 8091
env:
- name: LICENSE_SERVER_ADDRESS
value: :8091
- name: LICENSE_SERVER_DATA
value: /data/licenses.json
- name: LICENSE_TRUST_STORE_FILE
value: /config/trusted-keys.json
- name: LEASE_SIGNING_KEY_ID
value: lease-2026
- name: LEASE_SIGNING_PRIVATE_KEY
valueFrom:
secretKeyRef:
name: universal-license-secrets
key: lease-private-key
- name: LICENSE_SERVER_ADMIN_TOKEN
valueFrom:
secretKeyRef:
name: universal-license-secrets
key: admin-token
volumeMounts:
- name: data
mountPath: /data
- name: trust-store
mountPath: /config
readOnly: true
readinessProbe:
httpGet:
path: /healthz
port: http
livenessProbe:
httpGet:
path: /healthz
port: http
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumes:
- name: data
persistentVolumeClaim:
claimName: universal-license-data
- name: trust-store
configMap:
name: universal-license-trust-store
---
apiVersion: v1
kind: Service
metadata:
name: universal-license-server
spec:
selector:
app.kubernetes.io/name: universal-license-server
ports:
- name: http
port: 80
targetPort: http
+61
View File
@@ -0,0 +1,61 @@
version: "3.9"
services:
bulk:
image: ghcr.io/REPLACE_ME/ai-disclosure-standard-bulk:2.0.0
environment:
BASE_URL: http://bulk:8080
OUTPUT_BASE_URL: https://ai.example.org
DEFAULT_LANGUAGE: de
SERVICE_MODE: bulk
API_ALLOWED_ORIGIN: ""
LICENSE_TOKEN_FILE: /run/secrets/license_token
LICENSE_MODE: "${LICENSE_MODE:-hybrid}"
LICENSE_SERVER_URL: "${LICENSE_SERVER_URL:-https://licenses.example.org}"
LICENSE_INSTANCE_ID: "${LICENSE_INSTANCE_ID:-swarm-bulk}"
LICENSE_CACHE_FILE: /data/license-lease.json
REQUIRE_LICENSE: "true"
BULK_REQUIRE_API_KEY: "true"
BULK_API_KEY_FILE: /run/secrets/bulk_api_key
BULK_MAX_ITEMS: "${BULK_MAX_ITEMS:-500}"
BULK_MAX_BODY_BYTES: "${BULK_MAX_BODY_BYTES:-4194304}"
secrets:
- license_token
- bulk_api_key
networks: [internal]
volumes:
- bulk-license-cache:/data
read_only: true
tmpfs:
- /tmp:size=16m,mode=1777
cap_drop: [ALL]
healthcheck:
test: ["CMD", "/ai-disclosure", "--healthcheck"]
interval: 15s
timeout: 3s
retries: 3
start_period: 5s
deploy:
replicas: 3
update_config:
order: start-first
parallelism: 1
restart_policy:
condition: on-failure
resources:
reservations:
cpus: "0.05"
memory: 32M
limits:
cpus: "1.0"
memory: 192M
secrets:
license_token:
external: true
bulk_api_key:
external: true
networks:
internal:
driver: overlay
attachable: false
volumes:
bulk-license-cache:
+8 -19
View File
@@ -1,43 +1,33 @@
version: "3.9"
services:
app:
image: ghcr.io/REPLACE_ME/ai-disclosure-standard:1.8.0
image: ghcr.io/REPLACE_ME/ai-disclosure-standard:2.0.0
environment:
BASE_URL: https://ai.example.org
PUBLIC_NAME: AI Usage Disclosure
CONTACT_URL: https://b1tsblog.org/page/ai
SALES_URL: "${SALES_URL:-https://b1tsblog.org/page/ai}"
DEFAULT_LANGUAGE: de
TRUST_PROXY: "false"
LOG_CLIENT_IP: "false"
ENABLE_HSTS: "true"
METRICS_ENABLED: "false"
LEGAL_STRICT: "${LEGAL_STRICT:-true}"
LEGAL_NAME: "${LEGAL_NAME:-REPLACE_ME}"
LEGAL_ADDRESS: "${LEGAL_ADDRESS:-REPLACE_ME}"
LEGAL_EMAIL: "${LEGAL_EMAIL:-REPLACE_ME}"
HOSTING_PROVIDER: "${HOSTING_PROVIDER:-REPLACE_ME}"
LOG_RETENTION: "${LOG_RETENTION:-REPLACE_ME}"
CONSUMER_DISPUTE_STATUS: "${CONSUMER_DISPUTE_STATUS:-REPLACE_ME}"
TRUST_PROXY: "true"
SERVICE_MODE: full
API_ALLOWED_ORIGIN: "*"
LICENSE_TOKEN: "${LICENSE_TOKEN:-}"
LICENSE_MODE: "${LICENSE_MODE:-offline}"
LICENSE_SERVER_URL: "${LICENSE_SERVER_URL:-}"
LICENSE_INSTANCE_ID: "${LICENSE_INSTANCE_ID:-swarm}"
LICENSE_CACHE_FILE: /data/license-lease.json
WHITE_LABEL: "${WHITE_LABEL:-false}"
ports:
- target: 8080
published: 8080
protocol: tcp
mode: ingress
networks:
- public
networks: [public]
volumes:
- license-cache:/data
read_only: true
tmpfs:
- /tmp:size=16m,mode=1777
cap_drop:
- ALL
cap_drop: [ALL]
healthcheck:
test: ["CMD", "/ai-disclosure", "--healthcheck"]
interval: 15s
@@ -67,7 +57,7 @@ services:
resources:
reservations:
cpus: "0.05"
memory: 24M
memory: 32M
limits:
cpus: "0.50"
memory: 128M
@@ -75,6 +65,5 @@ networks:
public:
driver: overlay
attachable: true
volumes:
license-cache: