Initial AlphaPulse implementation: news crawler and Binance klines
- Backend (FastAPI, SQLAlchemy 2, Alembic): single-admin cookie auth, news/crawler/market APIs with SSE and WebSocket streaming - Crawler (Scrapy + Scrapy-Redis): wscn_news, wscn_live, cls_depth, cls_telegraph spiders, idempotent upserts with revisions, raw response archiving, per-source subprocess supervision, restart and backoff - Market worker: full-history Binance spot/USD-M kline backfill, realtime WS stream, hourly and on-reconnect catch-up - Frontend (Vue 3, Element Plus, UnoCSS, KLineChart): news feed, crawler console with live logs, Binance-style chart page - Deploy: docker compose, nginx site, migrate and daily backup scripts
This commit is contained in:
commit
aabc81ba5b
88 files changed
+12603
No files matched your search
@@ -0,0 +1,8 @@
|
||||
# 复制为仓库根目录 .env(chmod 600);只有这一套配置
|
||||
DATABASE_URL=postgresql+asyncpg://alphapulse:<密码>@postgres:5432/alphapulse
|
||||
# DB 14 与 AFFiNE 共用,key 一律带 ap: 前缀
|
||||
REDIS_URL=redis://:<密码>@redis:6379/14
|
||||
JWT_SECRET=<openssl rand -hex 32>
|
||||
ADMIN_USERNAME=admin
|
||||
# 哈希含 $,必须用单引号包住,否则 compose 会做变量替换
|
||||
ADMIN_PASSWORD_HASH='<python -m alphapulse.core.auth hash-password 的输出>'
|
||||
@@ -0,0 +1,8 @@
|
||||
FROM python:3.13-slim
|
||||
COPY --from=ghcr.io/astral-sh/uv:0.12 /uv /usr/local/bin/uv
|
||||
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy UV_PROJECT_ENVIRONMENT=/opt/venv PATH=/opt/venv/bin:$PATH
|
||||
WORKDIR /app
|
||||
COPY pyproject.toml uv.lock ./
|
||||
RUN uv sync --locked --no-dev --no-install-project
|
||||
COPY . .
|
||||
RUN uv sync --locked --no-dev
|
||||
@@ -0,0 +1,11 @@
|
||||
FROM node:24-alpine AS build
|
||||
RUN corepack enable
|
||||
WORKDIR /app
|
||||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
||||
RUN pnpm install --frozen-lockfile
|
||||
COPY . .
|
||||
RUN pnpm build
|
||||
|
||||
FROM nginx:alpine
|
||||
COPY --from=build /app/dist /usr/share/nginx/html
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
# 每日备份 alphapulse 库,保留最近 14 份;backrest 03:00 会把 /srv 整体备份到异地
|
||||
set -eu
|
||||
dir=/srv/AlphaPulse/backups/daily
|
||||
mkdir -p "$dir"
|
||||
target="$dir/alphapulse-$(date +%Y%m%d).dump"
|
||||
# 先写临时文件,成功后再改名,避免留下半截备份
|
||||
docker exec postgres pg_dump -U alphapulse -Fc alphapulse > "$target.tmp"
|
||||
mv "$target.tmp" "$target"
|
||||
ls -1t "$dir"/alphapulse-*.dump | tail -n +15 | xargs -r rm --
|
||||
echo "$(date '+%F %T') 备份完成:$target $(du -h "$target" | cut -f1)"
|
||||
@@ -0,0 +1,39 @@
|
||||
name: alphapulse
|
||||
|
||||
x-backend: &backend
|
||||
build:
|
||||
context: ../backend
|
||||
dockerfile: ../deploy/Dockerfile.backend
|
||||
image: alphapulse-backend
|
||||
env_file: ../.env
|
||||
restart: unless-stopped
|
||||
networks: [dev_default]
|
||||
|
||||
services:
|
||||
api:
|
||||
<<: *backend
|
||||
command: [uvicorn, alphapulse.api.main:app, --host, 0.0.0.0, --port, "8000", --proxy-headers, --forwarded-allow-ips, "*"]
|
||||
|
||||
crawler:
|
||||
<<: *backend
|
||||
command: [python, -m, alphapulse.crawler.manager]
|
||||
# 留时间给 scrapy 子进程优雅退出并刷完日志
|
||||
stop_grace_period: 30s
|
||||
|
||||
market:
|
||||
<<: *backend
|
||||
command: [python, -m, alphapulse.market.worker]
|
||||
|
||||
web:
|
||||
build:
|
||||
context: ../web
|
||||
dockerfile: ../deploy/Dockerfile.web
|
||||
restart: unless-stopped
|
||||
depends_on: [api]
|
||||
ports:
|
||||
- 127.0.0.1:21030:80
|
||||
networks: [dev_default]
|
||||
|
||||
networks:
|
||||
dev_default:
|
||||
external: true
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
# 迁移前先备份:只有一套环境,迁移即生产操作
|
||||
set -eu
|
||||
cd "$(dirname "$0")"
|
||||
mkdir -p ../backups
|
||||
dump="../backups/alphapulse-premigrate-$(date +%Y%m%d-%H%M%S).dump"
|
||||
docker exec postgres pg_dump -U alphapulse -Fc alphapulse > "$dump"
|
||||
echo "已备份:$dump"
|
||||
docker compose build api
|
||||
docker compose run --rm -T api alembic upgrade head
|
||||
@@ -0,0 +1,31 @@
|
||||
# alpha.134333.xyz -> AlphaPulse web 容器(127.0.0.1:21030)
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name alpha.134333.xyz;
|
||||
return 308 https://alpha.134333.xyz$request_uri;
|
||||
}
|
||||
server {
|
||||
listen 443 ssl;
|
||||
http2 on;
|
||||
server_name alpha.134333.xyz;
|
||||
|
||||
include /etc/nginx/snippets/ssl-134333.xyz.conf;
|
||||
include /etc/nginx/snippets/no-spider.conf;
|
||||
access_log /var/log/nginx/alpha.134333.xyz.log;
|
||||
error_log /var/log/nginx/alpha.134333.xyz.error.log warn;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:21030;
|
||||
proxy_http_version 1.1;
|
||||
# SSE 不缓冲;WebSocket 需要升级头
|
||||
proxy_buffering off;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $http_connection;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_read_timeout 1h;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user