Skip to content

Commit f0176c8

Browse files
author
Kevan
committed
Add GitHub Pages site, scaling infrastructure, CI/CD pipeline
- docs/index.html: Full GitHub Pages site (dark theme, phase cards, architecture flow) - .github/workflows/ci.yml: CI/CD with tests, linting, Pages deploy, Docker build - Dockerfile + docker-compose.yml: Multi-stage Docker with API, workers, PostgreSQL, Redis, IPFS - scaling/api.py: FastAPI REST layer exposing all 77 CLI commands as endpoints - scaling/worker_pool.py: Celery async task queue with scheduled jobs - scaling/db_migration.py: SQLite to PostgreSQL migration tool (33 tables) - scaling/config.py: Environment-aware configuration (dev/prod) - k8s/: Kubernetes manifests with HPA (auto-scale 2-10 worker pods) - requirements-scale.txt: Production dependencies (FastAPI, Celery, SQLAlchemy, Prometheus)
1 parent 5d40959 commit f0176c8

16 files changed

Lines changed: 3002 additions & 0 deletions

.github/workflows/ci.yml

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
name: CI / CD — Project Anchor
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
permissions:
10+
contents: read
11+
pages: write
12+
id-token: write
13+
14+
concurrency:
15+
group: "pages"
16+
cancel-in-progress: false
17+
18+
jobs:
19+
# ══════════════════════════════════════════════════════════════ TEST
20+
test:
21+
name: "🧪 Test Suite (284 tests)"
22+
runs-on: ubuntu-latest
23+
strategy:
24+
matrix:
25+
python-version: ["3.11", "3.12"]
26+
27+
steps:
28+
- uses: actions/checkout@v4
29+
30+
- name: Set up Python ${{ matrix.python-version }}
31+
uses: actions/setup-python@v5
32+
with:
33+
python-version: ${{ matrix.python-version }}
34+
cache: pip
35+
36+
- name: Install dependencies
37+
run: |
38+
python -m pip install --upgrade pip
39+
pip install -r requirements.txt
40+
pip install pytest pytest-cov
41+
42+
- name: Run tests
43+
env:
44+
PYTHONIOENCODING: utf-8
45+
PROJECT_ANCHOR_DB: ":memory:"
46+
run: |
47+
python -m pytest tests/ -v --tb=short --co -q 2>&1 | head -20
48+
python -m pytest tests/ -v --tb=short \
49+
--junitxml=test-results.xml \
50+
--cov=src --cov-report=xml --cov-report=term-missing
51+
52+
- name: Upload test results
53+
if: always()
54+
uses: actions/upload-artifact@v4
55+
with:
56+
name: test-results-py${{ matrix.python-version }}
57+
path: |
58+
test-results.xml
59+
coverage.xml
60+
61+
# ══════════════════════════════════════════════════════════════ LINT
62+
lint:
63+
name: "🔍 Code Quality"
64+
runs-on: ubuntu-latest
65+
steps:
66+
- uses: actions/checkout@v4
67+
68+
- name: Set up Python
69+
uses: actions/setup-python@v5
70+
with:
71+
python-version: "3.11"
72+
73+
- name: Install linters
74+
run: pip install flake8 black isort bandit
75+
76+
- name: Flake8
77+
run: flake8 src/ --max-line-length=120 --statistics --count || true
78+
79+
- name: Black (check)
80+
run: black --check --diff src/ tests/ || true
81+
82+
- name: isort (check)
83+
run: isort --check-only --diff src/ tests/ || true
84+
85+
- name: Bandit (security)
86+
run: bandit -r src/ -ll --skip B101 || true
87+
88+
# ══════════════════════════════════════════════════════════════ PAGES
89+
deploy-pages:
90+
name: "🌐 Deploy GitHub Pages"
91+
needs: test
92+
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
93+
runs-on: ubuntu-latest
94+
environment:
95+
name: github-pages
96+
url: ${{ steps.deployment.outputs.page_url }}
97+
98+
steps:
99+
- uses: actions/checkout@v4
100+
101+
- name: Setup Pages
102+
uses: actions/configure-pages@v5
103+
104+
- name: Upload artifact
105+
uses: actions/upload-pages-artifact@v3
106+
with:
107+
path: docs/
108+
109+
- name: Deploy to GitHub Pages
110+
id: deployment
111+
uses: actions/deploy-pages@v4
112+
113+
# ══════════════════════════════════════════════════════════════ DOCKER
114+
docker:
115+
name: "🐳 Docker Build"
116+
needs: test
117+
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
118+
runs-on: ubuntu-latest
119+
120+
steps:
121+
- uses: actions/checkout@v4
122+
123+
- name: Set up Docker Buildx
124+
uses: docker/setup-buildx-action@v3
125+
126+
- name: Build Docker image
127+
run: |
128+
docker build -t gravity-anchor:latest .
129+
docker images gravity-anchor
130+
131+
- name: Test Docker image
132+
env:
133+
PYTHONIOENCODING: utf-8
134+
PROJECT_ANCHOR_DB: ":memory:"
135+
run: |
136+
docker run --rm gravity-anchor:latest python -m pytest tests/ -v --tb=short -q

