feat: add paca

This commit is contained in:
Sun-ZhenXing
2026-06-23 11:26:44 +08:00
parent a742b5555b
commit 902627bbc2
12 changed files with 721 additions and 5 deletions
+1
View File
@@ -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
+1
View File
@@ -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 |
+1
View File
@@ -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 |
+113
View File
@@ -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
+83
View File
@@ -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
```
+83
View File
@@ -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
```
+272
View File
@@ -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:
+161
View File
@@ -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;
}
}
+2 -2
View File
@@ -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
View File
@@ -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`.
+1 -1
View File
@@ -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`
+2 -1
View File
@@ -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'