feat: add paca
This commit is contained in:
@@ -16,6 +16,7 @@ Compose Anything is a collection of production-ready, portable Docker Compose st
|
||||
3. Update these files together when a service changes: `docker-compose.yaml`, `.env.example`, `README.md`, and `README.zh.md`.
|
||||
4. Update the root `README.md` and `README.zh.md` whenever a service is added, renamed, removed, or needs a new quick-start entry.
|
||||
5. Keep the default startup path within `docker compose up -d`. If extra setup is unavoidable, document it clearly and prefer a `Makefile` over ad-hoc instructions.
|
||||
6. If a user requests to test locally, ensure that each service is healthy (if the service has health checks) and that there are no unnamed volumes.
|
||||
|
||||
## Compose Standards
|
||||
|
||||
|
||||
@@ -160,6 +160,7 @@ These services require building custom Docker images from source.
|
||||
| [OpenTelemetry Collector](./src/otel-collector) | 0.115.1 |
|
||||
| [OpenViking](./src/openviking) | 0.1.0 |
|
||||
| [Overleaf](./src/overleaf) | 5.2.1 |
|
||||
| [Paca](./apps/paca) | 0.5.2 |
|
||||
| [PocketBase](./src/pocketbase) | 0.30.0 |
|
||||
| [Podman](./src/podman) | v5.7.1 |
|
||||
| [Pogocache](./src/pogocache) | 1.3.1 |
|
||||
|
||||
@@ -160,6 +160,7 @@ docker compose exec redis redis-cli ping
|
||||
| [OpenTelemetry Collector](./src/otel-collector) | 0.115.1 |
|
||||
| [OpenViking](./src/openviking) | 0.1.0 |
|
||||
| [Overleaf](./src/overleaf) | 5.2.1 |
|
||||
| [Paca](./apps/paca) | 0.5.2 |
|
||||
| [PocketBase](./src/pocketbase) | 0.30.0 |
|
||||
| [Podman](./src/podman) | v5.7.1 |
|
||||
| [Pogocache](./src/pogocache) | 1.3.1 |
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
# Paca Configuration
|
||||
|
||||
# Paca application version (applies to API, Web, and Realtime images)
|
||||
# Individual image overrides: PACA_API_IMAGE, PACA_WEB_IMAGE, PACA_REALTIME_IMAGE
|
||||
PACA_VERSION=0.5.2
|
||||
|
||||
# Infrastructure versions
|
||||
PACA_POSTGRES_VERSION=16-alpine
|
||||
PACA_VALKEY_VERSION=8-alpine
|
||||
PACA_MINIO_VERSION=latest
|
||||
PACA_NGINX_VERSION=1.27-alpine
|
||||
|
||||
# Port Configuration
|
||||
PACA_PORT_OVERRIDE=80
|
||||
|
||||
# Environment
|
||||
PACA_ENVIRONMENT=production
|
||||
|
||||
# Timezone
|
||||
TZ=UTC
|
||||
|
||||
# ── Database ───────────────────────────────────────────────────────────────
|
||||
PACA_POSTGRES_DB=paca
|
||||
PACA_POSTGRES_USER=paca
|
||||
# IMPORTANT: Change this to a strong password in production!
|
||||
PACA_POSTGRES_PASSWORD=changeme
|
||||
# Set PACA_DATABASE_URL to use an external Postgres instead of the bundled one.
|
||||
# PACA_DATABASE_URL=postgres://user:password@host:5432/paca?sslmode=disable
|
||||
|
||||
# ── Cache ──────────────────────────────────────────────────────────────────
|
||||
# Set PACA_REDIS_URL to use an external Valkey/Redis instead of the bundled one.
|
||||
# PACA_REDIS_URL=redis://host:6379/0
|
||||
|
||||
# ── Security ───────────────────────────────────────────────────────────────
|
||||
# IMPORTANT: Change all of these in production!
|
||||
# Generate with: openssl rand -hex 32
|
||||
PACA_JWT_SECRET=changeme_jwt_secret_minimum_32_chars
|
||||
PACA_ENCRYPTION_KEY=
|
||||
PACA_ADMIN_USERNAME=admin
|
||||
PACA_ADMIN_PASSWORD=changeme
|
||||
PACA_AGENT_API_KEY=
|
||||
|
||||
# Cookie security: set to true when serving over HTTPS
|
||||
PACA_COOKIE_SECURE=false
|
||||
|
||||
# JWT TTL settings
|
||||
PACA_JWT_ACCESS_TTL=15m
|
||||
PACA_JWT_REFRESH_TTL=168h
|
||||
PACA_JWT_REFRESH_SESSION_TTL=24h
|
||||
|
||||
# ── Object Storage ─────────────────────────────────────────────────────────
|
||||
# Default: bundled MinIO. Set STORAGE_PROVIDER=s3 for AWS S3.
|
||||
PACA_STORAGE_PROVIDER=minio
|
||||
PACA_STORAGE_ENDPOINT=paca-minio:9000
|
||||
PACA_STORAGE_PUBLIC_URL=http://localhost/storage
|
||||
PACA_STORAGE_REGION=us-east-1
|
||||
PACA_STORAGE_BUCKET=paca
|
||||
PACA_STORAGE_ACCESS_KEY_ID=minioadmin
|
||||
PACA_STORAGE_SECRET_ACCESS_KEY=minioadmin
|
||||
PACA_STORAGE_USE_SSL=false
|
||||
|
||||
# ── Public URL ─────────────────────────────────────────────────────────────
|
||||
# The base URL where Paca will be accessed (used for plugin callbacks, etc.)
|
||||
PACA_PUBLIC_URL=http://localhost
|
||||
|
||||
# ── CORS Origins ───────────────────────────────────────────────────────────
|
||||
# Defaults to PACA_PUBLIC_URL if not set
|
||||
# PACA_CORS_ORIGINS=http://localhost
|
||||
|
||||
# ── Logging ────────────────────────────────────────────────────────────────
|
||||
LOG_LEVEL=info
|
||||
|
||||
# ── Resource Limits - PostgreSQL ───────────────────────────────────────────
|
||||
PACA_POSTGRES_CPU_LIMIT=1.0
|
||||
PACA_POSTGRES_CPU_RESERVATION=0.1
|
||||
PACA_POSTGRES_MEMORY_LIMIT=1G
|
||||
PACA_POSTGRES_MEMORY_RESERVATION=256M
|
||||
|
||||
# ── Resource Limits - Valkey ───────────────────────────────────────────────
|
||||
PACA_VALKEY_CPU_LIMIT=0.5
|
||||
PACA_VALKEY_CPU_RESERVATION=0.1
|
||||
PACA_VALKEY_MEMORY_LIMIT=512M
|
||||
PACA_VALKEY_MEMORY_RESERVATION=128M
|
||||
|
||||
# ── Resource Limits - MinIO ────────────────────────────────────────────────
|
||||
PACA_MINIO_CPU_LIMIT=0.5
|
||||
PACA_MINIO_CPU_RESERVATION=0.1
|
||||
PACA_MINIO_MEMORY_LIMIT=512M
|
||||
PACA_MINIO_MEMORY_RESERVATION=256M
|
||||
|
||||
# ── Resource Limits - API ──────────────────────────────────────────────────
|
||||
PACA_API_CPU_LIMIT=1.0
|
||||
PACA_API_CPU_RESERVATION=0.1
|
||||
PACA_API_MEMORY_LIMIT=1G
|
||||
PACA_API_MEMORY_RESERVATION=256M
|
||||
|
||||
# ── Resource Limits - Web ──────────────────────────────────────────────────
|
||||
PACA_WEB_CPU_LIMIT=0.5
|
||||
PACA_WEB_CPU_RESERVATION=0.1
|
||||
PACA_WEB_MEMORY_LIMIT=512M
|
||||
PACA_WEB_MEMORY_RESERVATION=128M
|
||||
|
||||
# ── Resource Limits - Realtime ─────────────────────────────────────────────
|
||||
PACA_REALTIME_CPU_LIMIT=0.5
|
||||
PACA_REALTIME_CPU_RESERVATION=0.1
|
||||
PACA_REALTIME_MEMORY_LIMIT=512M
|
||||
PACA_REALTIME_MEMORY_RESERVATION=128M
|
||||
|
||||
# ── Resource Limits - Gateway ──────────────────────────────────────────────
|
||||
PACA_GATEWAY_CPU_LIMIT=0.5
|
||||
PACA_GATEWAY_CPU_RESERVATION=0.1
|
||||
PACA_GATEWAY_MEMORY_LIMIT=256M
|
||||
PACA_GATEWAY_MEMORY_RESERVATION=128M
|
||||
@@ -0,0 +1,83 @@
|
||||
# Paca
|
||||
|
||||
Self-hosted project management platform designed for human + AI collaboration as Scrum team members.
|
||||
|
||||
## Services
|
||||
|
||||
- `paca-postgres`: PostgreSQL 16 database for persistent storage.
|
||||
- `paca-valkey`: Valkey 8 cache and pub-sub event bus.
|
||||
- `paca-minio`: MinIO S3-compatible object store for file uploads.
|
||||
- `paca-api`: Go REST API backend (port 8080 internal).
|
||||
- `paca-web`: React SPA frontend served via internal nginx (port 3000 internal).
|
||||
- `paca-realtime`: Node.js Socket.IO real-time event hub (port 3001 internal).
|
||||
- `paca-gateway`: Nginx reverse proxy that routes all traffic to the correct service.
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Create a `.env` file from the example and set your secrets:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# Edit .env to set PACA_JWT_SECRET, PACA_ENCRYPTION_KEY, PACA_ADMIN_PASSWORD, etc.
|
||||
```
|
||||
|
||||
1. Start the stack:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
1. Open `http://localhost` in your browser and log in with the configured admin credentials.
|
||||
|
||||
## Key Environment Variables
|
||||
|
||||
| Variable | Description | Default |
|
||||
| -------------------------------- | --------------------------------- | ------------------ |
|
||||
| `PACA_PORT_OVERRIDE` | Host port for the gateway | `80` |
|
||||
| `PACA_VERSION` | Application image tag | `latest` |
|
||||
| `PACA_POSTGRES_PASSWORD` | PostgreSQL password | `changeme` |
|
||||
| `PACA_ADMIN_USERNAME` | Initial admin username | `admin` |
|
||||
| `PACA_ADMIN_PASSWORD` | Initial admin password | `changeme` |
|
||||
| `PACA_JWT_SECRET` | JWT signing secret (min 32 chars) | (placeholder) |
|
||||
| `PACA_ENCRYPTION_KEY` | AES-256 key for plugin secrets | (empty) |
|
||||
| `PACA_PUBLIC_URL` | Public base URL | `http://localhost` |
|
||||
| `PACA_STORAGE_PROVIDER` | Object storage provider | `minio` |
|
||||
| `PACA_STORAGE_ACCESS_KEY_ID` | Storage access key | `minioadmin` |
|
||||
| `PACA_STORAGE_SECRET_ACCESS_KEY` | Storage secret key | `minioadmin` |
|
||||
|
||||
## Storage
|
||||
|
||||
| Volume | Purpose |
|
||||
| ----------------------- | ----------------------------- |
|
||||
| `paca_postgres_data` | PostgreSQL database files |
|
||||
| `paca_valkey_data` | Valkey append-only file |
|
||||
| `paca_minio_data` | MinIO object store data |
|
||||
| `paca_backend_plugins` | WASM backend plugin binaries |
|
||||
| `paca_frontend_plugins` | Frontend plugin static assets |
|
||||
| `paca_mcp_plugins` | MCP plugin bundles |
|
||||
|
||||
## Using External Services
|
||||
|
||||
- **External PostgreSQL**: Set `PACA_DATABASE_URL` and run with `--scale paca-postgres=0`.
|
||||
- **AWS S3 instead of MinIO**: Set `PACA_STORAGE_PROVIDER=s3` and run with `--scale paca-minio=0`.
|
||||
- **External Valkey/Redis**: Set `PACA_REDIS_URL` and run with `--scale paca-valkey=0`.
|
||||
|
||||
## Security Notes
|
||||
|
||||
- Generate strong secrets with `openssl rand -hex 32`.
|
||||
- Change all default passwords before using in production.
|
||||
- Set `PACA_COOKIE_SECURE=true` when serving over HTTPS.
|
||||
- The gateway binds to port 80 by default; use a reverse proxy with TLS for production.
|
||||
- This stack runs multiple services as root (nginx, postgres); consider hardening for production.
|
||||
|
||||
## Scaling
|
||||
|
||||
You can selectively disable optional services:
|
||||
|
||||
```bash
|
||||
# Without MinIO (use S3 instead)
|
||||
docker compose up -d --scale paca-minio=0
|
||||
|
||||
# Without the web frontend (serve SPA from CDN)
|
||||
docker compose up -d --scale paca-web=0
|
||||
```
|
||||
@@ -0,0 +1,83 @@
|
||||
# Paca
|
||||
|
||||
自托管的项目管理平台,专为人类与 AI 作为 Scrum 团队成员协作而设计。
|
||||
|
||||
## 服务
|
||||
|
||||
- `paca-postgres`:PostgreSQL 16 数据库,用于持久化存储。
|
||||
- `paca-valkey`:Valkey 8 缓存与发布/订阅事件总线。
|
||||
- `paca-minio`:兼容 S3 的 MinIO 对象存储,用于文件上传。
|
||||
- `paca-api`:Go 语言 REST API 后端(内部端口 8080)。
|
||||
- `paca-web`:React SPA 前端,通过内部 nginx 提供服务(内部端口 3000)。
|
||||
- `paca-realtime`:Node.js Socket.IO 实时事件中心(内部端口 3001)。
|
||||
- `paca-gateway`:Nginx 反向代理,将所有流量路由到正确的服务。
|
||||
|
||||
## 快速开始
|
||||
|
||||
1. 从示例文件创建 `.env` 并设置密钥:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# 编辑 .env 文件,设置 PACA_JWT_SECRET、PACA_ENCRYPTION_KEY、PACA_ADMIN_PASSWORD 等
|
||||
```
|
||||
|
||||
1. 启动服务栈:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
1. 在浏览器中打开 `http://localhost`,使用配置的管理员凭据登录。
|
||||
|
||||
## 主要环境变量
|
||||
|
||||
| 变量 | 说明 | 默认值 |
|
||||
| -------------------------------- | ---------------------------- | ------------------ |
|
||||
| `PACA_PORT_OVERRIDE` | 网关主机端口 | `80` |
|
||||
| `PACA_VERSION` | 应用镜像标签 | `latest` |
|
||||
| `PACA_POSTGRES_PASSWORD` | PostgreSQL 密码 | `changeme` |
|
||||
| `PACA_ADMIN_USERNAME` | 初始管理员用户名 | `admin` |
|
||||
| `PACA_ADMIN_PASSWORD` | 初始管理员密码 | `changeme` |
|
||||
| `PACA_JWT_SECRET` | JWT 签名密钥(至少 32 字符) | (占位符) |
|
||||
| `PACA_ENCRYPTION_KEY` | 插件密钥 AES-256 加密密钥 | (空) |
|
||||
| `PACA_PUBLIC_URL` | 公开访问的基础 URL | `http://localhost` |
|
||||
| `PACA_STORAGE_PROVIDER` | 对象存储提供商 | `minio` |
|
||||
| `PACA_STORAGE_ACCESS_KEY_ID` | 存储访问密钥 ID | `minioadmin` |
|
||||
| `PACA_STORAGE_SECRET_ACCESS_KEY` | 存储访问密钥 | `minioadmin` |
|
||||
|
||||
## 存储
|
||||
|
||||
| 卷 | 用途 |
|
||||
| ----------------------- | ----------------------- |
|
||||
| `paca_postgres_data` | PostgreSQL 数据库文件 |
|
||||
| `paca_valkey_data` | Valkey 追加日志文件 |
|
||||
| `paca_minio_data` | MinIO 对象存储数据 |
|
||||
| `paca_backend_plugins` | WASM 后端插件二进制文件 |
|
||||
| `paca_frontend_plugins` | 前端插件静态资源 |
|
||||
| `paca_mcp_plugins` | MCP 插件包 |
|
||||
|
||||
## 使用外部服务
|
||||
|
||||
- **外部 PostgreSQL**:设置 `PACA_DATABASE_URL`,启动时添加 `--scale paca-postgres=0`。
|
||||
- **AWS S3 替代 MinIO**:设置 `PACA_STORAGE_PROVIDER=s3`,启动时添加 `--scale paca-minio=0`。
|
||||
- **外部 Valkey / Redis**:设置 `PACA_REDIS_URL`,启动时添加 `--scale paca-valkey=0`。
|
||||
|
||||
## 安全说明
|
||||
|
||||
- 使用 `openssl rand -hex 32` 生成强密钥。
|
||||
- 在生产环境使用前务必修改所有默认密码。
|
||||
- 通过 HTTPS 提供服务时,设置 `PACA_COOKIE_SECURE=true`。
|
||||
- 网关默认绑定 80 端口;生产环境建议在前方使用带 TLS 的反向代理。
|
||||
- 本服务栈中多个服务以 root 运行(nginx、postgres);生产环境建议进一步加固。
|
||||
|
||||
## 扩缩容
|
||||
|
||||
可以按需禁用可选服务:
|
||||
|
||||
```bash
|
||||
# 不使用 MinIO(改用 S3)
|
||||
docker compose up -d --scale paca-minio=0
|
||||
|
||||
# 不使用 Web 前端(从 CDN 提供 SPA)
|
||||
docker compose up -d --scale paca-web=0
|
||||
```
|
||||
@@ -0,0 +1,272 @@
|
||||
# Paca - Self-hosted project management platform for humans + AI
|
||||
# https://github.com/Paca-AI/paca
|
||||
#
|
||||
# Paca is a project management platform designed for human + AI collaboration
|
||||
# as Scrum team members. It features a real-time Scrumban board, BDD
|
||||
# collaborative editing, system design docs, a plugin system (WASM backend +
|
||||
# frontend modules), and a built-in MCP server.
|
||||
#
|
||||
# Key Features:
|
||||
# - Real-time Scrumban board for task management
|
||||
# - AI agents as Scrum team members
|
||||
# - BDD (Behavior-Driven Development) collaborative editor
|
||||
# - System design documentation
|
||||
# - Plugin system with WASM backend and frontend modules
|
||||
# - Built-in MCP (Model Context Protocol) server
|
||||
# - Connects with Claude and other MCP-compatible clients
|
||||
#
|
||||
# Default Access:
|
||||
# - Access UI at http://localhost (after setting PUBLIC_URL)
|
||||
# - Default admin: configured via ADMIN_USERNAME / ADMIN_PASSWORD
|
||||
#
|
||||
# Security Notes:
|
||||
# - Change ADMIN_USERNAME and ADMIN_PASSWORD immediately
|
||||
# - Use strong JWT_SECRET and ENCRYPTION_KEY in production
|
||||
# - Generate keys with: openssl rand -hex 32
|
||||
# - Use STORAGE_PROVIDER=s3 for production instead of bundled MinIO
|
||||
# - Set COOKIE_SECURE=true when serving over HTTPS
|
||||
#
|
||||
# License: AGPL-3.0 (https://github.com/Paca-AI/paca/blob/main/LICENSE)
|
||||
|
||||
x-defaults: &defaults
|
||||
restart: unless-stopped
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: 100m
|
||||
max-file: '3'
|
||||
|
||||
services:
|
||||
# ── PostgreSQL ──────────────────────────────────────────────────────────
|
||||
paca-postgres:
|
||||
<<: *defaults
|
||||
image: ${GLOBAL_REGISTRY:-}postgres:${PACA_POSTGRES_VERSION:-16-alpine}
|
||||
environment:
|
||||
- TZ=${TZ:-UTC}
|
||||
- POSTGRES_DB=${PACA_POSTGRES_DB:-paca}
|
||||
- POSTGRES_USER=${PACA_POSTGRES_USER:-paca}
|
||||
- POSTGRES_PASSWORD=${PACA_POSTGRES_PASSWORD:-changeme}
|
||||
- PGDATA=/var/lib/postgresql/data/pgdata
|
||||
volumes:
|
||||
- paca_postgres_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD-SHELL
|
||||
- pg_isready -U ${PACA_POSTGRES_USER:-paca} -d ${PACA_POSTGRES_DB:-paca}
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
start_period: 10s
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '${PACA_POSTGRES_CPU_LIMIT:-1.0}'
|
||||
memory: '${PACA_POSTGRES_MEMORY_LIMIT:-1G}'
|
||||
reservations:
|
||||
cpus: '${PACA_POSTGRES_CPU_RESERVATION:-0.1}'
|
||||
memory: '${PACA_POSTGRES_MEMORY_RESERVATION:-256M}'
|
||||
|
||||
# ── Valkey (Redis-compatible cache / pub-sub) ───────────────────────────
|
||||
paca-valkey:
|
||||
<<: *defaults
|
||||
image: ${GLOBAL_REGISTRY:-}valkey/valkey:${PACA_VALKEY_VERSION:-8-alpine}
|
||||
command: valkey-server --appendonly yes
|
||||
environment:
|
||||
- TZ=${TZ:-UTC}
|
||||
volumes:
|
||||
- paca_valkey_data:/data
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD
|
||||
- valkey-cli
|
||||
- ping
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
start_period: 5s
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '${PACA_VALKEY_CPU_LIMIT:-0.5}'
|
||||
memory: '${PACA_VALKEY_MEMORY_LIMIT:-512M}'
|
||||
reservations:
|
||||
cpus: '${PACA_VALKEY_CPU_RESERVATION:-0.1}'
|
||||
memory: '${PACA_VALKEY_MEMORY_RESERVATION:-128M}'
|
||||
|
||||
# ── MinIO (S3-compatible object store) ──────────────────────────────────
|
||||
paca-minio:
|
||||
<<: *defaults
|
||||
user: root
|
||||
image: ${CGR_DEV_REGISTRY:-cgr.dev/}chainguard/minio:${PACA_MINIO_VERSION:-latest}
|
||||
command: server /data --console-address ":9001"
|
||||
environment:
|
||||
- TZ=${TZ:-UTC}
|
||||
- MINIO_ROOT_USER=${PACA_STORAGE_ACCESS_KEY_ID:-minioadmin}
|
||||
- MINIO_ROOT_PASSWORD=${PACA_STORAGE_SECRET_ACCESS_KEY:-minioadmin}
|
||||
volumes:
|
||||
- paca_minio_data:/data
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD
|
||||
- mc
|
||||
- ready
|
||||
- local
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
start_period: 10s
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '${PACA_MINIO_CPU_LIMIT:-0.5}'
|
||||
memory: '${PACA_MINIO_MEMORY_LIMIT:-512M}'
|
||||
reservations:
|
||||
cpus: '${PACA_MINIO_CPU_RESERVATION:-0.1}'
|
||||
memory: '${PACA_MINIO_MEMORY_RESERVATION:-256M}'
|
||||
|
||||
# ── API (Go backend) ────────────────────────────────────────────────────
|
||||
paca-api:
|
||||
<<: *defaults
|
||||
image: ${PACA_API_IMAGE:-${GLOBAL_REGISTRY:-}pacaai/paca-api:${PACA_VERSION:-0.5.2}}
|
||||
environment:
|
||||
- TZ=${TZ:-UTC}
|
||||
- ENV=${PACA_ENVIRONMENT:-production}
|
||||
- PORT=8080
|
||||
# Database. Set DATABASE_URL for an external Postgres and scale paca-postgres to 0.
|
||||
- DATABASE_URL=${PACA_DATABASE_URL:-postgres://${PACA_POSTGRES_USER:-paca}:${PACA_POSTGRES_PASSWORD:-changeme}@paca-postgres:5432/${PACA_POSTGRES_DB:-paca}?sslmode=disable}
|
||||
- REDIS_URL=${PACA_REDIS_URL:-redis://paca-valkey:6379/0}
|
||||
- JWT_SECRET=${PACA_JWT_SECRET:-changeme_jwt_secret_minimum_32_chars}
|
||||
- JWT_ACCESS_TTL=${PACA_JWT_ACCESS_TTL:-15m}
|
||||
- JWT_REFRESH_TTL=${PACA_JWT_REFRESH_TTL:-168h}
|
||||
- JWT_REFRESH_SESSION_TTL=${PACA_JWT_REFRESH_SESSION_TTL:-24h}
|
||||
- COOKIE_SECURE=${PACA_COOKIE_SECURE:-false}
|
||||
- ADMIN_USERNAME=${PACA_ADMIN_USERNAME:-admin}
|
||||
- ADMIN_PASSWORD=${PACA_ADMIN_PASSWORD:-changeme}
|
||||
# Object storage. Set STORAGE_PROVIDER=s3 for AWS S3 and scale paca-minio to 0.
|
||||
- STORAGE_PROVIDER=${PACA_STORAGE_PROVIDER:-minio}
|
||||
- STORAGE_ENDPOINT=${PACA_STORAGE_ENDPOINT:-paca-minio:9000}
|
||||
- STORAGE_PUBLIC_URL=${PACA_STORAGE_PUBLIC_URL:-http://localhost/storage}
|
||||
- STORAGE_REGION=${PACA_STORAGE_REGION:-us-east-1}
|
||||
- STORAGE_BUCKET=${PACA_STORAGE_BUCKET:-paca}
|
||||
- STORAGE_ACCESS_KEY_ID=${PACA_STORAGE_ACCESS_KEY_ID:-minioadmin}
|
||||
- STORAGE_SECRET_ACCESS_KEY=${PACA_STORAGE_SECRET_ACCESS_KEY:-minioadmin}
|
||||
- STORAGE_USE_SSL=${PACA_STORAGE_USE_SSL:-false}
|
||||
- ENCRYPTION_KEY=${PACA_ENCRYPTION_KEY:-}
|
||||
- PUBLIC_URL=${PACA_PUBLIC_URL:-http://localhost}
|
||||
# Plugin directories
|
||||
- PLUGINS_WASM_DIR=/plugins
|
||||
- PLUGINS_FRONTEND_DIR=/plugins-frontend
|
||||
- PLUGINS_MCP_DIR=/plugins-mcp
|
||||
# Pre-shared key for AI agent integration
|
||||
- AGENT_API_KEY=${PACA_AGENT_API_KEY:-}
|
||||
depends_on:
|
||||
paca-postgres:
|
||||
condition: service_healthy
|
||||
paca-valkey:
|
||||
condition: service_healthy
|
||||
paca-minio:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- paca_backend_plugins:/plugins
|
||||
- paca_frontend_plugins:/plugins-frontend
|
||||
- paca_mcp_plugins:/plugins-mcp
|
||||
healthcheck:
|
||||
test:
|
||||
- CMD
|
||||
- wget
|
||||
- --no-verbose
|
||||
- --tries=1
|
||||
- --spider
|
||||
- http://localhost:8080/api/healthz
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
start_period: 40s
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '${PACA_API_CPU_LIMIT:-1.0}'
|
||||
memory: '${PACA_API_MEMORY_LIMIT:-1G}'
|
||||
reservations:
|
||||
cpus: '${PACA_API_CPU_RESERVATION:-0.1}'
|
||||
memory: '${PACA_API_MEMORY_RESERVATION:-256M}'
|
||||
|
||||
# ── Web (React SPA served via nginx) ────────────────────────────────────
|
||||
paca-web:
|
||||
<<: *defaults
|
||||
image: ${PACA_WEB_IMAGE:-${GLOBAL_REGISTRY:-}pacaai/paca-web:${PACA_VERSION:-0.5.2}}
|
||||
environment:
|
||||
- TZ=${TZ:-UTC}
|
||||
depends_on:
|
||||
paca-api:
|
||||
condition: service_healthy
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '${PACA_WEB_CPU_LIMIT:-0.5}'
|
||||
memory: '${PACA_WEB_MEMORY_LIMIT:-512M}'
|
||||
reservations:
|
||||
cpus: '${PACA_WEB_CPU_RESERVATION:-0.1}'
|
||||
memory: '${PACA_WEB_MEMORY_RESERVATION:-128M}'
|
||||
|
||||
# ── Realtime (Socket.IO event hub) ──────────────────────────────────────
|
||||
paca-realtime:
|
||||
<<: *defaults
|
||||
image: ${PACA_REALTIME_IMAGE:-${GLOBAL_REGISTRY:-}pacaai/paca-realtime:${PACA_VERSION:-0.5.2}}
|
||||
environment:
|
||||
- TZ=${TZ:-UTC}
|
||||
- PORT=3001
|
||||
- NODE_ENV=${PACA_ENVIRONMENT:-production}
|
||||
- API_URL=http://paca-api:8080
|
||||
- REDIS_URL=${PACA_REDIS_URL:-redis://paca-valkey:6379/0}
|
||||
- CORS_ORIGINS=${PACA_CORS_ORIGINS:-${PACA_PUBLIC_URL:-http://localhost}}
|
||||
- LOG_LEVEL=${LOG_LEVEL:-info}
|
||||
depends_on:
|
||||
paca-valkey:
|
||||
condition: service_healthy
|
||||
paca-api:
|
||||
condition: service_healthy
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '${PACA_REALTIME_CPU_LIMIT:-0.5}'
|
||||
memory: '${PACA_REALTIME_MEMORY_LIMIT:-512M}'
|
||||
reservations:
|
||||
cpus: '${PACA_REALTIME_CPU_RESERVATION:-0.1}'
|
||||
memory: '${PACA_REALTIME_MEMORY_RESERVATION:-128M}'
|
||||
|
||||
# ── Gateway (nginx reverse proxy) ───────────────────────────────────────
|
||||
paca-gateway:
|
||||
<<: *defaults
|
||||
image: ${GLOBAL_REGISTRY:-}nginx:${PACA_NGINX_VERSION:-1.27-alpine}
|
||||
ports:
|
||||
- '${PACA_PORT_OVERRIDE:-80}:80'
|
||||
environment:
|
||||
- TZ=${TZ:-UTC}
|
||||
volumes:
|
||||
- ./gateway.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
- paca_frontend_plugins:/var/www/plugins:ro
|
||||
- paca_mcp_plugins:/var/www/plugins-mcp:ro
|
||||
depends_on:
|
||||
paca-api:
|
||||
condition: service_started
|
||||
paca-web:
|
||||
condition: service_started
|
||||
paca-realtime:
|
||||
condition: service_started
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '${PACA_GATEWAY_CPU_LIMIT:-0.5}'
|
||||
memory: '${PACA_GATEWAY_MEMORY_LIMIT:-256M}'
|
||||
reservations:
|
||||
cpus: '${PACA_GATEWAY_CPU_RESERVATION:-0.1}'
|
||||
memory: '${PACA_GATEWAY_MEMORY_RESERVATION:-128M}'
|
||||
|
||||
volumes:
|
||||
paca_postgres_data:
|
||||
paca_valkey_data:
|
||||
paca_minio_data:
|
||||
paca_backend_plugins:
|
||||
paca_frontend_plugins:
|
||||
paca_mcp_plugins:
|
||||
@@ -0,0 +1,161 @@
|
||||
# =============================================================================
|
||||
# Gateway nginx configuration for Paca
|
||||
# =============================================================================
|
||||
#
|
||||
# Single public entrypoint for the Paca stack:
|
||||
# /api/* → REST API service
|
||||
# /ws/* → Realtime service (Socket.IO)
|
||||
# /storage/* → MinIO object storage
|
||||
# /* → Web application (SPA)
|
||||
#
|
||||
# Mounted as /etc/nginx/conf.d/default.conf inside the nginx container.
|
||||
|
||||
# -- Rate-limit zones ---------------------------------------------------------
|
||||
limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s;
|
||||
|
||||
# -- WebSocket connection upgrade map -----------------------------------------
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
# Resolve Docker service names for variable-based proxy_pass targets.
|
||||
resolver 127.0.0.11 ipv6=off valid=30s;
|
||||
|
||||
# -- Upstream pools -----------------------------------------------------------
|
||||
upstream api_backend {
|
||||
server paca-api:8080;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
upstream realtime_backend {
|
||||
server paca-realtime:3001;
|
||||
keepalive 16;
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
server_tokens off;
|
||||
client_max_body_size 10m;
|
||||
|
||||
# -- Compression ----------------------------------------------------------
|
||||
gzip on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 5;
|
||||
gzip_min_length 256;
|
||||
gzip_types
|
||||
application/javascript
|
||||
application/json
|
||||
application/wasm
|
||||
font/woff
|
||||
font/woff2
|
||||
image/svg+xml
|
||||
text/css
|
||||
text/plain;
|
||||
|
||||
# -- Security headers -----------------------------------------------------
|
||||
add_header X-Frame-Options "DENY" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
||||
add_header X-XSS-Protection "0" always;
|
||||
|
||||
# =========================================================================
|
||||
# Routing
|
||||
# =========================================================================
|
||||
|
||||
# -- Object storage (MinIO) -----------------------------------------------
|
||||
location /storage/ {
|
||||
set $minio_backend http://paca-minio:9000;
|
||||
rewrite ^/storage/(.*)$ /$1 break;
|
||||
proxy_pass $minio_backend;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
proxy_set_header Host minio:9000;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
client_max_body_size 0;
|
||||
proxy_request_buffering off;
|
||||
proxy_connect_timeout 10s;
|
||||
proxy_send_timeout 120s;
|
||||
proxy_read_timeout 120s;
|
||||
}
|
||||
|
||||
# -- Realtime service (Socket.IO) -----------------------------------------
|
||||
location /ws/ {
|
||||
proxy_pass http://realtime_backend/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_connect_timeout 10s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 3600s;
|
||||
}
|
||||
|
||||
# -- API routes -----------------------------------------------------------
|
||||
location /api/ {
|
||||
limit_req zone=api burst=50 nodelay;
|
||||
limit_req_status 429;
|
||||
|
||||
proxy_pass http://api_backend/api/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_connect_timeout 10s;
|
||||
proxy_send_timeout 30s;
|
||||
proxy_read_timeout 30s;
|
||||
}
|
||||
|
||||
# -- Local plugin frontend assets -----------------------------------------
|
||||
location /plugins/ {
|
||||
alias /var/www/plugins/;
|
||||
autoindex off;
|
||||
types {
|
||||
application/javascript js;
|
||||
application/wasm wasm;
|
||||
text/css css;
|
||||
text/html html;
|
||||
image/svg+xml svg;
|
||||
font/woff woff;
|
||||
font/woff2 woff2;
|
||||
}
|
||||
add_header Cache-Control "public, max-age=900, immutable" always;
|
||||
}
|
||||
|
||||
# -- MCP plugin bundles ---------------------------------------------------
|
||||
location /plugins-mcp/ {
|
||||
alias /var/www/plugins-mcp/;
|
||||
autoindex off;
|
||||
types {
|
||||
application/javascript js;
|
||||
}
|
||||
add_header Cache-Control "public, max-age=900, immutable" always;
|
||||
}
|
||||
|
||||
# -- Web application (SPA) ------------------------------------------------
|
||||
location / {
|
||||
set $web_backend http://paca-web:3000;
|
||||
proxy_pass $web_backend;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_connect_timeout 10s;
|
||||
proxy_send_timeout 30s;
|
||||
proxy_read_timeout 30s;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
# MinIO Version (Chainguard Image)
|
||||
MINIO_VERSION=0.20251015
|
||||
MINIO_VERSION=latest
|
||||
|
||||
# MinIO Root User Credentials
|
||||
MINIO_ROOT_USER=minioadmin
|
||||
@@ -16,4 +16,4 @@ TZ=UTC
|
||||
MINIO_CPU_LIMIT=0.5
|
||||
MINIO_MEMORY_LIMIT=1G
|
||||
MINIO_CPU_RESERVATION=0.1
|
||||
MINIO_MEMORY_RESERVATION=512M
|
||||
MINIO_MEMORY_RESERVATION=512M
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ Open the Web UI: <http://localhost:9001>.
|
||||
|
||||
## Configuration
|
||||
|
||||
- `MINIO_VERSION`: The version of the MinIO image, default is `0.20251015`.
|
||||
- `MINIO_VERSION`: The version of the MinIO image, default is `latest`.
|
||||
- `MINIO_PORT_OVERRIDE_API`: The host port for the MinIO API, default is `9000`.
|
||||
- `MINIO_PORT_OVERRIDE_WEBUI`: The host port for the MinIO Web UI, default is `9001`.
|
||||
- `MINIO_ROOT_USER`: The root username for MinIO, default is `minioadmin`.
|
||||
|
||||
@@ -12,7 +12,7 @@ MinIO 是一个高性能的 S3 兼容对象存储系统,可以用于存储和
|
||||
|
||||
## 配置
|
||||
|
||||
- `MINIO_VERSION`: MinIO 镜像的版本,默认为 `0.20251015`。
|
||||
- `MINIO_VERSION`: MinIO 镜像的版本,默认为 `latest`。
|
||||
- `MINIO_PORT_OVERRIDE_API`: MinIO API 的主机端口,默认为 `9000`。
|
||||
- `MINIO_PORT_OVERRIDE_WEBUI`: MinIO Web UI 的主机端口,默认为 `9001`。
|
||||
- `MINIO_ROOT_USER`: MinIO 的根用户名,默认为 `minioadmin`。
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# https://images.chainguard.dev/directory/image/minio/versions#/
|
||||
x-defaults: &defaults
|
||||
restart: unless-stopped
|
||||
logging:
|
||||
@@ -9,7 +10,7 @@ x-defaults: &defaults
|
||||
services:
|
||||
minio:
|
||||
<<: *defaults
|
||||
image: ${CGR_DEV_REGISTRY:cgr.dev-}/chainguard/minio:${MINIO_VERSION:-0.20251015}
|
||||
image: ${CGR_DEV_REGISTRY:cgr.dev-}/chainguard/minio:${MINIO_VERSION:-latest}
|
||||
ports:
|
||||
- '${MINIO_PORT_OVERRIDE_API:-9000}:9000'
|
||||
- '${MINIO_PORT_OVERRIDE_WEBUI:-9001}:9001'
|
||||
|
||||
Reference in New Issue
Block a user