veylant/web/src/pages/docs/installation/DockerComposePage.tsx
2026-02-27 23:33:07 +01:00

134 lines
5.0 KiB
TypeScript

import { CodeBlock } from "../components/CodeBlock";
import { Callout } from "../components/Callout";
export function DockerComposePage() {
return (
<div>
<h1 id="docker-compose">Docker Compose Setup</h1>
<p>
The recommended way to run Veylant IA locally or in a single-server staging environment is
Docker Compose. The full stack is defined in <code>docker-compose.yml</code> at the
repository root.
</p>
<h2 id="services">Services</h2>
<div className="overflow-x-auto my-4">
<table className="w-full text-sm border rounded-lg overflow-hidden">
<thead>
<tr className="bg-muted/50 border-b">
<th className="text-left px-4 py-2.5 font-semibold">Service</th>
<th className="text-left px-4 py-2.5 font-semibold">Image</th>
<th className="text-left px-4 py-2.5 font-semibold">Port</th>
<th className="text-left px-4 py-2.5 font-semibold">Purpose</th>
</tr>
</thead>
<tbody>
{[
{ service: "proxy", image: "Custom (Go, distroless)", port: "8090", purpose: "Main AI gateway" },
{ service: "pii", image: "Custom (Python FastAPI)", port: "8091 / 50051", purpose: "PII detection" },
{ service: "postgres", image: "postgres:16-alpine", port: "5432", purpose: "Config, users, policies" },
{ service: "redis", image: "redis:7-alpine", port: "6379", purpose: "Sessions, rate limits, PII maps" },
{ service: "clickhouse", image: "clickhouse:24.3-alpine", port: "8123 / 9000", purpose: "Audit logs & analytics" },
{ service: "keycloak", image: "keycloak:24.0", port: "8080", purpose: "IAM & SSO" },
{ service: "prometheus", image: "prom/prometheus:v2.53.0", port: "9090", purpose: "Metrics scraper" },
{ service: "grafana", image: "grafana:11.3.0", port: "3001", purpose: "Dashboards" },
{ service: "web", image: "node:20-alpine", port: "3000", purpose: "React dashboard" },
].map((row) => (
<tr key={row.service} className="border-b last:border-0">
<td className="px-4 py-2.5 font-mono text-xs font-medium">{row.service}</td>
<td className="px-4 py-2.5 text-muted-foreground text-xs">{row.image}</td>
<td className="px-4 py-2.5 font-mono text-xs">{row.port}</td>
<td className="px-4 py-2.5 text-muted-foreground text-xs">{row.purpose}</td>
</tr>
))}
</tbody>
</table>
</div>
<h2 id="commands">Make Commands</h2>
<CodeBlock
language="bash"
code={`# Start the full stack (build images + run)
make dev
# Tail logs from all services
make dev-logs
# Stop all containers and remove volumes
make dev-down
# Check proxy health
make health
# Open Swagger UI in browser (proxy must be running)
make docs`}
/>
<h2 id="startup-order">Startup Order & Health Checks</h2>
<p>Services start in dependency order:</p>
<ol>
<li>PostgreSQL Redis ClickHouse (databases)</li>
<li>Keycloak (waits for PostgreSQL health check)</li>
<li>PII service (independent)</li>
<li>Go proxy (waits for PostgreSQL, uses <code>service_started</code> for others)</li>
<li>React web (waits for proxy)</li>
<li>Prometheus Grafana (monitoring)</li>
</ol>
<Callout type="warning" title="Proxy health check">
The proxy Docker image uses <code>distroless/static</code> no shell, no{" "}
<code>wget</code>. Services that depend on the proxy use{" "}
<code>condition: service_started</code> rather than a health check command.
</Callout>
<h2 id="first-run">First Run: Database Migrations</h2>
<p>
On first start, the proxy automatically applies PostgreSQL migrations (9 migration files)
and ClickHouse DDL. You can also run migrations manually:
</p>
<CodeBlock
language="bash"
code={`# Apply all pending migrations
make migrate-up
# Check current migration version
make migrate-status
# Roll back last migration
make migrate-down`}
/>
<h2 id="proto">Protocol Buffer Generation</h2>
<p>
If the <code>gen/</code> or <code>services/pii/gen/</code> directories are missing (e.g.,
fresh clone), regenerate the gRPC stubs before starting:
</p>
<CodeBlock
language="bash"
code={`# Requires buf CLI: brew install buf
make proto
# Lint proto definitions
make proto-lint`}
/>
<Callout type="info">
The PII service starts but rejects all gRPC requests if <code>services/pii/gen/</code> is
missing. Run <code>make proto</code> first.
</Callout>
<h2 id="logs">Viewing Logs</h2>
<CodeBlock
language="bash"
code={`# All services
make dev-logs
# Single service
docker compose logs -f proxy
docker compose logs -f pii
docker compose logs -f postgres`}
/>
</div>
);
}