Dockerfile

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# syntax=docker/dockerfile:1
2+
# ═══════════════════════════════════════════════════════════════════
3+
# GRAVITY- | Project Anchor — Multi-Stage Docker Build
4+
# ═══════════════════════════════════════════════════════════════════
5+
6+
# ── Stage 1: Builder ──────────────────────────────────────────────
7+
FROM python:3.11-slim AS builder
8+
9+
WORKDIR /build
10+
11+
# Install build deps only (cached)
12+
COPY requirements.txt .
13+
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt \
14+
&& pip install --no-cache-dir --prefix=/install \
15+
celery[redis] redis fastapi uvicorn[standard] \
16+
sqlalchemy alembic psycopg2-binary \
17+
prometheus-client opentelemetry-api opentelemetry-sdk \
18+
pytest pytest-cov
19+
20+
# ── Stage 2: Runtime ─────────────────────────────────────────────
21+
FROM python:3.11-slim AS runtime
22+
23+
LABEL maintainer="FTHTrading" \
24+
description="Project Anchor — 6-phase forensic research system" \
25+
version="1.0.0"
26+
27+
# Copy installed packages
28+
COPY --from=builder /install /usr/local
29+
30+
WORKDIR /app
31+
32+
# Copy application code
33+
COPY src/ src/
34+
COPY scaling/ scaling/
35+
COPY tests/ tests/
36+
COPY main.py .
37+
COPY requirements.txt .
38+
39+
# Create runtime directories
40+
RUN mkdir -p data/keys data/foia data/equations logs reports/audits \
41+
&& groupadd -r anchor && useradd -r -g anchor anchor \
42+
&& chown -R anchor:anchor /app
43+
44+
# Environment
45+
ENV PYTHONUNBUFFERED=1 \
46+
PYTHONIOENCODING=utf-8 \
47+
PYTHONDONTWRITEBYTECODE=1 \
48+
PROJECT_ANCHOR_HOME=/app
49+
50+
# Health check
51+
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
52+
CMD python -c "import src.database; print('OK')"
53+
54+
USER anchor
55+
56+
# Default: run tests to verify image
57+
CMD ["python", "-m", "pytest", "tests/", "-v", "--tb=short"]
58+
59+
# For API mode: docker run gravity-anchor:latest uvicorn scaling.api:app --host 0.0.0.0 --port 8000
60+
# For worker: docker run gravity-anchor:latest celery -A scaling.worker_pool worker --loglevel=info

