Remove copilot env overrides and add config placeholders

This commit is contained in:
Codex
2025-11-17 12:40:09 -06:00
parent 21652acb03
commit 801b6ea49d
7 changed files with 71 additions and 125 deletions

View File

@@ -13,14 +13,14 @@ cloudron build \
--set-build-service builder.docker.due.ren \ --set-build-service builder.docker.due.ren \
--build-service-token e3265de06b1d0e7bb38400539012a8433a74c2c96a17955e \ --build-service-token e3265de06b1d0e7bb38400539012a8433a74c2c96a17955e \
--set-repository andreasdueren/affine-cloudron \ --set-repository andreasdueren/affine-cloudron \
--tag 0.25.5-5 --tag 0.25.5-6
``` ```
## Deployment Steps ## Deployment Steps
1. Remove any previous dev install of AFFiNE on the Cloudron (always reinstall from scratch). 1. Remove any previous dev install of AFFiNE on the Cloudron (always reinstall from scratch).
2. Install the freshly built image: 2. Install the freshly built image:
```bash ```bash
cloudron install --location affine.due.ren --image andreasdueren/affine-cloudron:0.25.5-5 cloudron install --location affine.due.ren --image andreasdueren/affine-cloudron:0.25.5-6
``` ```
3. When prompted, confirm the app info and wait for Cloudron to report success (abort after ~30 seconds if installation stalls or errors to avoid hanging sessions). 3. When prompted, confirm the app info and wait for Cloudron to report success (abort after ~30 seconds if installation stalls or errors to avoid hanging sessions).
4. Visit `https://affine.due.ren` (or the chosen location) and sign in using Cloudron SSO. 4. Visit `https://affine.due.ren` (or the chosen location) and sign in using Cloudron SSO.
@@ -42,11 +42,4 @@ cloudron install --location affine.due.ren --image andreasdueren/affine-cloudron
- Persistent config lives in `/app/data/config/config.json`. Modify values (e.g., Stripe, throttling) and restart the app; the file is backed up by Cloudron. - Persistent config lives in `/app/data/config/config.json`. Modify values (e.g., Stripe, throttling) and restart the app; the file is backed up by Cloudron.
- Uploaded files live in `/app/data/storage` and map to `~/.affine/storage` inside the runtime. - Uploaded files live in `/app/data/storage` and map to `~/.affine/storage` inside the runtime.
- Default health check hits `/api/healthz`; customize via `CloudronManifest.json` if upstream changes. - Default health check hits `/api/healthz`; customize via `CloudronManifest.json` if upstream changes.
- Copilot providers can be configured with environment variables instead of editing `config.json`. Set any of the following via `cloudron env set --app affine.due.ren KEY=value` and restart: - Copilot API keys live in `/app/data/config/config.json`. The default file contains placeholders (`sk-provide-openai-key-here`, etc.); open it in the Cloudron File Manager or via `cloudron exec` to paste your own values, then restart the app so AFFiNE picks up the changes.
- `AFFINE_COPILOT_ENABLED` (`true`/`false`)
- `AFFINE_COPILOT_OPENAI_API_KEY`, `AFFINE_COPILOT_OPENAI_BASE_URL`
- `AFFINE_COPILOT_ANTHROPIC_API_KEY`, `AFFINE_COPILOT_ANTHROPIC_BASE_URL`
- `AFFINE_COPILOT_GEMINI_API_KEY`, `AFFINE_COPILOT_GEMINI_BASE_URL`
- `AFFINE_COPILOT_EXA_KEY` for web search
- `AFFINE_COPILOT_SCENARIOS_JSON` with a JSON payload such as `{"override_enabled":true,"scenarios":{"chat":"gpt-4o-mini"}}`
- A sample `.env` file is available at `/app/data/copilot.env.example` after install; download/edit it for reference before populating Cloudron env variables.

View File

@@ -5,9 +5,9 @@
"description": "Next-gen knowledge base that blends docs, whiteboards, and databases for self-hosted teams.", "description": "Next-gen knowledge base that blends docs, whiteboards, and databases for self-hosted teams.",
"website": "https://affine.pro", "website": "https://affine.pro",
"contactEmail": "support@affine.pro", "contactEmail": "support@affine.pro",
"version": "0.25.5-5", "version": "0.25.5-6",
"upstreamVersion": "0.25.5", "upstreamVersion": "0.25.5",
"changelog": "Auto seed Manticore tables (without external morphology packs)", "changelog": "Configure copilot via config.json placeholders; env overrides removed",
"icon": "file://icon.png", "icon": "file://icon.png",
"manifestVersion": 2, "manifestVersion": 2,
"minBoxVersion": "7.0.0", "minBoxVersion": "7.0.0",

View File

