forked from HM2899/grokcli-2api
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
148 lines (144 loc) · 5.86 KB
/
Copy pathdocker-compose.yml
File metadata and controls
148 lines (144 loc) · 5.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
services:
# Redis / Postgres are internal-only (no host port publish).
# App reaches them via the compose network: redis:6379 / postgres:5432.
redis:
image: redis:7-alpine
container_name: grokcli-2api-redis
command: ["redis-server", "--save", "", "--appendonly", "no"]
environment:
TZ: "${TZ:-Asia/Shanghai}"
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 10
postgres:
image: postgres:16-alpine
container_name: grokcli-2api-postgres
environment:
TZ: "${TZ:-Asia/Shanghai}"
PGTZ: "${TZ:-Asia/Shanghai}"
POSTGRES_USER: grok2api
POSTGRES_PASSWORD: grok2api
POSTGRES_DB: grok2api
volumes:
- grok2api_pg:/var/lib/postgresql/data
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U grok2api -d grok2api"]
interval: 5s
timeout: 5s
retries: 10
# Single app container: API + inline Turnstile Solver (same process tree)
grokcli-2api:
build:
context: .
dockerfile: Dockerfile
image: grokcli-2api:local
container_name: grokcli-2api
env_file:
- path: .env
required: false
ports:
# Only the app API is published. Postgres/Redis stay internal-only
# (compose network). Inline Turnstile Solver listens on container
# loopback 127.0.0.1:5072 and is NOT published to the host.
- "3000:3000"
- "40081:40081"
shm_size: "1gb"
security_opt:
- seccomp:unconfined
environment:
TZ: "${TZ:-Asia/Shanghai}"
GROK2API_HOST: "0.0.0.0"
GROK2API_PORT: "40081"
GROK2API_OPEN_BROWSER: "0"
GROK2API_TOKEN_MAINTAIN: "1"
GROK2API_MODEL_HEALTH: "1"
GROK2API_REASONING_COMPAT: "off"
GROK2API_STORE_BACKEND: "hybrid"
# Multi-worker: default 2 (enough for hybrid; override via .env for large hosts)
GROK2API_WORKERS: "${GROK2API_WORKERS:-2}"
# In-stack service DNS (do not use 127.0.0.1 here)
REDIS_URL: "redis://redis:6379/0"
GROK2API_REDIS_URL: "redis://redis:6379/0"
DATABASE_URL: "postgresql://grok2api:grok2api@postgres:5432/grok2api"
GROK2API_DATABASE_URL: "postgresql://grok2api:grok2api@postgres:5432/grok2api"
# Inline local Turnstile Solver (same container, Python captcha)
GROK2API_CAPTCHA_PROVIDER: "${GROK2API_CAPTCHA_PROVIDER:-local}"
CAPTCHA_PROVIDER: "${CAPTCHA_PROVIDER:-local}"
GROK2API_LOCAL_SOLVER_URL: "${GROK2API_LOCAL_SOLVER_URL:-http://127.0.0.1:5072}"
LOCAL_SOLVER_URL: "${LOCAL_SOLVER_URL:-http://127.0.0.1:5072}"
GROK2API_INLINE_SOLVER: "${GROK2API_INLINE_SOLVER:-1}"
TURNSTILE_HOST: "127.0.0.1"
TURNSTILE_PORT: "5072"
# Align with registration concurrency (default 3)
GROK2API_REG_CONCURRENCY: "${GROK2API_REG_CONCURRENCY:-3}"
TURNSTILE_THREAD: "${TURNSTILE_THREAD:-${GROK2API_REG_CONCURRENCY:-3}}"
TURNSTILE_BROWSER_TYPE: "${TURNSTILE_BROWSER_TYPE:-camoufox}"
# Idle memory: warm browsers only when solving captcha; reclaim after quiet period
TURNSTILE_LAZY: "${TURNSTILE_LAZY:-1}"
TURNSTILE_IDLE_SEC: "${TURNSTILE_IDLE_SEC:-180}"
# Go is the main process; Python only runs registration/SSO/captcha sidecars.
GROK2API_RUNTIME: "${GROK2API_RUNTIME:-go}"
GROK2API_GO_PUBLIC_READ: "${GROK2API_GO_PUBLIC_READ:-1}"
GROK2API_GO_CHAT: "${GROK2API_GO_CHAT:-1}"
GROK2API_GO_MESSAGES: "${GROK2API_GO_MESSAGES:-1}"
GROK2API_GO_RESPONSES: "${GROK2API_GO_RESPONSES:-1}"
GROK2API_GO_ADMIN_READ: "${GROK2API_GO_ADMIN_READ:-1}"
GROK2API_GO_ADMIN_WRITE: "${GROK2API_GO_ADMIN_WRITE:-1}"
GROK2API_GO_MAINTAINER: "${GROK2API_GO_MAINTAINER:-1}"
GROK2API_GO_WRITES: "${GROK2API_GO_WRITES:-1}"
GROK2API_GO_OWNERSHIP_MODE: "${GROK2API_GO_OWNERSHIP_MODE:-all}"
# Python registration + SSO sidecar (used when GROK2API_RUNTIME=go)
GROK2API_REGISTRATION_SIDECAR: "${GROK2API_REGISTRATION_SIDECAR:-1}"
GROK2API_REGISTRATION_HOST: "127.0.0.1"
GROK2API_REGISTRATION_PORT: "18070"
GROK2API_REGISTRATION_SERVICE_URL: "${GROK2API_REGISTRATION_SERVICE_URL:-http://127.0.0.1:18070}"
GROK2API_REGISTRATION_TOKEN: "${GROK2API_REGISTRATION_TOKEN:-}"
PYTHONPATH: "/app:/app/grok-build-auth"
# In-container hot-update (docker.sock + /compose mount; no host watcher)
GROK2API_HOT_UPDATE_MODE: "${GROK2API_HOT_UPDATE_MODE:-docker}"
GROK2API_COMPOSE_DIR: "${GROK2API_COMPOSE_DIR:-/compose}"
GROK2API_DOCKER_SERVICE: "${GROK2API_DOCKER_SERVICE:-grokcli-2api}"
GROK2API_GHCR_IMAGE: "${GROK2API_GHCR_IMAGE:-ghcr.io/hm2899/grokcli-2api}"
healthcheck:
# $$ keeps substitution inside the container so override ports (e.g. 40081) work
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:$${GROK2API_PORT:-3000}/health >/dev/null"]
interval: 10s
timeout: 3s
retries: 12
start_period: 90s
volumes:
- ./data:/app/data
- ./turnstile-solver/logs:/app/turnstile-solver/logs
# In-container hot-update: docker CLI talks to host docker daemon.
- /var/run/docker.sock:/var/run/docker.sock
# Compose project for force-recreate (override file written under /compose).
- ./:/compose
depends_on:
redis:
condition: service_healthy
postgres:
condition: service_healthy
# Explicit aliases so external stacks (sub2api etc.) can resolve us after recreate
networks:
default:
aliases:
- grokcli-2api
restart: unless-stopped
volumes:
grok2api_pg:
# Fixed project network name so other compose stacks can join as external:
# networks:
# grokcli-net:
# name: grokcli-2api_default
# external: true
# Downstream DNS: http://grokcli-2api:<port>/v1
networks:
default:
name: grokcli-2api_default
driver: bridge
labels:
com.grokcli-2api.network: "shared-upstream"