docker-compose.yml

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# ═══════════════════════════════════════════════════════════════════
2+
# GRAVITY- | Project Anchor — Docker Compose
3+
# ═══════════════════════════════════════════════════════════════════
4+
# Usage:
5+
# docker compose up -d # Start all services
6+
# docker compose up api # API only
7+
# docker compose up worker # Workers only
8+
# docker compose logs -f api # Follow API logs
9+
# ═══════════════════════════════════════════════════════════════════
10+
11+
services:
12+
# ── API Server ─────────────────────────────────────────────────
13+
api:
14+
build: .
15+
command: uvicorn scaling.api:app --host 0.0.0.0 --port 8000 --workers 4
16+
ports:
17+
- "8000:8000"
18+
environment:
19+
- PROJECT_ANCHOR_DB_URL=postgresql://anchor:anchor@postgres:5432/gravity
20+
- REDIS_URL=redis://redis:6379/0
21+
- PYTHONIOENCODING=utf-8
22+
depends_on:
23+
postgres:
24+
condition: service_healthy
25+
redis:
26+
condition: service_healthy
27+
healthcheck:
28+
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
29+
interval: 15s
30+
timeout: 5s
31+
retries: 3
32+
deploy:
33+
resources:
34+
limits:
35+
memory: 512M
36+
cpus: "1.0"
37+
restart: unless-stopped
38+
39+
# ── Celery Workers ─────────────────────────────────────────────
40+
worker:
41+
build: .
42+
command: celery -A scaling.worker_pool worker --loglevel=info --concurrency=4
43+
environment:
44+
- PROJECT_ANCHOR_DB_URL=postgresql://anchor:anchor@postgres:5432/gravity
45+
- REDIS_URL=redis://redis:6379/0
46+
- PYTHONIOENCODING=utf-8
47+
depends_on:
48+
postgres:
49+
condition: service_healthy
50+
redis:
51+
condition: service_healthy
52+
deploy:
53+
replicas: 2
54+
resources:
55+
limits:
56+
memory: 1G
57+
cpus: "2.0"
58+
restart: unless-stopped
59+
60+
# ── Celery Beat (Scheduler) ────────────────────────────────────
61+
scheduler:
62+
build: .
63+
command: celery -A scaling.worker_pool beat --loglevel=info
64+
environment:
65+
- PROJECT_ANCHOR_DB_URL=postgresql://anchor:anchor@postgres:5432/gravity
66+
- REDIS_URL=redis://redis:6379/0
67+
depends_on:
68+
- worker
69+
restart: unless-stopped
70+
71+
# ── PostgreSQL ─────────────────────────────────────────────────
72+
postgres:
73+
image: postgres:16-alpine
74+
environment:
75+
POSTGRES_DB: gravity
76+
POSTGRES_USER: anchor
77+
POSTGRES_PASSWORD: anchor
78+
volumes:
79+
- pgdata:/var/lib/postgresql/data
80+
ports:
81+
- "5432:5432"
82+
healthcheck:
83+
test: ["CMD-SHELL", "pg_isready -U anchor -d gravity"]
84+
interval: 10s
85+
timeout: 5s
86+
retries: 5
87+
deploy:
88+
resources:
89+
limits:
90+
memory: 256M
91+
restart: unless-stopped
92+
93+
# ── Redis (Task Queue Broker) ──────────────────────────────────
94+
redis:
95+
image: redis:7-alpine
96+
ports:
97+
- "6379:6379"
98+
volumes:
99+
- redisdata:/data
100+
healthcheck:
101+
test: ["CMD", "redis-cli", "ping"]
102+
interval: 10s
103+
timeout: 5s
104+
retries: 5
105+
deploy:
106+
resources:
107+
limits:
108+
memory: 128M
109+
restart: unless-stopped
110+
111+
# ── IPFS Node ──────────────────────────────────────────────────
112+
ipfs:
113+
image: ipfs/kubo:v0.39.0
114+
ports:
115+
- "4001:4001" # P2P
116+
- "5001:5001" # RPC API
117+
- "8080:8080" # Gateway
118+
volumes:
119+
- ipfsdata:/data/ipfs
120+
deploy:
121+
resources:
122+
limits:
123+
memory: 512M
124+
restart: unless-stopped
125+
126+
# ── Prometheus (Metrics) ───────────────────────────────────────
127+
prometheus:
128+
image: prom/prometheus:latest
129+
ports:
130+
- "9090:9090"
131+
volumes:
132+
- ./scaling/prometheus.yml:/etc/prometheus/prometheus.yml:ro
133+
depends_on:
134+
- api
135+
restart: unless-stopped
136+
137+
volumes:
138+
pgdata:
139+
redisdata:
140+
ipfsdata:

docs/_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
theme: null

0 commit comments

Comments
 (0)