@@ -42,7 +42,6 @@ COPY run-buddy.sh "$APP_CODE_DIR/run-buddy.sh"
COPY nginx.conf "$APP_CODE_DIR/nginx.conf" COPY nginx.conf "$APP_CODE_DIR/nginx.conf"
COPY supervisord.conf "$APP_CODE_DIR/supervisord.conf" COPY supervisord.conf "$APP_CODE_DIR/supervisord.conf"
COPY config.example.json "$APP_CODE_DIR/config.example.json" COPY config.example.json "$APP_CODE_DIR/config.example.json"
COPY copilot.env.example "$APP_CODE_DIR/copilot.env.example"
COPY tmp_data/ "$APP_TMP_DIR/" COPY tmp_data/ "$APP_TMP_DIR/"
COPY manticore/ "$APP_CODE_DIR/manticore/" COPY manticore/ "$APP_CODE_DIR/manticore/"

View File

@@ -2,5 +2,38 @@
"$schema": "https://github.com/toeverything/AFFiNE/releases/latest/download/config.schema.json", "$schema": "https://github.com/toeverything/AFFiNE/releases/latest/download/config.schema.json",
"server": { "server": {
"name": "AFFiNE Self Hosted Server" "name": "AFFiNE Self Hosted Server"
},
"copilot": {
"enabled": true,
"scenarios": {
"override_enabled": true,
"scenarios": {
"audio_transcribing": "gemini-2.5-flash",
"chat": "gemini-2.5-flash",
"embedding": "gemini-embedding-001",
"image": "gpt-image-1",
"rerank": "gpt-4.1",
"coding": "claude-sonnet-4-5@20250929",
"complex_text_generation": "gpt-4o-2024-08-06",
"quick_decision_making": "gpt-5-mini",
"quick_text_generation": "gemini-2.5-flash",
"polish_and_summarize": "gemini-2.5-flash"
}
},
"providers.openai": {
"apiKey": "sk-provide-openai-key-here",
"baseURL": "https://api.openai.com/v1"
},
"providers.anthropic": {
"apiKey": "sk-ant-provide-anthropic-key-here",
"baseURL": "https://api.anthropic.com/v1"
},
"providers.gemini": {
"apiKey": "provide-gemini-key-here",
"baseURL": "https://generativelanguage.googleapis.com/v1beta"
},
"exa": {
"key": "provide-exa-key-or-leave-empty"
}
} }
} }

View File

@@ -1,24 +0,0 @@
# AFFiNE Copilot sample environment overrides
# Copy this file to .env (or use Cloudron's env UI) and adjust values.
# Toggle Copilot globally (true/false).
AFFINE_COPILOT_ENABLED=true
# OpenAI-compatible provider (Official OpenAI, OpenRouter, local proxy, etc.).
AFFINE_COPILOT_OPENAI_API_KEY=sk-your-openai-key
AFFINE_COPILOT_OPENAI_BASE_URL=https://api.openai.com/v1
# Anthropic Claude provider.
AFFINE_COPILOT_ANTHROPIC_API_KEY=sk-ant-your-key
AFFINE_COPILOT_ANTHROPIC_BASE_URL=https://api.anthropic.com/v1
# Google Gemini provider (API key or reverse proxy).
AFFINE_COPILOT_GEMINI_API_KEY=your-gemini-key
AFFINE_COPILOT_GEMINI_BASE_URL=https://generativelanguage.googleapis.com/v1beta
# Optional Exa web search key for Copilot browsing.
AFFINE_COPILOT_EXA_KEY=exa-key
# Override the scenario/model mapping by providing JSON.
# Example keeps override_enabled true and customizes a few models.
AFFINE_COPILOT_SCENARIOS_JSON={"override_enabled":true,"scenarios":{"chat":"gpt-4o-mini","coding":"claude-3-5-sonnet-20241022","embedding":"text-embedding-3-large","quick_text_generation":"gpt-4o-mini"}}

View File

@@ -46,13 +46,6 @@ prepare_data_dirs() {
cp "$APP_TMP_DIR/config/config.json" "$APP_DATA_DIR/config/config.json" cp "$APP_TMP_DIR/config/config.json" "$APP_DATA_DIR/config/config.json"
fi fi
local sample_env_src="$APP_CODE_DIR/copilot.env.example"
local sample_env_dest="$APP_DATA_DIR/copilot.env.example"
if [ -f "$sample_env_src" ] && [ ! -f "$sample_env_dest" ]; then
cp "$sample_env_src" "$sample_env_dest"
chown cloudron:cloudron "$sample_env_dest"
fi
local storage_contents="" local storage_contents=""
if [ -d "$APP_DATA_DIR/storage" ]; then if [ -d "$APP_DATA_DIR/storage" ]; then
storage_contents=$(ls -A "$APP_DATA_DIR/storage" 2>/dev/null || true) storage_contents=$(ls -A "$APP_DATA_DIR/storage" 2>/dev/null || true)
@@ -360,86 +353,6 @@ PY
fi fi
} }
configure_copilot_env_overrides() {
local config_path="$APP_DATA_DIR/config/config.json"
if [ ! -f "$config_path" ]; then
log "Copilot config file not found at ${config_path}, skipping env overrides"
return
fi
python3 - "$config_path" <<'PY'
import json
import os
import sys
from pathlib import Path
path = Path(sys.argv[1])
data = json.loads(path.read_text())
copilot = data.setdefault('copilot', {})
changed = False
def set_nested(keys, value):
global changed
ref = copilot
for key in keys[:-1]:
ref = ref.setdefault(key, {})
if ref.get(keys[-1]) != value:
ref[keys[-1]] = value
print(f"[copilot] Set {'.'.join(keys)} from environment")
changed = True
def coerce_bool(value):
if isinstance(value, bool):
return value
v = value.strip().lower()
if v in ('1', 'true', 'yes', 'on'):
return True
if v in ('0', 'false', 'no', 'off'):
return False
raise ValueError(f"Invalid boolean value: {value}")
mapping = [
('AFFINE_COPILOT_ENABLED', ('enabled',), coerce_bool),
('AFFINE_COPILOT_OPENAI_API_KEY', ('providers.openai', 'apiKey'), str),
('AFFINE_COPILOT_OPENAI_BASE_URL', ('providers.openai', 'baseURL'), str),
('AFFINE_COPILOT_ANTHROPIC_API_KEY', ('providers.anthropic', 'apiKey'), str),
('AFFINE_COPILOT_ANTHROPIC_BASE_URL', ('providers.anthropic', 'baseURL'), str),
('AFFINE_COPILOT_GEMINI_API_KEY', ('providers.gemini', 'apiKey'), str),
('AFFINE_COPILOT_GEMINI_BASE_URL', ('providers.gemini', 'baseURL'), str),
('AFFINE_COPILOT_EXA_KEY', ('exa', 'key'), str),
]
for env_name, path_keys, caster in mapping:
value = os.environ.get(env_name)
if not value:
continue
try:
coerced = caster(value)
except Exception as exc:
print(f"[copilot] Skipping {env_name}: {exc}", flush=True)
continue
set_nested(path_keys, coerced)
scenarios_json = os.environ.get('AFFINE_COPILOT_SCENARIOS_JSON')
if scenarios_json:
try:
payload = json.loads(scenarios_json)
if not isinstance(payload, dict) or 'scenarios' not in payload:
raise ValueError("JSON must contain a 'scenarios' object")
except Exception as exc:
print(f"[copilot] Invalid AFFINE_COPILOT_SCENARIOS_JSON: {exc}", flush=True)
else:
copilot.setdefault('scenarios', {})
copilot['scenarios']['override_enabled'] = payload.get('override_enabled', True)
copilot['scenarios']['scenarios'] = payload['scenarios']
print("[copilot] Applied scenarios override from AFFINE_COPILOT_SCENARIOS_JSON")
changed = True
if changed:
path.write_text(json.dumps(data, indent=2))
PY
log "Applied copilot env configuration overrides (if any)"
}
update_server_config() { update_server_config() {
python3 - <<'PY' python3 - <<'PY'
import json import json
@@ -472,7 +385,6 @@ main() {
configure_indexer configure_indexer
update_server_config update_server_config
configure_auth configure_auth
configure_copilot_env_overrides
chown -R cloudron:cloudron "$APP_DATA_DIR" "$APP_HOME_DIR" chown -R cloudron:cloudron "$APP_DATA_DIR" "$APP_HOME_DIR"
log "Starting supervisor" log "Starting supervisor"
exec /usr/bin/supervisord -c "$APP_CODE_DIR/supervisord.conf" exec /usr/bin/supervisord -c "$APP_CODE_DIR/supervisord.conf"

View File

@@ -2,5 +2,38 @@
"$schema": "https://github.com/toeverything/AFFiNE/releases/latest/download/config.schema.json", "$schema": "https://github.com/toeverything/AFFiNE/releases/latest/download/config.schema.json",
"server": { "server": {
"name": "AFFiNE Self Hosted Server" "name": "AFFiNE Self Hosted Server"
},
"copilot": {
"enabled": true,
"scenarios": {
"override_enabled": true,
"scenarios": {
"audio_transcribing": "gemini-2.5-flash",
"chat": "gemini-2.5-flash",
"embedding": "gemini-embedding-001",
"image": "gpt-image-1",
"rerank": "gpt-4.1",
"coding": "claude-sonnet-4-5@20250929",
"complex_text_generation": "gpt-4o-2024-08-06",
"quick_decision_making": "gpt-5-mini",
"quick_text_generation": "gemini-2.5-flash",
"polish_and_summarize": "gemini-2.5-flash"
}
},
"providers.openai": {
"apiKey": "sk-provide-openai-key-here",
"baseURL": "https://api.openai.com/v1"
},
"providers.anthropic": {
"apiKey": "sk-ant-provide-anthropic-key-here",
"baseURL": "https://api.anthropic.com/v1"
},
"providers.gemini": {
"apiKey": "provide-gemini-key-here",
"baseURL": "https://generativelanguage.googleapis.com/v1beta"
},
"exa": {
"key": "provide-exa-key-or-leave-empty"
}
} }
} }