feat: publish CodexPi contest snapshot
Some checks are pending
Qualité / tests (push) Waiting to run
Some checks are pending
Qualité / tests (push) Waiting to run
This commit is contained in:
177
docker-compose.yml
Normal file
177
docker-compose.yml
Normal file
@@ -0,0 +1,177 @@
|
||||
name: codexpi
|
||||
|
||||
x-app: &app
|
||||
image: ${CODEXPI_IMAGE:-codexpi-app:local}
|
||||
build:
|
||||
context: .
|
||||
target: production
|
||||
args:
|
||||
CODEX_VERSION: ${CODEX_VERSION:-latest}
|
||||
CLAUDE_CODE_VERSION: ${CLAUDE_CODE_VERSION:-latest}
|
||||
OPENCODE_VERSION: ${OPENCODE_VERSION:-latest}
|
||||
env_file:
|
||||
- .env
|
||||
restart: unless-stopped
|
||||
init: true
|
||||
user: "${PUID:-1000}:${PGID:-1000}"
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
cap_drop:
|
||||
- ALL
|
||||
read_only: true
|
||||
tmpfs:
|
||||
- /tmp:size=128m,mode=1777
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
depends_on:
|
||||
data-permissions:
|
||||
condition: service_completed_successfully
|
||||
|
||||
services:
|
||||
data-permissions:
|
||||
image: codexpi-app:local
|
||||
user: "0:0"
|
||||
restart: "no"
|
||||
read_only: true
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
cap_drop:
|
||||
- ALL
|
||||
cap_add:
|
||||
- CHOWN
|
||||
- DAC_OVERRIDE
|
||||
- FOWNER
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
entrypoint: ["sh", "-c"]
|
||||
command: ["chown -R \"$${PUID}:$${PGID}\" /app/data && chmod 700 /app/data"]
|
||||
environment:
|
||||
PUID: "${PUID:-1000}"
|
||||
PGID: "${PGID:-1000}"
|
||||
|
||||
django-web:
|
||||
<<: *app
|
||||
command: >-
|
||||
sh -c "python3 manage.py migrate --noinput &&
|
||||
python3 -m uvicorn django_ui.asgi:application --host 0.0.0.0 --port 8001 --proxy-headers --forwarded-allow-ips='*'"
|
||||
environment:
|
||||
CODEXPI_DATA_DIR: /app/data
|
||||
CODEXPI_COOKIE_SECURE: "${CODEXPI_COOKIE_SECURE:-false}"
|
||||
healthcheck:
|
||||
test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8001/api/bootstrap', timeout=3)"]
|
||||
interval: 15s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 20s
|
||||
|
||||
api:
|
||||
<<: *app
|
||||
# Codex workspace-write uses Bubblewrap, which creates an unprivileged user
|
||||
# namespace. Docker's default seccomp profile blocks that syscall before
|
||||
# Bubblewrap can apply its own (stricter) filesystem sandbox.
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
- seccomp:unconfined
|
||||
command: >-
|
||||
python3 -m uvicorn codexpi.main:app --app-dir /app/backend
|
||||
--host 0.0.0.0 --port 8000 --proxy-headers --forwarded-allow-ips='*'
|
||||
environment:
|
||||
CODEXPI_BASE_DIR: /app
|
||||
CODEXPI_DATA_DIR: /app/data
|
||||
CODEXPI_DATABASE: /app/data/codexpi.db
|
||||
CODEXPI_HOST: 0.0.0.0
|
||||
CODEXPI_PORT: 8000
|
||||
CODEXPI_AUTH_BACKEND: django
|
||||
CODEXPI_CONTAINERIZED: "true"
|
||||
CODEXPI_COOKIE_SECURE: "${CODEXPI_COOKIE_SECURE:-false}"
|
||||
CODEXPI_BROWSER_WEBDRIVER_URL: http://browser:4444
|
||||
CODEXPI_BROWSER_CONTAINER: codexpi-browser-1
|
||||
CODEXPI_BROWSER_SCREENSHOTS: /app/data/browser/screenshots
|
||||
CODEXPI_APP_STORE_AUTH_URL: "${CODEXPI_APP_STORE_AUTH_URL:-http://192.168.1.63:16002/auth/me}"
|
||||
HOME: /home/codex
|
||||
group_add:
|
||||
- "${DOCKER_GID:-998}"
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
- type: bind
|
||||
source: /home/config
|
||||
target: /home/config
|
||||
bind:
|
||||
propagation: rslave
|
||||
- ${CODEXPI_HOME:-/home/config}/.codex:/home/codex/.codex
|
||||
- ${CODEXPI_HOME:-/home/config}/.claude:/home/codex/.claude
|
||||
- ${CODEXPI_HOME:-/home/config}/.config/opencode:/home/codex/.config/opencode
|
||||
- ${CODEXPI_HOME:-/home/config}/.local/share/opencode:/home/codex/.local/share/opencode
|
||||
- ${CODEXPI_HOME:-/home/config}/.config/gh:/home/codex/.config/gh
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
healthcheck:
|
||||
test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/api/health', timeout=3)"]
|
||||
interval: 15s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 15s
|
||||
|
||||
browser:
|
||||
image: ${CODEXPI_BROWSER_IMAGE:-selenium/standalone-chromium:latest}
|
||||
command: ["/opt/bin/codexpi-browser-entrypoint"]
|
||||
restart: unless-stopped
|
||||
shm_size: "1gb"
|
||||
environment:
|
||||
SE_NODE_MAX_SESSIONS: "1"
|
||||
SE_VNC_NO_PASSWORD: "true"
|
||||
SE_SCREEN_WIDTH: "1440"
|
||||
SE_SCREEN_HEIGHT: "900"
|
||||
SE_SCREEN_DEPTH: "24"
|
||||
volumes:
|
||||
- browser-home:/home/seluser
|
||||
- ./scripts/browser-entrypoint.sh:/opt/bin/codexpi-browser-entrypoint:ro
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
nginx:
|
||||
image: nginx:1.27-alpine
|
||||
restart: unless-stopped
|
||||
user: "101:101"
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
django_upstream="$${CODEXPI_DJANGO_UPSTREAM:-django-web}"
|
||||
api_upstream="$${CODEXPI_API_UPSTREAM:-api}"
|
||||
echo "Attente de Django ($${django_upstream}) et FastAPI ($${api_upstream})…"
|
||||
until wget -qO- "http://$${django_upstream}:8001/api/bootstrap" >/dev/null 2>&1 \
|
||||
&& wget -qO- "http://$${api_upstream}:8000/api/health" >/dev/null 2>&1; do
|
||||
sleep 2
|
||||
done
|
||||
echo "upstream django_ui { server $${django_upstream}:8001; }" > /tmp/codexpi-upstreams.conf
|
||||
echo "upstream fastapi_api { server $${api_upstream}:8000; }" >> /tmp/codexpi-upstreams.conf
|
||||
cat /tmp/codexpi-upstreams.conf
|
||||
exec nginx -g 'daemon off;'
|
||||
read_only: true
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
cap_drop:
|
||||
- ALL
|
||||
tmpfs:
|
||||
- /tmp:size=16m,mode=1777
|
||||
- /var/cache/nginx:size=16m,mode=0755
|
||||
volumes:
|
||||
- ./deploy/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
ports:
|
||||
- "${CODEXPI_BIND_ADDRESS:-0.0.0.0}:${CODEXPI_PROXY_PORT:-8765}:8080"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:8080/proxy-health"]
|
||||
interval: 15s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 30s
|
||||
depends_on:
|
||||
django-web:
|
||||
condition: service_healthy
|
||||
api:
|
||||
condition: service_healthy
|
||||
browser:
|
||||
condition: service_started
|
||||
|
||||
volumes:
|
||||
browser-home:
|
||||
Reference in New Issue
Block a user