name: ${COMPOSE_PROJECT_NAME:-zhixing-system-dev} services: postgres: image: postgres:16-alpine ports: - "127.0.0.1:5433:5432" environment: POSTGRES_DB: ${ZHIXING_POSTGRES_DB:-zhixing} POSTGRES_PASSWORD: ${ZHIXING_POSTGRES_PASSWORD:-zhixing} POSTGRES_USER: ${ZHIXING_POSTGRES_USER:-zhixing} healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s timeout: 3s retries: 10 volumes: - postgres-data:/var/lib/postgresql/data server: build: context: ./zhixing-server target: development command: ["uv", "run", "uvicorn", "zhixing_server.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] depends_on: postgres: condition: service_healthy environment: ZHIXING_APP_ENV: ${ZHIXING_APP_ENV:-development} ZHIXING_DATABASE_URL: ${ZHIXING_DATABASE_URL:-postgresql://zhixing:zhixing@postgres:5432/zhixing} ZHIXING_LOG_LEVEL: ${ZHIXING_LOG_LEVEL:-INFO} ZHIXING_MARKET_DATA_CSV_ROOT: /app/data/market-data ZHIXING_MARKET_DATA_COVERAGE_THRESHOLD: ${ZHIXING_MARKET_DATA_COVERAGE_THRESHOLD:-0.99} ZHIXING_MARKET_DATA_MAX_WORKERS: ${ZHIXING_MARKET_DATA_MAX_WORKERS:-8} ZHIXING_MARKET_DATA_MAX_RETRIES: ${ZHIXING_MARKET_DATA_MAX_RETRIES:-3} ZHIXING_MARKET_DATA_RETRY_BACKOFF_SECONDS: ${ZHIXING_MARKET_DATA_RETRY_BACKOFF_SECONDS:-1.0} ZHIXING_MARKET_DATA_REQUEST_INTERVAL_SECONDS: ${ZHIXING_MARKET_DATA_REQUEST_INTERVAL_SECONDS:-0.2} ZHIXING_MARKET_DATA_ADVISORY_LOCK_KEY: ${ZHIXING_MARKET_DATA_ADVISORY_LOCK_KEY:-7380521} ZHIXING_SELECTION_MAX_WORKERS: ${ZHIXING_SELECTION_MAX_WORKERS:-4} ZHIXING_SELECTION_BATCH_SIZE: ${ZHIXING_SELECTION_BATCH_SIZE:-200} ZHIXING_TUSHARE_TOKEN: ${ZHIXING_TUSHARE_TOKEN:-} init: true ports: - "${ZHIXING_SERVER_PORT:-8000}:8000" volumes: - ./zhixing-server:/app - market-data:/app/data/market-data - server-venv:/app/.venv healthcheck: test: - CMD - python - -c - "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/healthz')" interval: 5s timeout: 3s retries: 10 start_period: 5s web: build: context: ./zhixing-web target: development depends_on: server: condition: service_healthy environment: VITE_DEV_API_TARGET: http://server:8000 init: true ports: - "${ZHIXING_WEB_PORT:-5555}:5173" volumes: - ./zhixing-web:/app - web-node-modules:/app/node_modules migrate: profiles: ["jobs"] build: context: ./zhixing-server target: development command: ["uv", "run", "alembic", "upgrade", "head"] depends_on: postgres: condition: service_healthy environment: ZHIXING_DATABASE_URL: ${ZHIXING_DATABASE_URL:-postgresql://zhixing:zhixing@postgres:5432/zhixing} volumes: - ./zhixing-server:/app - server-venv:/app/.venv market-sync: profiles: ["jobs"] build: context: ./zhixing-server target: development command: ["uv", "run", "market-data-sync"] depends_on: migrate: condition: service_completed_successfully environment: ZHIXING_DATABASE_URL: ${ZHIXING_DATABASE_URL:-postgresql://zhixing:zhixing@postgres:5432/zhixing} ZHIXING_MARKET_DATA_CSV_ROOT: /app/data/market-data ZHIXING_MARKET_DATA_COVERAGE_THRESHOLD: ${ZHIXING_MARKET_DATA_COVERAGE_THRESHOLD:-0.99} ZHIXING_MARKET_DATA_MAX_WORKERS: ${ZHIXING_MARKET_DATA_MAX_WORKERS:-8} ZHIXING_MARKET_DATA_MAX_RETRIES: ${ZHIXING_MARKET_DATA_MAX_RETRIES:-3} ZHIXING_MARKET_DATA_RETRY_BACKOFF_SECONDS: ${ZHIXING_MARKET_DATA_RETRY_BACKOFF_SECONDS:-1.0} ZHIXING_MARKET_DATA_REQUEST_INTERVAL_SECONDS: ${ZHIXING_MARKET_DATA_REQUEST_INTERVAL_SECONDS:-0.2} ZHIXING_MARKET_DATA_ADVISORY_LOCK_KEY: ${ZHIXING_MARKET_DATA_ADVISORY_LOCK_KEY:-7380521} ZHIXING_TUSHARE_TOKEN: ${ZHIXING_TUSHARE_TOKEN:-} volumes: - ./zhixing-server:/app - market-data:/app/data/market-data - server-venv:/app/.venv volumes: market-data: postgres-data: server-venv: web-node-modules: