diff --git a/docs.json b/docs.json
index 0a4e3539..6e8677da 100644
--- a/docs.json
+++ b/docs.json
@@ -35,6 +35,78 @@
{
"source": "/zh/about",
"destination": "/zh/basic/ai/overview"
+ },
+ {
+ "source": "/en/deploy/production-overview",
+ "destination": "/en/deploy/choose"
+ },
+ {
+ "source": "/zh/deploy/production-overview",
+ "destination": "/zh/deploy/choose"
+ },
+ {
+ "source": "/en/deploy/k8s",
+ "destination": "/en/deploy/choose"
+ },
+ {
+ "source": "/zh/deploy/k8s",
+ "destination": "/zh/deploy/choose"
+ },
+ {
+ "source": "/en/deploy/aws",
+ "destination": "/en/deploy/choose"
+ },
+ {
+ "source": "/zh/deploy/aws",
+ "destination": "/zh/deploy/choose"
+ },
+ {
+ "source": "/en/deploy/azure",
+ "destination": "/en/deploy/choose"
+ },
+ {
+ "source": "/zh/deploy/azure",
+ "destination": "/zh/deploy/choose"
+ },
+ {
+ "source": "/en/deploy/gcp",
+ "destination": "/en/deploy/choose"
+ },
+ {
+ "source": "/zh/deploy/gcp",
+ "destination": "/zh/deploy/choose"
+ },
+ {
+ "source": "/en/deploy/one-key",
+ "destination": "/en/deploy/choose"
+ },
+ {
+ "source": "/zh/deploy/one-key",
+ "destination": "/zh/deploy/choose"
+ },
+ {
+ "source": "/en/deploy/storage",
+ "destination": "/en/deploy/env"
+ },
+ {
+ "source": "/zh/deploy/storage",
+ "destination": "/zh/deploy/env"
+ },
+ {
+ "source": "/en/deploy/database-connection",
+ "destination": "/en/deploy/env"
+ },
+ {
+ "source": "/zh/deploy/database-connection",
+ "destination": "/zh/deploy/env"
+ },
+ {
+ "source": "/en/deploy/agent-runtime",
+ "destination": "/en/deploy/architecture"
+ },
+ {
+ "source": "/zh/deploy/agent-runtime",
+ "destination": "/zh/deploy/architecture"
}
],
"navigation": {
@@ -295,8 +367,8 @@
{
"group": "Quick Start",
"pages": [
- "en/deploy/docker",
- "en/deploy/one-key"
+ "en/deploy/choose",
+ "en/deploy/architecture"
]
},
{
@@ -315,27 +387,12 @@
"en/basic/admin-panel/multitenancy"
]
},
- {
- "group": "Production Deployment",
- "pages": [
- "en/deploy/production-overview",
- "en/deploy/agent-runtime",
- "en/deploy/k8s",
- "en/deploy/aws",
- "en/deploy/azure",
- "en/deploy/gcp"
- ]
- },
{
"group": "Configuration",
"pages": [
"en/deploy/env",
- "en/deploy/storage",
"en/deploy/email",
- "en/deploy/database-connection",
- "en/deploy/oidc",
- "en/deploy/nginx",
- "en/deploy/dashboard"
+ "en/deploy/oidc"
]
},
{
@@ -659,8 +716,8 @@
{
"group": "快速开始",
"pages": [
- "zh/deploy/docker",
- "zh/deploy/one-key"
+ "zh/deploy/choose",
+ "zh/deploy/architecture"
]
},
{
@@ -679,27 +736,12 @@
"zh/basic/admin-panel/multitenancy"
]
},
- {
- "group": "生产环境部署",
- "pages": [
- "zh/deploy/production-overview",
- "zh/deploy/agent-runtime",
- "zh/deploy/k8s",
- "zh/deploy/aws",
- "zh/deploy/azure",
- "zh/deploy/gcp"
- ]
- },
{
"group": "配置",
"pages": [
"zh/deploy/env",
- "zh/deploy/storage",
"zh/deploy/email",
- "zh/deploy/database-connection",
- "zh/deploy/oidc",
- "zh/deploy/nginx",
- "zh/deploy/dashboard"
+ "zh/deploy/oidc"
]
},
{
diff --git a/en/api-doc/sql-query.mdx b/en/api-doc/sql-query.mdx
index 42cda7ba..8523c0d1 100644
--- a/en/api-doc/sql-query.mdx
+++ b/en/api-doc/sql-query.mdx
@@ -4,7 +4,7 @@ noindex: true
---
-**Self-hosted only**: Available for all versions with unlimited connections. For setup, see [Database Connection](/en/deploy/database-connection).
+**Self-hosted only**: Available for all versions with unlimited connections.
Teable allows you to connect to its underlying PostgreSQL database through external tools for read-only queries. This enables integration with BI tools (PowerBI, Metabase, Superset), database clients (DataGrip, Navicat, TablePlus), low-code platforms (Appsmith, Budibase), and application code.
diff --git a/en/basic/admin-panel/ai-setting.mdx b/en/basic/admin-panel/ai-setting.mdx
index 0a1be64b..715d640d 100644
--- a/en/basic/admin-panel/ai-setting.mdx
+++ b/en/basic/admin-panel/ai-setting.mdx
@@ -12,7 +12,7 @@ The **AI Settings** page is used to configure **AI Chat**, **AI fields**, **AI a
## Before you start
-Before you open the AI Settings page, make sure the following items are ready. For self-hosted AI Chat and App Builder, first follow [Agent Runtime Deployment](/en/deploy/agent-runtime).
+Before you open the AI Settings page, make sure the following items are ready. For self-hosted AI Chat and App Builder, first deploy the runtime plane — see [Architecture](/en/deploy/architecture).
| Requirement | Required? | Notes |
|------|------|------|
@@ -77,7 +77,7 @@ To let users use the microphone in AI Chat, enable voice input and enter the **O
### Configure Agent Runtime and App Builder
-Self-hosted **AI Chat** and **App Builder** require Agent Runtime setup and a compatible chat model. When you use your own key (BYOK), the chat model must come from an **OpenAI Compatible** or **Anthropic** provider. Self-hosted Agent Runtime is still in an early stage, and setup can be complex. Follow [Agent Runtime Deployment](/en/deploy/agent-runtime), which will continue to evolve based on deployment feedback. For assistance, contact **support@teable.ai**.
+Self-hosted **AI Chat** and **App Builder** require Agent Runtime setup and a compatible chat model. When you use your own key (BYOK), the chat model must come from an **OpenAI Compatible** or **Anthropic** provider. Deploy the runtime plane first — see [Architecture](/en/deploy/architecture) and the [teable-deployment](https://github.com/teableio/teable-deployment) repository. For assistance, contact **support@teable.ai**.
@@ -125,7 +125,7 @@ Check the **Pending configuration** panel first to see which item is still missi
-Check whether the current deployment has completed [Agent Runtime Deployment](/en/deploy/agent-runtime), including the required Teable environment variables. For assistance, contact **support@teable.ai**.
+Check whether the runtime plane is deployed and connected (see [Architecture](/en/deploy/architecture)), including the required Teable environment variables — the deployment's doctor script verifies the whole chain. For assistance, contact **support@teable.ai**.
diff --git a/en/basic/admin-panel/sandbox-agent.mdx b/en/basic/admin-panel/sandbox-agent.mdx
index 8359932a..734a0e63 100644
--- a/en/basic/admin-panel/sandbox-agent.mdx
+++ b/en/basic/admin-panel/sandbox-agent.mdx
@@ -10,7 +10,7 @@ Path: Admin Panel → Sandbox Agent
The **Sandbox Agent** page contains **Settings** and **Sandboxes** tabs for configuring how AI Chat runs in sandboxes.
-For self-hosted setup, complete [Agent Runtime Deployment](/en/deploy/agent-runtime) before configuring this page.
+For self-hosted setup, deploy the full-featured runtime plane first — see [Architecture](/en/deploy/architecture).
## Runtime Limits
diff --git a/en/basic/ai/app-builder.mdx b/en/basic/ai/app-builder.mdx
index b1bca78b..efb055fd 100644
--- a/en/basic/ai/app-builder.mdx
+++ b/en/basic/ai/app-builder.mdx
@@ -231,7 +231,7 @@ For prompt patterns, build tips, rollback advice, and common troubleshooting, se
- If you are running Teable self-hosted, follow the setup on the [AI Settings](/en/basic/admin-panel/ai-setting) page. If App Builder uses your own key (BYOK), the chat model must come from an **OpenAI Compatible** or **Anthropic** provider. Agent Runtime deployment is still in an early stage and can be complex. Contact Teable at **support@teable.ai** for deployment support.
+ If you are running Teable self-hosted, follow the setup on the [AI Settings](/en/basic/admin-panel/ai-setting) page. If App Builder uses your own key (BYOK), the chat model must come from an **OpenAI Compatible** or **Anthropic** provider. For deployment support, contact Teable at **support@teable.ai**.
Before publishing, make sure both your Teable instance and object storage (MinIO / S3) are publicly accessible. If you are unsure, use **Test Public Access** on the [AI Settings](/en/basic/admin-panel/ai-setting) page.
diff --git a/en/deploy/activate.mdx b/en/deploy/activate.mdx
index 121eda19..3a9e60f0 100644
--- a/en/deploy/activate.mdx
+++ b/en/deploy/activate.mdx
@@ -25,8 +25,7 @@ Before subscribing to a plan, you need to have Teable installed and running on y
If you haven't installed Teable yet, please follow one of these installation guides:
- [Docker Deployment](/en/deploy/docker) (Recommended for quick setup)
-- [Kubernetes Deployment](/en/deploy/k8s) (For production environments)
-- [One-Click Cloud Deployment](/en/deploy/one-key) (Template-based setup)
+- [Full-featured platform](/en/deploy/architecture) (AI features and App Builder, Docker or Kubernetes)
Make sure your Teable instance is up and running before proceeding to the next steps.
diff --git a/en/deploy/agent-runtime.mdx b/en/deploy/agent-runtime.mdx
deleted file mode 100644
index 48197157..00000000
--- a/en/deploy/agent-runtime.mdx
+++ /dev/null
@@ -1,778 +0,0 @@
----
-title: "Agent Runtime Deployment"
-description: "Deploy a self-hosted Teable Agent Runtime stack on a Linux server with Docker Compose."
----
-
-Available for self-hosted Business plan and above
-
-Teable Agent Runtime provides the sandbox and app runtime services used by **AI Chat** and **App Builder**. This guide deploys the complete stack on a single Linux server with Docker Compose.
-
-The deployment includes the AI sandbox engine, App Runtime, git repository service, artifact storage, and TLS gateway. Kubernetes and an additional source repository are not required because every configuration file is included below.
-
-
-Self-hosted Agent Runtime is still in an early stage. This guide is intended for early adopters and will continue to evolve based on deployment feedback. The current runtime uses OpenSandbox through Teable Infra and does not use Vercel Sandbox or Vercel snapshots. For deployment assistance, contact **support@teable.ai**.
-
-
-Use the complete stack when you need App Builder previews and deployed apps. Running only `opensandbox-server` does not provide the app runtime, git registry, artifact storage, or gateway required by App Builder.
-
-## Architecture
-
-Only the Caddy gateway exposes ports 80 and 443 to the public network. All other services stay inside internal Docker networks.
-
-| Service | Description | Internal port |
-|---|---|---|
-| **caddy** | TLS termination and routing for the console, sandbox and app previews, S3, and git | Public 80/443 |
-| **opensandbox-server** | AI sandbox engine in Docker mode. It uses the host `docker.sock` to create sandbox containers on demand. | 8090 |
-| **infra-service** | Console UI, Infra API, App Runtime Docker backend, and built-in app gateway | 8080 |
-| **git-registry** | Git smart-http service for App Builder. It uses the same image as `infra-service`. | 8080 |
-| **minio** *(optional)* | Built-in S3-compatible artifact storage. Can be replaced with external S3. See [Choose Artifact Storage](#choose-artifact-storage). | 9000 / 9001 |
-| **minio-init** *(optional)* | One-time task that waits for MinIO to become ready and creates the artifact bucket | N/A |
-
-Domain routes are derived from the root `BASE_DOMAIN`.
-
-| Address | Purpose |
-|---|---|
-| `https://` | Console UI, Infra API, and sandbox engine API under `/v1/*` |
-| `https://{appId}.app.` | Entry point for deployed apps |
-| `https://{sandboxId}-{port}.sandbox.` | Sandbox port preview |
-| `https://s3.` | Artifact storage in built-in MinIO mode. Presigned URLs point here. |
-| `https://git.` | Git smart-http endpoint, optional for manual external clone |
-
-## Before You Begin
-
-### Server Requirements
-
-| | Minimum | Recommended |
-|---|---|---|
-| vCPU | 4 | 8 |
-| Memory | 8 GB | 16 GB |
-| Disk | 80 GB NVMe | 120+ GB NVMe |
-| OS | Ubuntu 22.04/24.04 (x86_64) | Ubuntu 22.04/24.04 (x86_64) |
-| Software | Docker Engine 24+, Docker Compose v2.24+, OpenSSL | Docker Engine 24+, Docker Compose v2.24+, OpenSSL |
-
-Capacity notes: each active build session runs one sandbox container with a limit of 2 vCPU and 4 GiB. Each deployed app also has a limit of 2 vCPU and 4 GiB, though typical usage is only a few hundred MB. The base services use about 1 to 1.5 GiB of memory. Disk usage mainly comes from container images, about 15 to 20 GB after warm-up, plus writable layers for sandboxes and apps. Monitor free disk space.
-
-### DNS and Firewall
-
-Add **4 A records** at your DNS provider. All records must point to the server public IP. A wildcard certificate only covers one subdomain level, so all 4 records are required.
-
-```text
- A ->
-*. A ->
-*.app. A ->
-*.sandbox. A ->
-```
-
-If the domain is hosted on Cloudflare, set these 4 records to **DNS only (gray cloud)**, not **Proxied (orange cloud)**.
-
-Only allow inbound **22 (SSH), 80, and 443** in the firewall. Do not expose other ports.
-
-### Container Images
-
-This deployment uses **GHCR + Docker Hub** by default. **All images are public and do not require `docker login`**. For Teable images, `` is not a fixed value. Open each corresponding GHCR package page and use the release tag shown in that package page's Installation command. Confirm the tag for each image separately. Do not assume the tags are the same across images.
-
-#### Images Managed by Docker Compose
-
-These images are pulled and started by `docker compose up`.
-
-| Purpose | Image template | Package page |
-|---|---|---|
-| Console, Infra API, and App Runtime. `infra-service` and `git-registry` use the same image. The latter only uses a different startup entry point. | `ghcr.io/teableio/teable-infra-service:` | [GHCR](https://github.com/orgs/teableio/packages/container/package/teable-infra-service) |
-| AI sandbox engine, OpenSandbox in Docker runtime mode, Teable build | `ghcr.io/teableio/opensandbox-server:` | [GHCR](https://github.com/orgs/teableio/packages/container/package/opensandbox-server) |
-| TLS edge gateway. The official image is used for static certificate mode. Cloudflare mode requires a local build, see [Choose a TLS Mode](#choose-a-tls-mode). | `caddy:2.9.1` | [Docker Hub](https://hub.docker.com/_/caddy) |
-| Built-in artifact storage, only used in built-in MinIO mode. Pinning by digest is recommended for production. | `minio/minio:latest` | [Docker Hub](https://hub.docker.com/r/minio/minio) |
-| One-time bucket creation tool, only used in built-in MinIO mode | `minio/mc:latest` | [Docker Hub](https://hub.docker.com/r/minio/mc) |
-
-#### Runtime Images
-
-These images are not started by compose directly. The services use the host `docker.sock` to create containers from them on demand. They are public images and can be pulled anonymously by the Docker daemon. Pre-pulling them as described in [Pre-pull Runtime Images](#pre-pull-runtime-images) is recommended to avoid first-use latency when creating the first sandbox or deploying the first app.
-
-| Purpose | Image template | Package page |
-|---|---|---|
-| Sandbox base image. Each AI build session runs inside this image. | `ghcr.io/teableio/teable-sandbox-agent:` | [GHCR](https://github.com/orgs/teableio/packages/container/package/teable-sandbox-agent) |
-| App runtime base image. Each deployed app container uses this image. Apps cannot be deployed if this is not configured. | `ghcr.io/teableio/teable-app-runtime:` | [GHCR](https://github.com/orgs/teableio/packages/container/package/teable-app-runtime) |
-| Sandbox execution agent `execd`, injected by the engine into each sandbox container | `ghcr.io/teableio/opensandbox-execd:v1.0.19-fix-1064` | [GHCR](https://github.com/orgs/teableio/packages/container/package/opensandbox-execd) |
-| Sandbox outbound network sidecar, egress in DNS mode, created by the engine for each sandbox as needed | `opensandbox/egress:v1.0.12` | [Docker Hub](https://hub.docker.com/r/opensandbox/egress) |
-
-Use the Teable-built fixed version of execd shown above, `opensandbox-execd:v1.0.19-fix-1064`. Do not replace it with the upstream `opensandbox/execd` image.
-
-### Choose Artifact Storage
-
-| Mode | Configuration | Notes |
-|---|---|---|
-| **Built-in MinIO** (default) | Leave `S3_ENDPOINT` empty in `.env`, keep `COMPOSE_PROFILES=minio` | MinIO starts automatically and the bucket is created. Presigned URLs use `https://s3.`. |
-| **External S3** | Set `S3_ENDPOINT` to the provider URL and set `COMPOSE_PROFILES=` to empty | Built-in MinIO no longer starts. `S3_ACCESS_KEY`, `S3_SECRET_KEY`, and `S3_BUCKET` must use provider-issued values. The bucket must already exist. If the provider only supports virtual-host style, set `S3_FORCE_PATH_STYLE=false`. |
-
-## Create the Deployment Files
-
-### Deployment Directory
-
-Create a deployment directory on the server. This guide uses `teable-runtime/` as the example directory. The [Configuration Files](#configuration-files) section contains the full contents of the first four files.
-
-```text
-teable-runtime/
-|-- .env # Edit for your environment
-|-- compose.yaml # Service composition, copy as is
-|-- Caddyfile # Gateway routing, adjust two places for the TLS mode
-|-- opensandbox.toml # Sandbox engine configuration, copy as is
-|-- compose.override.yaml # Generated during deployment, Git service signing key
-|-- certs/ # Static certificate mode only
-| |-- fullchain.pem
-| `-- privkey.pem
-`-- Dockerfile.caddy # Cloudflare TLS mode only
-```
-
-The files containing secrets are `.env` and `compose.override.yaml`. Do not share them externally or commit them to a repository.
-
-### Configuration Files
-
-#### `.env`
-
-```bash .env
-# ============================================================================
-# Teable Agent Runtime environment configuration.
-# This is the only file that needs environment-specific changes.
-# Generate secrets with commands such as `openssl rand -hex 32`.
-# ============================================================================
-
-# === Domain and TLS ===
-# Deployment root domain. The `app.`, `sandbox.`, `s3.`, and `git.` subdomains are derived from it.
-BASE_DOMAIN=teable.example.com
-# Console access host. Usually the same as BASE_DOMAIN. Use another host only if needed.
-INFRA_HOST=teable.example.com
-# Only used in Cloudflare TLS mode. Leave empty in static mode.
-ACME_EMAIL=
-CLOUDFLARE_API_TOKEN=
-
-# === Secrets ===
-# Shared API key for engine auth, Infra API, console login, and internal git calls.
-OPENSANDBOX_API_KEY=
-# Console session signing secret.
-SESSION_SECRET=
-# Built-in MinIO: generated values become the MinIO root account.
-# External S3: use the access key and secret key issued by the provider.
-S3_ACCESS_KEY=
-S3_SECRET_KEY=
-
-# === Images, all public, docker login is not required ===
-# Copy each Teable image from the Installation command on its own GHCR package page.
-# infra-service and git-registry use the same image.
-INFRA_SERVICE_IMAGE=ghcr.io/teableio/teable-infra-service:
-# Sandbox engine.
-OPENSANDBOX_SERVER_IMAGE=ghcr.io/teableio/opensandbox-server:
-# Sandbox base image. Each AI build session runs inside this image.
-SANDBOX_OPENSANDBOX_IMAGE=ghcr.io/teableio/teable-sandbox-agent:
-# App runtime base image. Apps cannot be deployed if this is not configured.
-APP_RUNTIME_DEFAULT_IMAGE=ghcr.io/teableio/teable-app-runtime:
-# Allowlist of app image prefixes, comma-separated. Must cover the default image prefix above.
-APP_RUNTIME_ALLOWED_IMAGE_PREFIXES=ghcr.io/teableio/
-
-# TLS gateway image. Static mode uses the official image.
-# Cloudflare mode uses the locally built teable-caddy-cloudflare:2.9.1 image.
-# See the TLS instructions below.
-CADDY_IMAGE=caddy:2.9.1
-# Third-party images default to :latest. Pinning by digest is recommended for production, for example:
-# MINIO_IMAGE=minio/minio@sha256:...
-# MINIO_MC_IMAGE=minio/mc@sha256:...
-
-# === Artifact storage, S3 / MinIO ===
-# "minio" enables built-in MinIO. Leave empty when using external S3.
-COMPOSE_PROFILES=minio
-# Empty means built-in MinIO, with presigned URLs served from https://s3..
-# Set this to an external S3-compatible endpoint URL, for example https://s3.your-provider.com,
-# to use external storage. Also set COMPOSE_PROFILES above to empty and create the bucket
-# on the provider side before deployment.
-S3_ENDPOINT=
-S3_BUCKET=teable-app-artifacts
-S3_REGION=us-east-1
-# Built-in MinIO requires true. Set false only if the external S3 provider supports
-# virtual-host style only.
-S3_FORCE_PATH_STYLE=true
-
-# === Docker networks ===
-# Usually no change is needed. SANDBOX_DOCKER_NETWORK must match network_mode in opensandbox.toml.
-APP_RUNTIME_DOCKER_NETWORK=teable-appnet
-SANDBOX_DOCKER_NETWORK=teable-sandbox-net
-```
-
-#### `compose.yaml`
-
-Copy this file as is. All environment-specific values are loaded from `.env`.
-
-```yaml compose.yaml
-# Teable Agent Runtime, single-node Docker stack.
-name: teable-agent-runtime
-
-networks:
- # Control-plane network. infra-service and the app containers it starts are attached
- # to this network so the built-in gateway can reach apps by IP.
- teable-appnet:
- name: ${APP_RUNTIME_DOCKER_NETWORK:-teable-appnet}
- driver: bridge
- # Sandbox-only network. Sandboxes are created in this network and isolated from
- # the control plane. opensandbox-server also joins it so it can reach sandboxes by IP.
- teable-sandbox-net:
- name: ${SANDBOX_DOCKER_NETWORK:-teable-sandbox-net}
- driver: bridge
-
-volumes:
- opensandbox-state:
- infra-state:
- git-registry-data:
- minio-data:
- caddy-data: # TLS certificates and ACME account. Must be persistent.
- caddy-config:
- # Agent shared workspace. external means it must be created manually first:
- # docker volume create teable-agent-juicefs
- teable-agent-juicefs:
- external: true
-
-services:
- # AI sandbox engine in Docker mode.
- opensandbox-server:
- image: ${OPENSANDBOX_SERVER_IMAGE:?set in .env}
- container_name: opensandbox-server
- restart: unless-stopped
- networks: [teable-appnet, teable-sandbox-net]
- volumes:
- - /var/run/docker.sock:/var/run/docker.sock # Create sandboxes on the host.
- - ./opensandbox.toml:/etc/opensandbox/config.toml:ro
- - opensandbox-state:/data
- environment:
- SANDBOX_CONFIG_PATH: /etc/opensandbox/config.toml
- # API key is injected through the environment. It is not written into toml.
- OPENSANDBOX_SERVER_API_KEY: ${OPENSANDBOX_API_KEY:?set in .env}
-
- # Console UI, Infra API, App Runtime Docker backend, and built-in app gateway.
- infra-service:
- image: ${INFRA_SERVICE_IMAGE:?set in .env}
- container_name: infra-service
- restart: unless-stopped
- networks: [teable-appnet]
- volumes:
- - /var/run/docker.sock:/var/run/docker.sock # Start and manage app containers.
- - infra-state:/var/lib/teable-app-runtime
- - teable-agent-juicefs:/mnt/juicefs
- environment:
- # --- Backend selection ---
- APP_RUNTIME_BACKEND: docker
- K8S_IN_CLUSTER: "false"
- PORT: "8080"
- # --- Auth and session, one shared key for the stack ---
- AUTH_PROVIDER: api-key
- SESSION_SECRET: ${SESSION_SECRET:?set in .env}
- OPENSANDBOX_API_KEY: ${OPENSANDBOX_API_KEY:?set in .env}
- INFRA_API_KEY: ${OPENSANDBOX_API_KEY}
- # --- Sandbox engine ---
- OPENSANDBOX_RUNTIME_URL: http://opensandbox-server:8090
- SANDBOX_OPENSANDBOX_IMAGE: ${SANDBOX_OPENSANDBOX_IMAGE:?set in .env}
- OPENSANDBOX_PREVIEW_WILDCARD_DOMAIN: "*.sandbox.${BASE_DOMAIN}"
- # --- App Runtime, Docker backend ---
- APP_RUNTIME_DOCKER_SOCKET_PATH: /var/run/docker.sock
- APP_RUNTIME_DOCKER_NETWORK: ${APP_RUNTIME_DOCKER_NETWORK:-teable-appnet}
- APP_RUNTIME_STATE_DIR: /var/lib/teable-app-runtime
- APP_RUNTIME_INGRESS_MODE: gateway
- APP_RUNTIME_HOST_MATCH_MODE: suffix
- APP_RUNTIME_DOMAIN: app.${BASE_DOMAIN:?set in .env} # Apps run at {appId}.app..
- APP_RUNTIME_PUBLIC_SCHEME: https
- APP_RUNTIME_DEFAULT_IMAGE: ${APP_RUNTIME_DEFAULT_IMAGE:-}
- APP_RUNTIME_ALLOWED_IMAGE_PREFIXES: ${APP_RUNTIME_ALLOWED_IMAGE_PREFIXES:-ghcr.io/teableio/}
- APP_RUNTIME_ARTIFACT_PUBLIC_ORIGIN: http://infra-service:8080 # App containers fetch artifacts through the internal service name.
- # --- Artifact storage, S3 / built-in MinIO ---
- APP_RUNTIME_ARTIFACT_STORE_PROVIDER: s3
- APP_RUNTIME_ARTIFACT_S3_ENDPOINT: ${S3_ENDPOINT:-https://s3.${BASE_DOMAIN}}
- APP_RUNTIME_ARTIFACT_BUCKET: ${S3_BUCKET:-teable-app-artifacts}
- APP_RUNTIME_ARTIFACT_S3_REGION: ${S3_REGION:-us-east-1}
- APP_RUNTIME_ARTIFACT_S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY:?set in .env}
- APP_RUNTIME_ARTIFACT_S3_ACCESS_KEY_SECRET: ${S3_SECRET_KEY:?set in .env}
- APP_RUNTIME_ARTIFACT_S3_FORCE_PATH_STYLE: ${S3_FORCE_PATH_STYLE:-true}
- # --- Git registry, JWT key injected through compose.override.yaml ---
- GIT_REGISTRY_ENABLED: "true"
- GIT_REGISTRY_INTERNAL_URL: http://git-registry:8080
- GIT_REGISTRY_SANDBOX_URL: http://git-registry:8080 # Sandboxes clone through the internal network.
- GIT_REGISTRY_PUBLIC_URL: https://git.${BASE_DOMAIN} # Only for external or manual clone.
- # --- File browser and S3-compatible API ---
- FILE_BROWSER_ENABLED: "true"
- FILE_BROWSER_ROOT: /mnt/juicefs
- S3_COMPAT_ENABLED: "true"
- healthcheck:
- test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:8080/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
- interval: 30s
- timeout: 5s
- retries: 5
- start_period: 40s
- depends_on:
- opensandbox-server:
- condition: service_started
- minio-init: # Wait for the artifact bucket to be created.
- condition: service_completed_successfully
- required: false # Ignored when MinIO profile is disabled in external S3 mode.
-
- # Git smart-http service for App Builder. It uses the same image as infra-service,
- # with a different startup entry point.
- git-registry:
- image: ${INFRA_SERVICE_IMAGE:?set in .env}
- container_name: git-registry
- restart: unless-stopped
- command: ["node", ".output/git-registry/server.mjs"]
- networks: [teable-appnet, teable-sandbox-net] # sandbox-net lets sandboxes clone directly through the internal network.
- volumes:
- - git-registry-data:/data
- environment:
- GIT_REGISTRY_PORT: "8080"
- GIT_REGISTRY_DATA_DIR: /data
- GIT_REGISTRY_INTERNAL_API_KEY: ${OPENSANDBOX_API_KEY:?set in .env}
- # GIT_REGISTRY_JWT_PUBLIC_KEY is injected through compose.override.yaml.
- healthcheck:
- test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:8080/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
- interval: 30s
- timeout: 5s
- retries: 5
- start_period: 20s
-
- # Built-in artifact storage, profile "minio". Disabled in external S3 mode.
- minio:
- profiles: ["minio"]
- image: ${MINIO_IMAGE:-minio/minio:latest}
- container_name: minio
- restart: unless-stopped
- networks: [teable-appnet]
- command: server /data --console-address ":9001"
- volumes:
- - minio-data:/data
- environment:
- MINIO_ROOT_USER: ${S3_ACCESS_KEY:?set in .env}
- MINIO_ROOT_PASSWORD: ${S3_SECRET_KEY:?set in .env}
- MINIO_REGION: ${S3_REGION:-us-east-1}
- # One-time bucket creation task. infra-service uses it as a startup gate.
- minio-init:
- profiles: ["minio"]
- image: ${MINIO_MC_IMAGE:-minio/mc:latest}
- container_name: minio-init
- restart: "no"
- networks: [teable-appnet]
- depends_on:
- - minio
- entrypoint: ["/bin/sh", "-c"]
- command:
- - >
- until mc alias set local http://minio:9000 "$$S3_ACCESS_KEY" "$$S3_SECRET_KEY" >/dev/null 2>&1; do
- echo 'waiting for minio...'; sleep 2;
- done;
- mc mb --ignore-existing "local/$$S3_BUCKET";
- echo "bucket $$S3_BUCKET ready";
- environment:
- S3_ACCESS_KEY: ${S3_ACCESS_KEY:?set in .env}
- S3_SECRET_KEY: ${S3_SECRET_KEY:?set in .env}
- S3_BUCKET: ${S3_BUCKET:-teable-app-artifacts}
-
- # TLS edge and routing. This is the only service exposed to the public network.
- caddy:
- image: ${CADDY_IMAGE:-caddy:2.9.1}
- container_name: caddy
- restart: unless-stopped
- networks:
- teable-appnet:
- aliases:
- - s3.${BASE_DOMAIN} # Let infra-service reach Caddy by the presigned URL host inside the container network.
- ports:
- - "80:80" # ACME + http to https redirect
- - "443:443"
- - "443:443/udp" # HTTP/3 QUIC, optional
- volumes:
- - ./Caddyfile:/etc/caddy/Caddyfile:ro
- - ./certs:/certs:ro # Certificate files for static TLS mode. Empty directory is harmless in Cloudflare mode.
- - caddy-data:/data
- - caddy-config:/config
- environment:
- BASE_DOMAIN: ${BASE_DOMAIN:?set in .env}
- INFRA_HOST: ${INFRA_HOST:?set in .env}
- ACME_EMAIL: ${ACME_EMAIL:-} # Cloudflare mode only
- CLOUDFLARE_API_TOKEN: ${CLOUDFLARE_API_TOKEN:-} # Cloudflare mode only
- OPENSANDBOX_API_KEY: ${OPENSANDBOX_API_KEY:?set in .env} # Server-side injection for sandbox preview requests
- SANDBOX_PREVIEW_HOST: sandbox.${BASE_DOMAIN}
- depends_on:
- # Caddy is not gated on upstream health. It should start early for ACME.
- # reverse_proxy retries automatically while upstream services are not ready.
- opensandbox-server:
- condition: service_started
- infra-service:
- condition: service_started
- minio:
- condition: service_started
- required: false # MinIO is disabled in external S3 mode.
- git-registry:
- condition: service_started
-```
-
-#### `Caddyfile`
-
-The file is written for **static** certificate mode by default. For **cloudflare** mode, make the two changes described in the file header and under [Choose a TLS Mode](#choose-a-tls-mode).
-
-```caddyfile Caddyfile
-# Teable Agent Runtime edge gateway.
-# Default TLS mode: "static", using a self-provided wildcard certificate mounted at /certs.
-# To switch to "cloudflare" mode, DNS-01 automatic issuance:
-# 1. Uncomment the global block below.
-# 2. Delete the `tls /certs/...` line in the (site_tls) snippet.
-
-# {
-# email {$ACME_EMAIL}
-# acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
-# }
-
-# Site-level TLS for static mode. Leave this snippet empty in Cloudflare mode.
-(site_tls) {
- tls /certs/fullchain.pem /certs/privkey.pem
-}
-
-# Console, Infra API, and sandbox endpoint preview rewrite.
-# The engine endpoint preview API, /v1/sandboxes/{id}/endpoints/{port},
-# is rewritten to a root-path subdomain:
-# {id}-{port}.sandbox., without scheme. The consumer adds the scheme.
-(infra_and_v1) {
- @endpoints path_regexp ep ^/v1/sandboxes/([a-z0-9-]+)/endpoints/([0-9]+)/?$
- handle @endpoints {
- header Content-Type application/json
- respond `{"endpoint":"{re.ep.1}-{re.ep.2}.{$SANDBOX_PREVIEW_HOST}"}` 200
- }
- # Sandbox engine API, auth header is passed through.
- handle /v1/* {
- reverse_proxy opensandbox-server:8090
- }
- # Console / Infra API. App preview also lands here and is routed by the built-in gateway by Host.
- handle {
- reverse_proxy infra-service:8080
- }
-}
-
-# Sandbox preview. Each sandbox + port has a separate origin:
-# Host = {id}-{port}.sandbox. -> engine server-proxy.
-# The API key is injected server-side because browser top-level navigation cannot send custom headers.
-# Accept-Encoding=identity disables compression to avoid multi-hop decoding issues.
-# WebSocket is passed through by default.
-(sandbox_preview) {
- @sbx header_regexp sbx Host ^([a-z0-9-]+)-([0-9]+)\.
- handle @sbx {
- rewrite * /v1/sandboxes/{re.sbx.1}/proxy/{re.sbx.2}{uri}
- reverse_proxy opensandbox-server:8090 {
- header_up OPEN-SANDBOX-API-KEY {env.OPENSANDBOX_API_KEY}
- header_up Accept-Encoding identity
- }
- }
- handle {
- respond 404
- }
-}
-
-# ---- Sites ----
-
-# Console, Infra API, and engine API. Teable's TEABLE_INFRA_API_URL points here.
-{$INFRA_HOST} {
- import site_tls
- import infra_and_v1
-}
-
-# Deployed apps
-*.app.{$BASE_DOMAIN} {
- import site_tls
- reverse_proxy infra-service:8080
-}
-
-# Sandbox preview
-*.sandbox.{$BASE_DOMAIN} {
- import site_tls
- import sandbox_preview
-}
-
-# Artifact storage. Used in built-in MinIO mode. The presigned URL host matches this site.
-# In external S3 mode, this block is idle and harmless.
-s3.{$BASE_DOMAIN} {
- import site_tls
- reverse_proxy minio:9000
-}
-
-# Git smart-http. Optional, only for external manual clone.
-git.{$BASE_DOMAIN} {
- import site_tls
- reverse_proxy git-registry:8080
-}
-```
-
-#### `opensandbox.toml`
-
-Copy this file as is.
-
-```toml opensandbox.toml
-# OpenSandbox engine configuration, Docker runtime mode.
-# API key is not written in this file. It is injected by compose through
-# OPENSANDBOX_SERVER_API_KEY.
-
-[server]
-host = "0.0.0.0"
-port = 8090
-api_key = "" # Injected from env. Leave empty.
-max_sandbox_timeout_seconds = 86400
-
-[runtime]
-type = "docker"
-# execd is the execution agent injected into each sandbox container.
-# Use the Teable-built fixed image. Do not replace it with the upstream image.
-execd_image = "ghcr.io/teableio/opensandbox-execd:v1.0.19-fix-1064"
-
-[store]
-type = "sqlite"
-path = "/data/opensandbox.db" # Stored in the opensandbox-state volume.
-
-[storage]
-allowed_host_paths = [] # Bind-mount allowlist. Empty means allow all. Lock this down for production.
-volume_default_size = "1Gi"
-
-[docker]
-# Must match SANDBOX_DOCKER_NETWORK in .env, the sandbox network created by compose.
-# The engine reaches sandboxes by container IP in this network.
-network_mode = "teable-sandbox-net"
-host_ip = "127.0.0.1" # Direct port mapping binds to loopback. Preview always goes through Caddy.
-drop_capabilities = ["AUDIT_WRITE", "MKNOD", "NET_ADMIN", "NET_RAW", "SYS_ADMIN", "SYS_MODULE", "SYS_PTRACE", "SYS_TIME", "SYS_TTY_CONFIG"]
-no_new_privileges = false # Allow setuid inside the sandbox.
-pids_limit = 4096 # Fork-bomb protection.
-
-[ingress]
-mode = "direct" # Docker runtime supports direct mode only.
-
-[egress]
-# Sandbox outbound network sidecar. The engine creates it for each sandbox when needed.
-image = "opensandbox/egress:v1.0.12"
-mode = "dns"
-```
-
-## Deploy Agent Runtime
-
-### Configure `.env` and Generate Secrets
-
-Edit the `.env` file from [Configuration Files](#configuration-files). Required items:
-
-- `BASE_DOMAIN` / `INFRA_HOST`: your root domain. `INFRA_HOST` is usually the same as `BASE_DOMAIN`.
-- Images: fill the image list under [Container Images](#container-images). For each Teable image, copy the `` from the Installation command on that image's GHCR package page.
-- Secrets: generate and fill them with the commands below.
-
-```bash
-openssl rand -hex 32 # -> OPENSANDBOX_API_KEY, one shared API key for the whole stack
-openssl rand -hex 32 # -> SESSION_SECRET, console session signing secret
-openssl rand -hex 12 # -> S3_ACCESS_KEY, generated for built-in MinIO, provider value for external S3
-openssl rand -hex 24 # -> S3_SECRET_KEY, same rule as above
-```
-
-### Choose a TLS Mode
-
-| Mode | Preparation | Certificate renewal |
-|---|---|---|
-| **static** (self-provided certificate, default) | Put `fullchain.pem` and `privkey.pem` into `certs/`. The certificate must be a single multi-SAN certificate covering ``, `*.`, `*.app.`, and `*.sandbox.`, and the private key must match it. Wildcards cover only one level. | Manual. Replace files in `certs/`, then run `docker compose exec caddy caddy reload -c /etc/caddy/Caddyfile`. |
-| **cloudflare** (DNS-01 automatic issuance) | DNS must be hosted on Cloudflare. Prepare an API token with **Zone:Read + DNS:Edit** permissions. | Fully automatic through Caddy |
-
-**static mode**: the configuration files above are already written for this mode. Put the certificate files in place. No other change is needed.
-
-Use the following commands to check certificate SAN coverage and whether the certificate matches the private key:
-
-```bash
-openssl x509 -in certs/fullchain.pem -noout -text | grep -A1 'Subject Alternative Name'
-diff <(openssl x509 -in certs/fullchain.pem -noout -pubkey) \
- <(openssl pkey -in certs/privkey.pem -pubout) && echo "certificate and private key match"
-```
-
-**cloudflare mode** requires 4 changes:
-
-1. The official Caddy image does not include the DNS plugin. Save the following content as `Dockerfile.caddy` and build it locally:
-
- ```dockerfile Dockerfile.caddy
- # Caddy with the Cloudflare DNS plugin. Wildcard certificates require DNS-01.
- # Use caddy 2.9.x. The 2.8.x builder fails because of xcaddy dependency drift.
- FROM caddy:2.9.1-builder AS builder
- RUN xcaddy build --with github.com/caddy-dns/cloudflare
-
- FROM caddy:2.9.1
- COPY --from=builder /usr/bin/caddy /usr/bin/caddy
- ```
-
- ```bash
- docker build -t teable-caddy-cloudflare:2.9.1 -f Dockerfile.caddy .
- ```
-
-2. In `.env`, set `CADDY_IMAGE=teable-caddy-cloudflare:2.9.1`, and fill `ACME_EMAIL` and `CLOUDFLARE_API_TOKEN`.
-3. In `Caddyfile`, follow the file header and uncomment the global block, including `email` and `acme_dns cloudflare`.
-4. In `Caddyfile`, delete the `tls /certs/...` line inside the `(site_tls)` snippet. Certificates will be managed automatically by ACME.
-
-In Cloudflare mode, the `caddy-data` volume must be persistent. It stores certificates and the ACME account. If it is lost, Caddy will request certificates again after rebuilds, which can trigger Let's Encrypt rate limits.
-
-### Generate the Git Service Signing Key
-
-The git service uses an Ed25519 key pair to sign and verify access tokens. Multi-line PEM values cannot be stored cleanly in `.env`, so they are injected through `compose.override.yaml`, which Docker Compose loads automatically.
-
-Run this in the deployment directory:
-
-```bash
-openssl genpkey -algorithm ed25519 -out git-jwt.key
-openssl pkey -in git-jwt.key -pubout -out git-jwt.pub
-{
- echo "services:"
- echo " infra-service:"
- echo " environment:"
- echo " GIT_REGISTRY_JWT_PRIVATE_KEY: |"
- sed 's/^/ /' git-jwt.key
- echo " git-registry:"
- echo " environment:"
- echo " GIT_REGISTRY_JWT_PUBLIC_KEY: |"
- sed 's/^/ /' git-jwt.pub
-} > compose.override.yaml
-rm -f git-jwt.key git-jwt.pub
-```
-
-The generated `compose.override.yaml` will have this structure. The PEM content is your generated key:
-
-```yaml compose.override.yaml
-services:
- infra-service:
- environment:
- GIT_REGISTRY_JWT_PRIVATE_KEY: |
- -----BEGIN PRIVATE KEY-----
- ...your generated private key...
- -----END PRIVATE KEY-----
- git-registry:
- environment:
- GIT_REGISTRY_JWT_PUBLIC_KEY: |
- -----BEGIN PUBLIC KEY-----
- ...your generated public key...
- -----END PUBLIC KEY-----
-```
-
-To rotate the key, run this section again.
-
-> If `openssl genpkey` reports `Algorithm ed25519 not found`, for example on macOS with LibreSSL, use Docker to generate the key pair, then run the same assembly command above:
->
-> ```bash
-> docker run --rm node:22-slim node -e 'const c=require("crypto");const{privateKey}=c.generateKeyPairSync("ed25519");process.stdout.write(privateKey.export({type:"pkcs8",format:"pem"}))' > git-jwt.key
-> docker run --rm -v "$PWD:/w" node:22-slim node -e 'const c=require("crypto"),fs=require("fs");const k=c.createPrivateKey(fs.readFileSync("/w/git-jwt.key"));fs.writeFileSync("/w/git-jwt.pub",c.createPublicKey(k).export({type:"spki",format:"pem"}))'
-> ```
-
-### Create the Shared Workspace Volume
-
-The Agent shared workspace uses an external volume. Since compose declares it as `external`, compose will not create or delete it automatically.
-
-```bash
-docker volume create teable-agent-juicefs
-```
-
-### Pre-pull Runtime Images
-
-All images are public. `docker login` is not required.
-
-```bash
-set -a; . ./.env; set +a
-docker pull "$OPENSANDBOX_SERVER_IMAGE"
-docker pull "$SANDBOX_OPENSANDBOX_IMAGE"
-docker pull "$APP_RUNTIME_DEFAULT_IMAGE"
-docker pull ghcr.io/teableio/opensandbox-execd:v1.0.19-fix-1064
-docker pull opensandbox/egress:v1.0.12
-```
-
-The execd and egress image addresses must exactly match the values configured in `opensandbox.toml`.
-
-### Start the Services
-
-```bash
-docker compose up -d
-docker compose ps # All services should be running / healthy. minio-init should be exited(0).
-
-# In cloudflare mode, watch certificate issuance on first startup. It usually takes seconds to about one minute.
-docker compose logs -f caddy
-```
-
-## Verify the Deployment
-
-### Check Service Health
-
-```bash
-KEY=$(grep '^OPENSANDBOX_API_KEY=' .env | cut -d= -f2)
-
-# Sandbox engine
-curl -s -H "OPEN-SANDBOX-API-KEY: $KEY" https:///v1/sandboxes; echo
-# Infra API
-curl -s -o /dev/null -w "health -> %{http_code}\n" https:///api/health
-```
-
-Console UI: open `https://` in a browser, or the host configured in `INFRA_HOST`. Log in with `api-key`. The key is the `OPENSANDBOX_API_KEY` value in `.env`.
-
-### Connect Teable
-
-Add these environment variables to the Teable deployment:
-
-```bash
-TEABLE_INFRA_API_URL=https://
-TEABLE_INFRA_API_KEY=
-SANDBOX_OPENSANDBOX_IMAGE=ghcr.io/teableio/teable-sandbox-agent:
-APP_DEPLOY_PROVIDER=docker-runtime
-```
-
-Use the same value for `TEABLE_INFRA_API_KEY` as `OPENSANDBOX_API_KEY` in the Agent Runtime `.env` file. The `SANDBOX_OPENSANDBOX_IMAGE` value must also match the sandbox image configured for Agent Runtime.
-
-`TEABLE_INFRA_API_URL` must point to the Teable Infra root URL without a path. Restart Teable after updating the variables.
-
-## Troubleshooting
-
-| Problem | What to check |
-|---|---|
-| Teable reports that Agent Runtime is not configured | Confirm all four Teable environment variables above are set, then restart Teable. |
-| Sandbox or app previews return DNS, TLS, or 404 errors | Confirm all four DNS records point to the server and the certificate covers every required hostname. |
-| The first sandbox or app deployment is slow | Pre-pull all runtime images before the first use. |
-| A service is unhealthy | Run `docker compose ps`, then inspect the affected service with `docker compose logs `. |
-
-
-If you need deployment assistance, contact **support@teable.ai** and include the output of `docker compose ps` and the relevant service logs.
-
-
-## Operations
-
-### View Logs and Manage Services
-
-```bash
-docker compose logs -f infra-service # / opensandbox-server / caddy / git-registry
-docker compose restart infra-service
-docker compose down # Stop services and keep data volumes.
-```
-
-### Upgrade
-
-Update the image tags in `.env`, then run `docker compose pull && docker compose up -d`.
-
-After updating the sandbox or app base image, or execd / egress, pre-pull the images again as described in [Pre-pull Runtime Images](#pre-pull-runtime-images).
-
-### Back Up Data
-
-Back up these volumes regularly, especially `minio-data` and `caddy-data`.
-
-| Volume | Content |
-|---|---|
-| `opensandbox-state` | Sandbox engine state, SQLite |
-| `infra-state` | App Runtime state and drafts |
-| `git-registry-data` | Git repository data |
-| `minio-data` | Artifact files, built-in MinIO mode |
-| `teable-agent-juicefs` | Agent shared workspace, external volume created during deployment |
-| `caddy-data` / `caddy-config` | TLS certificates, ACME account, and Caddy configuration |
-
-`docker compose down -v` deletes data volumes too, including artifacts, Git repositories, and certificates. Use it carefully.
-
-## Security and Limitations
-
-### Security
-
-- The only files containing secrets are `.env` and `compose.override.yaml`. Do not commit them to a repository or share them externally.
-- The whole stack uses one shared `OPENSANDBOX_API_KEY`. If you need separate permissions, replace the corresponding environment variables for each service separately.
-- `docker.sock` is mounted into `opensandbox-server` and `infra-service`. This is required for the Docker backend and is equivalent to host root access. Deploy only on a dedicated and trusted host.
-- The only public entry point is Caddy on ports 80 and 443. The MinIO console on 9001 is not exposed. Use an SSH tunnel if access is needed.
-- Sandboxes share the host kernel. This is **not** a strong multi-tenant isolation boundary. For public multi-tenant scenarios, configure a stronger isolation runtime for the sandbox engine, such as gVisor or Kata.
-
-### Capability Boundaries
-
-**Available**: full sandbox engine functionality; the main app lifecycle, including create, activate, gateway access, delete, dashboard, logs, and S3 artifacts; git push and pull; console `api-key` login and Infra API; file browser and S3-compatible API.
-
-**Unavailable or limited** due to Docker mode tradeoffs: app `host-prefix` rename returns 501; `scale-to-zero` idle scaling is a no-op; engine key rotation and server rolling upgrade are not supported; Kubernetes observability pages in the console are empty, which is expected.
diff --git a/en/deploy/architecture.mdx b/en/deploy/architecture.mdx
new file mode 100644
index 00000000..5cb79e99
--- /dev/null
+++ b/en/deploy/architecture.mdx
@@ -0,0 +1,158 @@
+---
+title: "Architecture"
+description: "What a self-hosted Teable deployment runs: the app, its data services, and the runtime plane behind AI sessions, App Builder, and deployed apps."
+---
+
+Teable is an AI product: **AI Chat**, **App Builder**, and **app deployments**
+are part of the platform, not bolt-ons. A self-hosted deployment therefore
+runs the Teable app and its data services together with the **runtime plane**
+that powers those AI features. This page explains how the pieces fit
+together. The deployable assets (compose files, Helm chart, values) live in
+[teableio/teable-deployment](https://github.com/teableio/teable-deployment) and
+are the single source of truth — nothing on this page needs to be copied.
+
+AI features are available for self-hosted Business plan and above.
+
+## What a deployment runs
+
+| Service | Purpose |
+|---|---|
+| **Teable app** | Web UI, API, automations, AI chat — a single image: `ghcr.io/teableio/teable` |
+| **PostgreSQL** | The system of record: tables, views, metadata |
+| **Redis** | Cache, queues, realtime collaboration |
+| **Object storage** | S3-compatible, three buckets: **public** (avatars and public assets), **private** (attachments), **build artifacts** (App Builder output) |
+| **Infra Service** | Console + API — the one door the Teable app talks to; orchestrates builds and app deployments |
+| **Sandbox engine** | Runs every AI session inside an isolated sandbox container |
+| **Git registry** | Source of truth for the apps you build (App Builder pushes here) |
+| **Preview gateway** | Serves sandbox previews and deployed apps in the browser |
+
+The last four services form the **runtime plane**; the deployment assets set
+all of this up as one platform.
+
+## How it fits together
+
+```mermaid
+graph LR
+ U["Browser"]
+ subgraph "App & data"
+ T["Teable app"]
+ P[("PostgreSQL")]
+ R[("Redis")]
+ S[("Object storage")]
+ end
+ subgraph "Runtime plane"
+ I["Infra Service"]
+ E["Sandboxes — one per AI session"]
+ A["Deployed apps — one container each"]
+ G["Git registry"]
+ W["Preview gateway"]
+ end
+ U --> T
+ T --> P
+ T --> R
+ T -- "attachments" --> S
+ T -- "AI sessions" --> I
+ I -- "starts" --> E
+ I -- "deploys" --> A
+ E -. "source" .-> G
+ E -. "artifacts" .-> S
+ U -- "sandbox previews" --> W
+ U -- "deployed apps" --> W
+ W --> E
+ W --> A
+
+ style T fill:#0D9373,stroke:#0a7a5e,color:#fff
+ style E fill:#F59E0B,stroke:#b45309,color:#fff
+ style A fill:#F59E0B,stroke:#b45309,color:#fff
+```
+
+The Teable app reaches the runtime plane through **one connection**: the Infra
+Service (`TEABLE_INFRA_API_URL` / `TEABLE_INFRA_API_KEY`); everything behind it
+is internal. What the plane actually runs is two kinds of workload:
+
+- **Sandboxes** — every AI chat or App Builder session gets its own isolated
+ container, started on demand and destroyed when the session ends. This is
+ the dominant, bursty load: size your machine by **peak concurrent AI
+ sessions**, not by user count (per-sandbox limits are configurable in the
+ admin panel).
+- **Deployed apps** — every app someone ships runs as its own long-lived
+ container behind `*.app.`. Sandboxes come and go; deployed apps
+ accumulate and keep serving.
+
+The rest is plumbing: building happens inside the session's sandbox, the git
+registry and object storage persist what it produces (source and build
+artifacts), and the gateway routes browsers to the right sandbox or app.
+
+## One domain, four DNS records
+
+Everything hangs off **one base domain** — typically a subdomain of yours, such
+as `teable.example.com`:
+
+| Record | Serves |
+|---|---|
+| `` | The Teable app |
+| `infra.` | Infra console + API — git (`/git`) and object storage (bucket paths) ride this host as paths |
+| `*.app.` | Apps you built and deployed |
+| `*.sandbox.` | Sandbox previews in the browser |
+
+Each name is only a default; every hostname can be overridden individually
+(see the values example in the deployment repository).
+
+## How the agent stays in sync with the app
+
+The sandbox agent image is configured as a **prefix without a tag**. The Teable
+app appends **its own release tag** when launching AI sessions, so the agent
+always matches the app version — and the app preheats that exact image through
+the Infra Service, so the first session doesn't wait on a multi-gigabyte pull.
+You never pull or pin the agent manually.
+
+## Versioning
+
+The platform ships as **platform releases** (`v..`) of the
+deployment repository:
+
+- A **tag** is a verified snapshot: `versions.yaml` pins every component image
+ (with digests), and the repository's `CHANGELOG.md` says what changed and
+ what, if anything, you must do.
+- The repository's `main` is the rolling latest.
+- The bundled **doctor** scripts compare what your deployment actually runs
+ against the release manifest and report one of three states: compatible,
+ upgrade the Teable app, or an unknown (unverified) combination.
+
+The Teable app has its own release line (date-based tags; `latest` is the
+stable channel) — see [Version Upgrade](/en/deploy/upgrade). Platform releases
+declare the app compatibility window; the doctor checks it for you.
+
+## Deploy it
+
+Both paths install the whole platform and are covered end to end in the
+deployment repository:
+
+
+
+ Everything on one machine — first full deployment, `local` or `server` mode.
+
+
+ One umbrella chart on an existing cluster; only `global.baseDomain` is required.
+
+
+
+Don't need AI? You can run just the app with PostgreSQL, Redis, and storage —
+a **standalone** deployment ([Docker Deployment](/en/deploy/docker)) — and
+attach the runtime plane later with your data in place.
+
+Related topics, all maintained in the deployment repository:
+
+- **Already running standalone Teable?** Your data stays in place — the runtime
+ plane attaches next to it: [migration guide](https://github.com/teableio/teable-deployment/blob/main/migration/2026-07-basic-to-full-featured.md)
+- **Private / corporate CA**: sandboxes must trust the CA your entry serves —
+ [private-ca.md](https://github.com/teableio/teable-deployment/blob/main/helm/private-ca.md)
+- **Sizing, versions and mirrors**: [VERSIONS.md](https://github.com/teableio/teable-deployment/blob/main/VERSIONS.md) ·
+ [images/README.md](https://github.com/teableio/teable-deployment/blob/main/images/README.md)
+- **When something fails**: run the doctor first, then
+ [TROUBLESHOOTING.md](https://github.com/teableio/teable-deployment/blob/main/TROUBLESHOOTING.md)
+
+After deploying, connect your Teable app to the runtime plane with
+`TEABLE_INFRA_API_URL` / `TEABLE_INFRA_API_KEY` (the deployment guides cover
+this), then configure limits in
+[Admin Panel → Sandbox Agent](/en/basic/admin-panel/sandbox-agent).
diff --git a/en/deploy/aws.mdx b/en/deploy/aws.mdx
deleted file mode 100644
index b3dc5ae9..00000000
--- a/en/deploy/aws.mdx
+++ /dev/null
@@ -1,384 +0,0 @@
----
-title: "Deploy on AWS"
-description: "Step-by-step guide: Deploy Teable on AWS using ECS, RDS PostgreSQL, ElastiCache, and S3"
----
-
-
-**Recommended for:** Production deployments with 50+ users
-
-
-## Architecture overview
-
-```mermaid
-graph TB
- ECS["AWS ECS
(Fargate or EC2)
Teable App: 4+ replicas
Sandbox: 2+ replicas (optional)"]
-
- RDS["Amazon RDS
Aurora PostgreSQL"]
- ElastiCache["Amazon ElastiCache
(Valkey/Redis)
Queue & Cache"]
- S3["Amazon S3
Public + Private buckets"]
-
- ECS --> RDS
- ECS --> ElastiCache
- ECS --> S3
-
- style ECS fill:#ff9900,stroke:#cc7a00,color:#fff
- style RDS fill:#527fff,stroke:#3d5fd9,color:#fff
- style ElastiCache fill:#c925d1,stroke:#a01ba8,color:#fff
- style S3 fill:#569a31,stroke:#3f7224,color:#fff
-```
-
-## Prerequisites
-
-- AWS CLI installed and configured
-- AWS account with permissions for ECS, RDS, ElastiCache, S3, IAM
-- Docker image registry access (or ECR for your built images)
-
----
-
-## Step 1: Create AWS resources
-
-### 1.1 Create RDS PostgreSQL
-
-```bash
-aws rds create-db-instance \
- --db-instance-identifier teable-db \
- --db-instance-class db.t3.medium \
- --engine postgres \
- --engine-version 16 \
- --master-username teableadmin \
- --master-user-password '' \
- --allocated-storage 100 \
- --vpc-security-group-ids sg-xxxxxx \
- --db-subnet-group-name your-subnet-group \
- --publicly-accessible false
-```
-
-
-Wait until the instance status is `available`. Get the endpoint:
-```bash
-aws rds describe-db-instances \
- --db-instance-identifier teable-db \
- --query 'DBInstances[0].Endpoint.Address' --output text
-```
-
-
-### 1.2 Create ElastiCache Redis (for queues)
-
-```bash
-aws elasticache create-cache-cluster \
- --cache-cluster-id teable-cache \
- --engine redis \
- --cache-node-type cache.t3.small \
- --num-cache-nodes 1 \
- --engine-version 7.0 \
- --security-group-ids sg-xxxxxx \
- --cache-subnet-group-name your-subnet-group
-```
-
-
-Get the endpoint:
-```bash
-aws elasticache describe-cache-clusters \
- --cache-cluster-id teable-cache \
- --show-cache-node-info \
- --query 'CacheClusters[0].CacheNodes[0].Endpoint.Address' --output text
-```
-
-
-### 1.3 Create S3 buckets (public + private)
-
-```bash
-# Create public bucket
-aws s3api create-bucket \
- --bucket teable-public- \
- --region us-west-2 \
- --create-bucket-configuration LocationConstraint=us-west-2
-
-# Create private bucket
-aws s3api create-bucket \
- --bucket teable-private- \
- --region us-west-2 \
- --create-bucket-configuration LocationConstraint=us-west-2
-```
-
-**Must-do: Configure public bucket**
-
-1. **Public read policy**:
-
-```bash
-cat > public-bucket-policy.json </*"
- }
- ]
-}
-EOF
-
-aws s3api put-bucket-policy \
- --bucket teable-public- \
- --policy file://public-bucket-policy.json
-```
-
-2. **Disable "Block Public Access" for public bucket**:
-
-```bash
-aws s3api put-public-access-block \
- --bucket teable-public- \
- --public-access-block-configuration \
- BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false
-```
-
-3. **CORS configuration** (allow any origin):
-
-```bash
-cat > cors.json < \
- --cors-configuration file://cors.json
-```
-
-
-**Security reminder**: The public bucket must allow public read. Ensure this complies with your organization's security policy. The private bucket should remain non-public.
-
-
-### 1.4 Create IAM user/role for S3 access
-
-```bash
-# Create IAM user
-aws iam create-user --user-name teable-s3-user
-
-# Attach S3 full access policy (or create a custom policy)
-aws iam attach-user-policy \
- --user-name teable-s3-user \
- --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
-
-# Create access key
-aws iam create-access-key --user-name teable-s3-user
-```
-
-
-Save the `AccessKeyId` and `SecretAccessKey` from the output.
-
-
----
-
-## Step 2: Prepare environment variables
-
-Create a `.env` file (or ECS task definition environment):
-
-```bash
-# Core
-PUBLIC_ORIGIN=https://teable.yourcompany.com
-SECRET_KEY=
-
-# Database
-PRISMA_DATABASE_URL=postgresql://teableadmin:@:5432/teable
-
-# Redis (required for queues)
-BACKEND_CACHE_PROVIDER=redis
-BACKEND_CACHE_REDIS_URI=redis://:6379/0
-
-# Performance cache (optional; can point to the same Redis or a separate cluster)
-BACKEND_PERFORMANCE_CACHE=redis://:6379/0
-
-# Storage (S3 dual buckets)
-BACKEND_STORAGE_PROVIDER=s3
-BACKEND_STORAGE_S3_REGION=us-west-2
-BACKEND_STORAGE_S3_ENDPOINT=https://s3.us-west-2.amazonaws.com
-BACKEND_STORAGE_S3_ACCESS_KEY=
-BACKEND_STORAGE_S3_SECRET_KEY=
-BACKEND_STORAGE_PUBLIC_BUCKET=teable-public-
-BACKEND_STORAGE_PRIVATE_BUCKET=teable-private-
-STORAGE_PREFIX=https://teable-public-.s3.us-west-2.amazonaws.com
-
-# Optional: Sandbox service (if deploying separately)
-# SANDBOX_URL=http://teable-sandbox:7070
-```
-
-
-Generate a strong `SECRET_KEY`:
-```bash
-openssl rand -base64 32
-```
-
-
----
-
-## Step 3: Deploy to ECS
-
-### Option A: Using ECS Fargate (recommended for simplicity)
-
-1. **Create ECS cluster**:
-
-```bash
-aws ecs create-cluster --cluster-name teable-cluster
-```
-
-2. **Create task definition** (`teable-task.json`):
-
-```json
-{
- "family": "teable",
- "networkMode": "awsvpc",
- "requiresCompatibilities": ["FARGATE"],
- "cpu": "2048",
- "memory": "4096",
- "containerDefinitions": [
- {
- "name": "teable",
- "image": "ghcr.io/teableio/teable:latest",
- "portMappings": [
- {
- "containerPort": 3000,
- "protocol": "tcp"
- }
- ],
- "environment": [
- {"name": "PUBLIC_ORIGIN", "value": "https://teable.yourcompany.com"},
- {"name": "SECRET_KEY", "value": "***REDACTED***"},
- {"name": "PRISMA_DATABASE_URL", "value": "postgresql://..."},
- {"name": "BACKEND_CACHE_PROVIDER", "value": "redis"},
- {"name": "BACKEND_CACHE_REDIS_URI", "value": "redis://..."},
- {"name": "BACKEND_STORAGE_PROVIDER", "value": "s3"},
- {"name": "BACKEND_STORAGE_S3_REGION", "value": "us-west-2"},
- {"name": "BACKEND_STORAGE_S3_ENDPOINT", "value": "https://s3.us-west-2.amazonaws.com"},
- {"name": "BACKEND_STORAGE_S3_ACCESS_KEY", "value": "***"},
- {"name": "BACKEND_STORAGE_S3_SECRET_KEY", "value": "***"},
- {"name": "BACKEND_STORAGE_PUBLIC_BUCKET", "value": "teable-public-xxx"},
- {"name": "BACKEND_STORAGE_PRIVATE_BUCKET", "value": "teable-private-xxx"},
- {"name": "STORAGE_PREFIX", "value": "https://teable-public-xxx.s3.us-west-2.amazonaws.com"}
- ],
- "logConfiguration": {
- "logDriver": "awslogs",
- "options": {
- "awslogs-group": "/ecs/teable",
- "awslogs-region": "us-west-2",
- "awslogs-stream-prefix": "teable"
- }
- }
- }
- ]
-}
-```
-
-3. **Register task definition**:
-
-```bash
-aws ecs register-task-definition --cli-input-json file://teable-task.json
-```
-
-4. **Create ECS service**:
-
-```bash
-aws ecs create-service \
- --cluster teable-cluster \
- --service-name teable-service \
- --task-definition teable \
- --desired-count 2 \
- --launch-type FARGATE \
- --network-configuration "awsvpcConfiguration={subnets=[subnet-xxx,subnet-yyy],securityGroups=[sg-xxx],assignPublicIp=ENABLED}" \
- --load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:...,containerName=teable,containerPort=3000"
-```
-
-
-You need to create an Application Load Balancer (ALB) and target group separately, then reference it in `--load-balancers`.
-
-
----
-
-## Step 4: Verify deployment
-
-1. **Check ECS service status**:
-
-```bash
-aws ecs describe-services \
- --cluster teable-cluster \
- --services teable-service
-```
-
-2. **Check logs**:
-
-```bash
-aws logs tail /ecs/teable --follow
-```
-
-3. **Access health check**:
-
-```bash
-curl https://teable.yourcompany.com/health
-```
-
-Expected response:
-```json
-{"status":"ok"}
-```
-
-4. **Open Teable in browser**: `https://teable.yourcompany.com`
-
----
-
-## Troubleshooting
-
-### Database connection errors
-
-- Verify RDS security group allows traffic from ECS tasks
-- Check `PRISMA_DATABASE_URL` format: `postgresql://user:pass@endpoint:5432/dbname`
-
-### Redis connection errors
-
-- Verify ElastiCache security group allows traffic from ECS
-- Use the **primary endpoint** (not reader endpoint)
-
-### S3 access errors
-
-- Verify IAM user has `s3:GetObject`, `s3:PutObject`, `s3:DeleteObject` permissions
-- Check bucket names match exactly in `BACKEND_STORAGE_PUBLIC_BUCKET` / `BACKEND_STORAGE_PRIVATE_BUCKET`
-- Ensure public bucket has public read policy and CORS configured
-
-### Container fails to start
-
-- Check CloudWatch Logs: `/ecs/teable`
-- Verify all required environment variables are set
-- Ensure `SECRET_KEY` is set (not empty)
-
----
-
-## Production best practices
-
-
-For detailed production recommendations including resource sizing, high availability, and scaling strategies, see [Self-Hosted Overview](/en/deploy/production-overview).
-
-
-**AWS-specific tips**:
-- Use AWS Secrets Manager for sensitive values
-- Enable RDS encryption at rest
-- Use VPC endpoints for S3/ECR to avoid internet traffic
-- Enable CloudWatch Container Insights for ECS
-
----
-
-## Related documentation
-
-- [Self-Hosted Overview](/en/deploy/production-overview) — Architecture, sizing, and scaling
-- [Environment Variables Reference](/en/deploy/env)
-- [Object Storage (S3-compatible)](/en/deploy/storage)
diff --git a/en/deploy/azure.mdx b/en/deploy/azure.mdx
deleted file mode 100644
index 07199b9e..00000000
--- a/en/deploy/azure.mdx
+++ /dev/null
@@ -1,820 +0,0 @@
----
-title: "Deploy on Azure"
-description: "Step-by-step guide: Deploy Teable on Azure using App Service or AKS, with PostgreSQL Flexible Server, Azure Cache for Redis, and S3-compatible storage"
----
-
-
-**Recommended for:** Production deployments with 50+ users
-
-
-## Architecture overview
-
-```mermaid
-graph TB
- AppService["Azure App Service
(Linux Container)
Teable App
(scale out as needed)"]
-
- DB["Azure Database for
PostgreSQL Flexible Server"]
- Redis["Azure Cache for Redis
(Queue & Cache)"]
- S3["S3-compatible Storage
(AWS S3 or MinIO)
Public + Private buckets"]
-
- AppService --> DB
- AppService --> Redis
- AppService --> S3
-
- style AppService fill:#0078d4,stroke:#005a9e,color:#fff
- style DB fill:#0078d4,stroke:#005a9e,color:#fff
- style Redis fill:#0078d4,stroke:#005a9e,color:#fff
- style S3 fill:#ff9900,stroke:#cc7a00,color:#fff
-```
-
-
-**Important**: Teable requires **S3-compatible storage**. You can use:
-- **AWS S3** (cross-cloud setup)
-- **MinIO** (self-hosted on Azure VM/AKS)
-- Any other S3-compatible service
-
-Azure Blob Storage is **not** directly supported because it uses a different API.
-
-
-## Prerequisites
-
-- Azure CLI installed and logged in
-- Azure subscription with permissions for App Service, PostgreSQL, Redis
-- Access to an **S3-compatible storage** (e.g., AWS S3 account, or MinIO deployment)
-
----
-
-## Step 1: Create Azure resources
-
-### 1.1 Create resource group
-
-```bash
-az group create \
- --name teable-rg \
- --location eastus
-```
-
-### 1.2 Create PostgreSQL Flexible Server
-
-```bash
-az postgres flexible-server create \
- --resource-group teable-rg \
- --name teable-db \
- --location eastus \
- --admin-user teableadmin \
- --admin-password '' \
- --sku-name Standard_B2s \
- --tier Burstable \
- --storage-size 128 \
- --version 16 \
- --public-access 0.0.0.0-255.255.255.255
-```
-
-
-Wait until provisioning completes. Get the connection string:
-```bash
-az postgres flexible-server show \
- --resource-group teable-rg \
- --name teable-db \
- --query "fullyQualifiedDomainName" --output tsv
-```
-Result: `teable-db.postgres.database.azure.com`
-
-
-### 1.3 Create Azure Cache for Redis
-
-```bash
-az redis create \
- --resource-group teable-rg \
- --name teable-cache \
- --location eastus \
- --sku Basic \
- --vm-size c0 \
- --minimum-tls-version 1.2
-```
-
-
-Get the access key:
-```bash
-az redis list-keys \
- --resource-group teable-rg \
- --name teable-cache \
- --query "primaryKey" --output tsv
-```
-
-
----
-
-## Step 2: Set up S3-compatible storage
-
-Since Azure Blob Storage is not S3-compatible, choose one of the following options:
-
-### Option A: Use AWS S3 (cross-cloud)
-
-This is the simplest approach if you already have AWS access or don't want to manage MinIO.
-
-1. **Create S3 buckets on AWS** (see [AWS deployment guide](/en/deploy/aws) steps 1.3-1.4)
- - Public bucket: `teable-public-`
- - Private bucket: `teable-private-`
-
-2. **Configure public bucket** (see [Object Storage guide](/en/deploy/storage)):
- - Enable public read access
- - Configure CORS to allow any origin
-
-You'll use these environment variables:
-```bash
-BACKEND_STORAGE_PROVIDER=s3
-BACKEND_STORAGE_S3_REGION=us-west-2
-BACKEND_STORAGE_S3_ENDPOINT=https://s3.us-west-2.amazonaws.com
-BACKEND_STORAGE_S3_ACCESS_KEY=
-BACKEND_STORAGE_S3_SECRET_KEY=
-BACKEND_STORAGE_PUBLIC_BUCKET=teable-public-
-BACKEND_STORAGE_PRIVATE_BUCKET=teable-private-
-STORAGE_PREFIX=https://teable-public-.s3.us-west-2.amazonaws.com
-```
-
-### Option B: Deploy MinIO on Azure
-
-If you prefer to keep everything in Azure, deploy MinIO as an S3-compatible gateway.
-
-**Recommended image**: `minio/minio:RELEASE.2025-04-22T22-12-26Z`
-
-**Quick setup (Azure VM)**:
-
-1. Create a VM and install MinIO:
-```bash
-wget https://dl.min.io/server/minio/release/linux-amd64/minio
-chmod +x minio
-sudo mv minio /usr/local/bin/
-
-# Start MinIO
-export MINIO_ROOT_USER=admin
-export MINIO_ROOT_PASSWORD=
-minio server /data --console-address ":9001"
-```
-
-2. Create buckets via MinIO console (port 9001) or CLI:
-```bash
-mc alias set myminio http://your-vm-ip:9000 admin
-mc mb myminio/public
-mc mb myminio/private
-mc policy set download myminio/public
-```
-
-You'll use these environment variables:
-```bash
-BACKEND_STORAGE_PROVIDER=minio
-BACKEND_STORAGE_MINIO_ENDPOINT=
-BACKEND_STORAGE_MINIO_PORT=443
-BACKEND_STORAGE_MINIO_USE_SSL=true
-BACKEND_STORAGE_MINIO_ACCESS_KEY=admin
-BACKEND_STORAGE_MINIO_SECRET_KEY=
-BACKEND_STORAGE_PUBLIC_BUCKET=public
-BACKEND_STORAGE_PRIVATE_BUCKET=private
-STORAGE_PREFIX=https://
-```
-
----
-
-## Step 3: Prepare environment variables
-
-Create a file `app-settings.txt` with all required variables:
-
-```bash
-# Core
-PUBLIC_ORIGIN=https://teable-app.azurewebsites.net
-SECRET_KEY=
-
-# Database
-PRISMA_DATABASE_URL=postgresql://teableadmin:@teable-db.postgres.database.azure.com:5432/postgres?sslmode=require
-
-# Redis (required for queues)
-BACKEND_CACHE_PROVIDER=redis
-BACKEND_CACHE_REDIS_URI=rediss://:@teable-cache.redis.cache.windows.net:6380/0
-
-# Performance cache (optional; can point to the same Redis)
-BACKEND_PERFORMANCE_CACHE=rediss://:@teable-cache.redis.cache.windows.net:6380/0
-
-# Storage (S3-compatible)
-# For Option A (AWS S3):
-BACKEND_STORAGE_PROVIDER=s3
-BACKEND_STORAGE_S3_REGION=us-west-2
-BACKEND_STORAGE_S3_ENDPOINT=https://s3.us-west-2.amazonaws.com
-BACKEND_STORAGE_S3_ACCESS_KEY=
-BACKEND_STORAGE_S3_SECRET_KEY=
-BACKEND_STORAGE_PUBLIC_BUCKET=teable-public-
-BACKEND_STORAGE_PRIVATE_BUCKET=teable-private-
-STORAGE_PREFIX=https://teable-public-.s3.us-west-2.amazonaws.com
-
-# For Option B (MinIO):
-# BACKEND_STORAGE_PROVIDER=minio
-# BACKEND_STORAGE_MINIO_ENDPOINT=
-# BACKEND_STORAGE_MINIO_PORT=443
-# BACKEND_STORAGE_MINIO_USE_SSL=true
-# BACKEND_STORAGE_MINIO_ACCESS_KEY=admin
-# BACKEND_STORAGE_MINIO_SECRET_KEY=
-# BACKEND_STORAGE_PUBLIC_BUCKET=public
-# BACKEND_STORAGE_PRIVATE_BUCKET=private
-# STORAGE_PREFIX=https://
-```
-
-
-Generate a strong `SECRET_KEY`:
-```bash
-openssl rand -base64 32
-```
-
-
----
-
-## Step 4: Deploy to Azure App Service
-
-### 4.1 Create App Service Plan
-
-```bash
-az appservice plan create \
- --resource-group teable-rg \
- --name teable-plan \
- --location eastus \
- --is-linux \
- --sku P1v3
-```
-
-### 4.2 Create Web App (container-based)
-
-```bash
-az webapp create \
- --resource-group teable-rg \
- --plan teable-plan \
- --name teable-app \
- --deployment-container-image-name ghcr.io/teableio/teable:latest
-```
-
-### 4.3 Configure container settings
-
-```bash
-az webapp config container set \
- --resource-group teable-rg \
- --name teable-app \
- --docker-custom-image-name ghcr.io/teableio/teable:latest \
- --docker-registry-server-url https://ghcr.io
-```
-
-### 4.4 Set environment variables
-
-```bash
-# Convert app-settings.txt to JSON format and apply
-az webapp config appsettings set \
- --resource-group teable-rg \
- --name teable-app \
- --settings \
- WEBSITES_PORT=3000 \
- PUBLIC_ORIGIN="https://teable-app.azurewebsites.net" \
- SECRET_KEY="" \
- PRISMA_DATABASE_URL="postgresql://..." \
- BACKEND_CACHE_PROVIDER="redis" \
- BACKEND_CACHE_REDIS_URI="rediss://..." \
- BACKEND_PERFORMANCE_CACHE="rediss://..." \
- BACKEND_STORAGE_PROVIDER="s3" \
- BACKEND_STORAGE_S3_REGION="us-west-2" \
- BACKEND_STORAGE_S3_ENDPOINT="https://s3.us-west-2.amazonaws.com" \
- BACKEND_STORAGE_S3_ACCESS_KEY="***" \
- BACKEND_STORAGE_S3_SECRET_KEY="***" \
- BACKEND_STORAGE_PUBLIC_BUCKET="teable-public-xxx" \
- BACKEND_STORAGE_PRIVATE_BUCKET="teable-private-xxx" \
- STORAGE_PREFIX="https://teable-public-xxx.s3.us-west-2.amazonaws.com"
-```
-
-### 4.5 Configure health check
-
-```bash
-az webapp config set \
- --resource-group teable-rg \
- --name teable-app \
- --generic-configurations '{"healthCheckPath": "/health"}'
-```
-
-### 4.6 Restart the app
-
-```bash
-az webapp restart \
- --resource-group teable-rg \
- --name teable-app
-```
-
----
-
-## Step 5: Verify deployment
-
-1. **Check app status**:
-
-```bash
-az webapp show \
- --resource-group teable-rg \
- --name teable-app \
- --query "state" --output tsv
-```
-
-Expected: `Running`
-
-2. **View logs**:
-
-```bash
-az webapp log tail \
- --resource-group teable-rg \
- --name teable-app
-```
-
-3. **Test health check**:
-
-```bash
-curl https://teable-app.azurewebsites.net/health
-```
-
-Expected response:
-```json
-{"status":"ok"}
-```
-
-4. **Open Teable in browser**: `https://teable-app.azurewebsites.net`
-
----
-
-## Troubleshooting
-
-### Database connection errors
-
-- Verify PostgreSQL firewall allows Azure services
-- Check connection string includes `?sslmode=require`
-- Ensure database name is correct (default is `postgres`, not `teable`)
-
-### Redis connection errors
-
-- Use `rediss://` (with double 's') for TLS connections
-- Use port **6380** (not 6379) for Azure Cache for Redis
-- Verify access key is correct
-
-### S3 access errors (Option A: AWS S3)
-
-- Verify AWS credentials are correct
-- Check bucket names match exactly
-- Ensure public bucket has public read policy and CORS configured
-- Test S3 access from Azure: `curl https://s3.us-west-2.amazonaws.com` should work
-
-### Container fails to start
-
-- Check logs: `az webapp log tail ...`
-- Verify all required environment variables are set
-- Ensure `WEBSITES_PORT=3000` is set
-
----
-
-## Production best practices
-
-
-For detailed production recommendations including resource sizing, high availability, and scaling strategies, see [Self-Hosted Overview](/en/deploy/production-overview).
-
-
-**Azure-specific tips**:
-- Use Azure Key Vault for sensitive values
-- Enable HTTPS only: `az webapp update --https-only true`
-- Use VNet Integration to restrict database/redis access
-- Enable Application Insights for monitoring
-
-**Custom domain setup**:
-```bash
-# Add custom domain
-az webapp config hostname add \
- --resource-group teable-rg \
- --webapp-name teable-app \
- --hostname teable.yourcompany.com
-
-# Create managed SSL certificate
-az webapp config ssl create \
- --resource-group teable-rg \
- --name teable-app \
- --hostname teable.yourcompany.com
-```
-
----
-
-## Alternative: Deploy on AKS (Azure Kubernetes Service)
-
-For larger deployments or teams already using Kubernetes, AKS provides better scalability and control.
-
-### AKS Architecture
-
-```mermaid
-graph TB
- subgraph AKS["Azure Kubernetes Service"]
- Ingress["Ingress Controller
(AGIC or NGINX)"]
- Pods["Teable Pods
(scale horizontally)"]
- end
-
- DB["Azure Database for
PostgreSQL Flexible Server"]
- Redis["Azure Cache for Redis"]
- S3["S3-compatible Storage
(MinIO or AWS S3)"]
-
- Ingress --> Pods
- Pods --> DB
- Pods --> Redis
- Pods --> S3
-
- style AKS fill:#326ce5,stroke:#1a4ba0,color:#fff
- style DB fill:#0078d4,stroke:#005a9e,color:#fff
- style Redis fill:#0078d4,stroke:#005a9e,color:#fff
- style S3 fill:#ff9900,stroke:#cc7a00,color:#fff
-```
-
-### Step 1: Create AKS Cluster
-
-```bash
-# Create AKS cluster
-az aks create \
- --resource-group teable-rg \
- --name teable-aks \
- --location eastus \
- --node-count 2 \
- --node-vm-size Standard_D4s_v3 \
- --enable-managed-identity \
- --generate-ssh-keys
-
-# Get credentials
-az aks get-credentials \
- --resource-group teable-rg \
- --name teable-aks
-```
-
-### Step 2: Create Azure Managed Services
-
-Create PostgreSQL and Redis using the same commands from [Step 1.2](#12-create-postgresql-flexible-server) and [Step 1.3](#13-create-azure-cache-for-redis).
-
-
-For AKS, you may want to enable VNet integration to secure the connection:
-
-```bash
-# Get AKS VNet ID
-AKS_VNET=$(az aks show \
- --resource-group teable-rg \
- --name teable-aks \
- --query "networkProfile.networkPlugin" -o tsv)
-
-# Configure PostgreSQL to accept connections from AKS VNet
-az postgres flexible-server vnet-rule create \
- --resource-group teable-rg \
- --server-name teable-db \
- --name aks-access \
- --vnet-name \
- --subnet
-```
-
-
-### Step 3: Deploy MinIO to AKS (Optional)
-
-If you prefer to keep storage within Azure, deploy MinIO to AKS:
-
-```yaml
-# minio-deployment.yaml
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: minio
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: minio
- template:
- metadata:
- labels:
- app: minio
- spec:
- containers:
- - name: minio
- image: minio/minio:latest
- args:
- - server
- - /data
- - --console-address
- - ":9001"
- env:
- - name: MINIO_ROOT_USER
- value: "minioadmin"
- - name: MINIO_ROOT_PASSWORD
- valueFrom:
- secretKeyRef:
- name: minio-secrets
- key: password
- ports:
- - containerPort: 9000
- - containerPort: 9001
- volumeMounts:
- - name: data
- mountPath: /data
- volumes:
- - name: data
- persistentVolumeClaim:
- claimName: minio-pvc
----
-apiVersion: v1
-kind: Service
-metadata:
- name: minio
-spec:
- ports:
- - name: api
- port: 9000
- targetPort: 9000
- - name: console
- port: 9001
- targetPort: 9001
- selector:
- app: minio
----
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- name: minio-pvc
-spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 50Gi
- storageClassName: managed-premium
-```
-
-
-For production MinIO deployments, consider using the [MinIO Operator](https://min.io/docs/minio/kubernetes/upstream/) for distributed mode with data redundancy.
-
-
-### Step 4: Create Kubernetes Configurations
-
-Create the ConfigMap with Azure-specific settings:
-
-```yaml
-# teable-config.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: teable-config
-data:
- PUBLIC_ORIGIN: "https://teable.yourcompany.com"
-
- # Storage (MinIO in AKS)
- BACKEND_STORAGE_PROVIDER: "minio"
- BACKEND_STORAGE_MINIO_ENDPOINT: "minio.yourcompany.com"
- STORAGE_PREFIX: "https://minio.yourcompany.com"
- BACKEND_STORAGE_MINIO_INTERNAL_ENDPOINT: "minio.default.svc.cluster.local"
- BACKEND_STORAGE_MINIO_PORT: "443"
- BACKEND_STORAGE_MINIO_INTERNAL_PORT: "9000"
- BACKEND_STORAGE_MINIO_USE_SSL: "true"
-
- # Cache
- BACKEND_CACHE_PROVIDER: "redis"
-
- # Other
- NEXT_ENV_IMAGES_ALL_REMOTE: "true"
- PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING: "1"
-```
-
-Create secrets with Azure service credentials:
-
-```yaml
-# teable-secrets.yaml
-apiVersion: v1
-kind: Secret
-metadata:
- name: teable-secrets
-type: Opaque
-stringData:
- # PostgreSQL (Azure Flexible Server)
- PRISMA_DATABASE_URL: "postgresql://teableadmin:@teable-db.postgres.database.azure.com:5432/postgres?sslmode=require"
-
- # Application secrets
- SECRET_KEY: ""
-
- # MinIO credentials
- BACKEND_STORAGE_PUBLIC_BUCKET: "public"
- BACKEND_STORAGE_PRIVATE_BUCKET: "private"
- BACKEND_STORAGE_MINIO_ACCESS_KEY: "minioadmin"
- BACKEND_STORAGE_MINIO_SECRET_KEY: ""
-
- # Redis (Azure Cache for Redis)
- BACKEND_CACHE_REDIS_URI: "rediss://:@teable-cache.redis.cache.windows.net:6380/0"
-```
-
-### Step 5: Deploy Teable
-
-```yaml
-# teable-deployment.yaml
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: teable
-spec:
- replicas: 2 # Scale as needed
- selector:
- matchLabels:
- app: teable
- template:
- metadata:
- labels:
- app: teable
- spec:
- initContainers:
- - name: db-migrate
- image: ghcr.io/teableio/teable:latest
- args:
- - migrate-only
- envFrom:
- - configMapRef:
- name: teable-config
- - secretRef:
- name: teable-secrets
- resources:
- limits:
- cpu: 1000m
- memory: 1024Mi
- containers:
- - name: teable
- image: ghcr.io/teableio/teable:latest
- args:
- - skip-migrate
- ports:
- - containerPort: 3000
- envFrom:
- - configMapRef:
- name: teable-config
- - secretRef:
- name: teable-secrets
- resources:
- requests:
- cpu: 500m
- memory: 1Gi
- limits:
- cpu: 2000m
- memory: 4Gi
- livenessProbe:
- httpGet:
- path: /health
- port: 3000
- initialDelaySeconds: 30
- periodSeconds: 30
- readinessProbe:
- httpGet:
- path: /health
- port: 3000
- initialDelaySeconds: 15
- periodSeconds: 10
----
-apiVersion: v1
-kind: Service
-metadata:
- name: teable
-spec:
- ports:
- - port: 3000
- targetPort: 3000
- selector:
- app: teable
-```
-
-### Step 6: Configure Ingress
-
-**Option A: Using NGINX Ingress Controller**
-
-```bash
-# Install NGINX Ingress
-helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
-helm install ingress-nginx ingress-nginx/ingress-nginx \
- --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz
-```
-
-```yaml
-# teable-ingress.yaml
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: teable
- annotations:
- kubernetes.io/ingress.class: nginx
- nginx.ingress.kubernetes.io/proxy-body-size: "100m"
- cert-manager.io/cluster-issuer: letsencrypt-prod
-spec:
- tls:
- - hosts:
- - teable.yourcompany.com
- secretName: teable-tls
- rules:
- - host: teable.yourcompany.com
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: teable
- port:
- number: 3000
-```
-
-**Option B: Using Azure Application Gateway Ingress Controller (AGIC)**
-
-```bash
-# Enable AGIC addon
-az aks enable-addons \
- --resource-group teable-rg \
- --name teable-aks \
- --addons ingress-appgw \
- --appgw-name teable-appgw \
- --appgw-subnet-cidr "10.225.0.0/16"
-```
-
-```yaml
-# teable-ingress-agic.yaml
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: teable
- annotations:
- kubernetes.io/ingress.class: azure/application-gateway
- appgw.ingress.kubernetes.io/backend-path-prefix: "/"
- appgw.ingress.kubernetes.io/ssl-redirect: "true"
-spec:
- tls:
- - hosts:
- - teable.yourcompany.com
- secretName: teable-tls
- rules:
- - host: teable.yourcompany.com
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: teable
- port:
- number: 3000
-```
-
-### Step 7: Apply All Configurations
-
-```bash
-# Apply configurations
-kubectl apply -f teable-config.yaml
-kubectl apply -f teable-secrets.yaml
-kubectl apply -f minio-deployment.yaml # If using MinIO in AKS
-kubectl apply -f teable-deployment.yaml
-kubectl apply -f teable-ingress.yaml
-
-# Verify deployment
-kubectl get pods -l app=teable
-kubectl logs -l app=teable
-```
-
-### AKS Production Recommendations
-
-1. **Autoscaling**:
-```bash
-# Enable Horizontal Pod Autoscaler
-kubectl autoscale deployment teable --cpu-percent=70 --min=2 --max=10
-
-# Enable Cluster Autoscaler
-az aks update \
- --resource-group teable-rg \
- --name teable-aks \
- --enable-cluster-autoscaler \
- --min-count 2 \
- --max-count 5
-```
-
-2. **Use Azure Key Vault** for secrets instead of Kubernetes secrets:
-```bash
-# Enable Key Vault secrets provider
-az aks enable-addons \
- --resource-group teable-rg \
- --name teable-aks \
- --addons azure-keyvault-secrets-provider
-```
-
-3. **Enable Azure Monitor**:
-```bash
-az aks enable-addons \
- --resource-group teable-rg \
- --name teable-aks \
- --addons monitoring
-```
-
-4. **Use Azure Private Link** for PostgreSQL and Redis to keep traffic within Azure network.
-
----
-
-## Related documentation
-
-- [Self-Hosted Overview](/en/deploy/production-overview) — Architecture, sizing, and scaling
-- [Environment Variables Reference](/en/deploy/env)
-- [Object Storage (S3-compatible)](/en/deploy/storage)
-- [Kubernetes Deployment](/en/deploy/k8s) (generic K8s guide)
-- [AWS Deployment](/en/deploy/aws) (for S3 setup if using cross-cloud storage)
diff --git a/en/deploy/choose.mdx b/en/deploy/choose.mdx
new file mode 100644
index 00000000..4eec8d20
--- /dev/null
+++ b/en/deploy/choose.mdx
@@ -0,0 +1,47 @@
+---
+title: "Deployment"
+description: "Pick between Teable Cloud, standalone self-hosting, and the full-featured self-hosted platform."
+---
+
+Three ways to run Teable — pick by what you need:
+
+| | **Teable Cloud** | **Full-featured self-host** | **Standalone self-host** |
+|---|---|---|---|
+| Tables, collaboration, API, automation | ✅ | ✅ | ✅ |
+| AI features (chat, agents) | ✅ | ✅ | ❌ |
+| App Builder (build & deploy apps) | ✅ | ✅ | ❌ |
+| Sandboxes / previews | ✅ | ✅ | ❌ |
+| Runs on | [teable.ai](https://teable.ai) — nothing to deploy | one machine (Docker) or a Kubernetes cluster | one machine: app + PostgreSQL |
+| Start here | [teable.ai](https://teable.ai) | [Architecture](/en/deploy/architecture) → [teableio/teable-deployment](https://github.com/teableio/teable-deployment) | [Docker Deployment](/en/deploy/docker) |
+
+
+Standalone and full-featured are not a fork in the road: the full-featured
+platform **attaches a runtime plane next to your existing standalone Teable** —
+your data stays in place. Start standalone today, add AI later:
+[migration guide](https://github.com/teableio/teable-deployment/blob/main/migration/2026-07-basic-to-full-featured.md).
+
+
+## Let an AI agent deploy it
+
+The deployment repository is written to be driven by AI agents. Point your
+agent harness (Claude Code, Codex, …) at
+[teableio/teable-deployment](https://github.com/teableio/teable-deployment),
+tell it which environment you're deploying to, and it can take the deployment
+end to end. Prepare three things:
+
+1. **A domain** — everything derives from one base domain, e.g.
+ `teable.example.com`.
+2. **A DNS token** — an API token for the platform hosting your DNS
+ (Cloudflare, Route 53, …), so DNS records and TLS certificates can be set
+ up automatically. Scope it to that one zone.
+3. **Access to the deployment target:**
+
+| Target | What to hand the agent |
+|---|---|
+| Your own machine — Docker all-in-one, `local` mode | Just Docker on the machine — no domain or DNS token needed (everything runs on `*.localhost`) |
+| A cloud server — Docker all-in-one | SSH access to the machine |
+| A managed cluster on AWS (EKS) / GCP (GKE) / Azure (AKS) | Create the cluster, then hand over its `kubeconfig` |
+| Any existing Kubernetes cluster | A `kubeconfig` that can install Helm releases |
+
+That's all it takes — the repository's guides, doctor scripts, and version
+manifests carry the agent through the rest.
diff --git a/en/deploy/database-connection.mdx b/en/deploy/database-connection.mdx
deleted file mode 100644
index 3c469c56..00000000
--- a/en/deploy/database-connection.mdx
+++ /dev/null
@@ -1,22 +0,0 @@
----
-title: "Enable External Database Connection"
-description: "Automatically create database roles in the application to enable secure access to base data from external applications"
----
-
-
-
-To enable this feature, you need to configure the additional environment variable `PUBLIC_DATABASE_PROXY`
-
-Configure this parameter with an externally accessible database IP or domain name + port number. If you're using the docker-compose deployment method mentioned earlier, the external access port is 42345. For other deployment methods, please configure according to your specific setup.
-
-```
-PUBLIC_DATABASE_PROXY=db-proxy.example.com:port
-```
-
-## More Environment Variables
-
-[Environment Variables](/en/deploy/env)
diff --git a/en/deploy/docker.mdx b/en/deploy/docker.mdx
index dd118b4c..9113b217 100644
--- a/en/deploy/docker.mdx
+++ b/en/deploy/docker.mdx
@@ -4,7 +4,7 @@ title: "Docker Deployment"
**Docker Compose is recommended for small teams and evaluation** (< 50 users).
-For production deployments, first read the [Overview](/en/deploy/production-overview), then follow [Kubernetes](/en/deploy/k8s) or a cloud-specific guide.
+Not sure this is the right path? Start from [Deployment](/en/deploy/choose). Need AI features or App Builder? Deploy the [full-featured platform](/en/deploy/architecture) instead.
## Docker Compose Deployment
@@ -170,8 +170,6 @@ BACKEND_CACHE_REDIS_URI=redis://default:${REDIS_PASSWORD}@${REDIS_HOST}:${REDIS_
For production deployments, use **S3-compatible object storage** (such as S3, MinIO, OSS/OBS/COS with S3-compatible endpoints, or another S3-compatible service) for better durability and scaling.
-See: [Object Storage (S3-compatible)](/en/deploy/storage)
-
MinIO provides an additional storage management interface (port 9001) and more powerful, stable file service.
@@ -329,7 +327,7 @@ STORAGE_PREFIX=https://your-public-bucket.s3.us-west-2.amazonaws.com
```
-This process applies to most cloud providers, not just AWS S3. For exact bucket policy and CORS examples, see: [Object Storage (S3-compatible)](/en/deploy/storage)
+This process applies to most cloud providers, not just AWS S3.
@@ -382,8 +380,6 @@ Note that `127.0.0.1` is the container's internal network. If you want to connec
[Configure Email Service](/en/deploy/email)
-[Configure External Database Connection](/en/deploy/database-connection)
-
## Support and Feedback
If you encounter any issues during deployment, please contact our support team at support@teable.ai or [submit an issue](https://github.com/teableio/teable/issues).
diff --git a/en/deploy/env.mdx b/en/deploy/env.mdx
index 84385bac..53537667 100644
--- a/en/deploy/env.mdx
+++ b/en/deploy/env.mdx
@@ -4,19 +4,17 @@ description: "Here are all available environment variables in Teable and their e
mode: "wide"
---
-{/* mintlify-resync: 2026-05-14 */}
-
-For production deployments, use **S3-compatible object storage** (`s3` / `minio`) with **public/private dual buckets**. Also ensure the public bucket is configured with **public-read + CORS**. See: [Object Storage (S3-compatible)](/en/deploy/storage).
-
-
| Environment Variable | Description | Default Value | Required | Example |
| ----------------------------------------- | -------------------------------------------------------------------------- | --------------- | -------- | ------------------------------------------------- |
| **Core Configuration** | | | | |
| PUBLIC_ORIGIN | Public origin for generating complete URLs, must be set to your app's access address | - | Yes | https://app.teable.ai |
| SECRET_KEY | Key for JWT, sessions, and sharing, use a strong password | defaultSecretKey | Yes | yourStrongSecretKey |
+| BACKEND_STORAGE_ENCRYPTION_KEY | Encryption key for storage tokens. The default is a public constant in the source — production deployments must set their own random value (the full-featured assets generate one per host) | public constant | - | 16-char random string |
+| BACKEND_STORAGE_ENCRYPTION_IV | Encryption IV paired with BACKEND_STORAGE_ENCRYPTION_KEY | public constant | - | 16-char random string |
+| BACKEND_ACCESS_TOKEN_ENCRYPTION_KEY | Encryption key for personal access tokens. Same caveat: the default is public — set your own in production | public constant | - | 16-char random string |
+| BACKEND_ACCESS_TOKEN_ENCRYPTION_IV | Encryption IV paired with BACKEND_ACCESS_TOKEN_ENCRYPTION_KEY | public constant | - | 16-char random string |
| PORT | Port on which the application runs | 3000 | - | 3000 |
| LOG_LEVEL | Log level, options: fatal, error, warn, info, debug, trace | info | - | debug |
-| NEXT_ENV_IMAGES_ALL_REMOTE | Whether to allow loading third-party images | false | - | true |
| **Storage Configuration** | | | | |
| BACKEND_STORAGE_PROVIDER | Storage provider, options: local, minio, s3, aliyun | local | - | s3 |
| BACKEND_STORAGE_LOCAL_PATH | Local storage path | .assets/uploads | - | .assets/uploads |
@@ -79,7 +77,6 @@ For production deployments, use **S3-compatible object storage** (`s3` / `minio`
| MAX_COPY_CELLS | Maximum number of cells to copy in a single request | - | - | 50000 |
| MAX_READ_ROWS | Maximum number of rows to read in a single request | - | - | 10000 |
| MAX_ATTACHMENT_UPLOAD_SIZE | Maximum attachment upload size (bytes) | - | - | 2147483648 |
-| MAX_SPACE_OWNER_COUNT | Maximum number of spaces a user can own | 10 | - | 10 |
| TASK_MAX_FIELDS_PER_BATCH | Maximum number of AI fields sent to the model in one batch request. Values are clamped from 1 to 20 | 5 | - | 5 |
| TASK_MAX_CONCURRENCY | Maximum pending AI field task runs dispatched in one scheduling cycle. Values are clamped from 1 to 20 | 5 | - | 5 |
| TABLE_LIMIT_FIELD_OPTIONS_MAX_BYTES | Maximum serialized field option bytes | 262144 | - | 262144 |
@@ -105,6 +102,19 @@ For production deployments, use **S3-compatible object storage** (`s3` / `minio`
| TABLE_LIMIT_VIEW_OPTIONS_MAX_BYTES | Maximum serialized view option bytes | 262144 | - | 262144 |
| TABLE_LIMIT_NAME_MAX_LENGTH | Maximum display name length for supported table objects | 100 | - | 100 |
| TABLE_LIMIT_DESCRIPTION_MAX_LENGTH | Maximum description length for supported table objects | 2000 | - | 2000 |
+| **AI & App Builder (runtime plane connection)** | | | | |
+| SANDBOX_PROVIDER | Sandbox provider for AI sessions; `opensandbox` connects to a self-hosted runtime plane | - | - | opensandbox |
+| TEABLE_INFRA_API_URL | Runtime plane entry URL — must be the public entry (it routes `/v1` to the sandbox engine), not an internal service address | - | - | https://infra.teable.example.com |
+| TEABLE_INFRA_API_KEY | API key shared with the runtime plane | - | - | your-infra-api-key |
+| TEABLE_INFRA_BUCKET | Bucket for the AI workspace data plane | teable-agent | - | teable-agent |
+| SANDBOX_OPENSANDBOX_IMAGE | Sandbox agent image **prefix without a tag** — Teable appends its own release tag so the agent always matches the app version. China deployments use the Aliyun mirror prefix | - | - | ghcr.io/teableio/teable-sandbox-agent |
+| SANDBOX_OPENSANDBOX_RUNTIME | Sandbox engine runtime type: `kubernetes` or `docker`. Must be `docker` on Docker deployments | kubernetes | - | docker |
+| SANDBOX_OPENSANDBOX_USE_SERVER_PROXY | Route sandbox endpoints through the engine's path-based proxy instead of per-port subdomains (used by Docker local mode) | false | - | true |
+| APP_DEPLOY_PROVIDER | App Builder deployment backend; full-featured self-host uses `docker-runtime` | vercel | - | docker-runtime |
+| SANDBOX_JWT_SECRET | Secret signing sandbox sessions — generate a random value per host | - | - | random string |
+| SANDBOX_CPU | vCPUs per sandbox (admin panel settings take precedence) | 2 | - | 2 |
+| SANDBOX_MEMORY | Memory (GiB) per sandbox (admin panel settings take precedence) | 4 | - | 4 |
+| SANDBOX_DISK | Ephemeral disk (GiB) per sandbox (admin panel settings take precedence) | 15 | - | 15 |
| **Feature Toggles** | | | | |
| RECORD_HISTORY_DISABLED | Whether to disable record history, defaults to false | false | - | true |
| BACKEND_RECORD_HISTORY_COLD_DISABLED | Whether to stop scheduled record-history cold-storage migration, compaction, and buffer deletion. Reads still include migrated history | false | - | true |
@@ -115,10 +125,7 @@ For production deployments, use **S3-compatible object storage** (`s3` / `minio`
| TELEMETRY_REPORT_DISABLED | Disable self-hosted telemetry reporting, including license compliance reports from connected instances | false | - | true |
| **Database Configuration** | | | | |
| PRISMA_DATABASE_URL | Database connection URL, must be configured | - | Yes | postgresql://teable:teable@127.0.0.1:5432/teable |
+| PUBLIC_DATABASE_PROXY | Externally reachable database address (host:port) used in the credentials generated by the base "Database Connection" panel; set it to enable external read-only SQL access | - | - | db.example.com:42345 |
| PRISMA_TRANSACTION_TIMEOUT | Maximum time (ms) a transaction can run before timing out. Increase for long-running transactions (e.g., bulk updates with many foreign keys) | 5000 | - | 60000 |
| PRISMA_TRANSACTION_MAX_WAIT | Maximum time (ms) to wait to acquire a transaction from the pool | 2000 | - | 5000 |
| BIG_TRANSACTION_TIMEOUT | Timeout (ms) for large internal transactions, such as exporting large bases | 600000 | - | 1200000 |
-
-
-If exporting a large base fails with a Prisma interactive transaction timeout, increase `BIG_TRANSACTION_TIMEOUT` and restart the Teable service. The right value depends on your deployment size, database performance, record count, table complexity, and attachments. Use the smallest value that works reliably for your environment.
-
diff --git a/en/deploy/gcp.mdx b/en/deploy/gcp.mdx
deleted file mode 100644
index 3d3f073a..00000000
--- a/en/deploy/gcp.mdx
+++ /dev/null
@@ -1,280 +0,0 @@
----
-title: "Deploy on GCP"
-description: "Step-by-step guide: Deploy Teable on Google Cloud Platform using Cloud Run/GKE, Cloud SQL, Memorystore, and S3-compatible storage"
----
-
-
-**Recommended for:** Production deployments with 50+ users
-
-
-## Architecture overview
-
-```mermaid
-graph TB
- CloudRun["Cloud Run / GKE
Teable App
(auto-scaling)"]
-
- CloudSQL["Cloud SQL
PostgreSQL"]
- Memorystore["Memorystore for Redis
(Queue & Cache)"]
- S3["S3-compatible Storage
(AWS S3 or MinIO)
Public + Private buckets"]
-
- CloudRun --> CloudSQL
- CloudRun --> Memorystore
- CloudRun --> S3
-
- style CloudRun fill:#4285f4,stroke:#2b5fab,color:#fff
- style CloudSQL fill:#4285f4,stroke:#2b5fab,color:#fff
- style Memorystore fill:#ea4335,stroke:#b8321e,color:#fff
- style S3 fill:#ff9900,stroke:#cc7a00,color:#fff
-```
-
-
-**Important**: Teable requires **S3-compatible storage**. You can use:
-- **AWS S3** (cross-cloud setup)
-- **MinIO** (self-hosted on GCE/GKE)
-- Any other S3-compatible service
-
-Google Cloud Storage (GCS) is **not** directly supported because it uses a different API.
-
-
-## Prerequisites
-
-- `gcloud` CLI installed and authenticated
-- GCP project with billing enabled
-- Access to **S3-compatible storage** (e.g., AWS S3 account or MinIO deployment)
-
----
-
-## Step 1: Create GCP resources
-
-### 1.1 Set project and region
-
-```bash
-export PROJECT_ID=your-project-id
-export REGION=us-central1
-
-gcloud config set project $PROJECT_ID
-```
-
-### 1.2 Create Cloud SQL (PostgreSQL)
-
-```bash
-gcloud sql instances create teable-db \
- --database-version=POSTGRES_16 \
- --tier=db-custom-2-7680 \
- --region=$REGION \
- --root-password= \
- --storage-type=SSD \
- --storage-size=100GB
-```
-
-
-Get connection name:
-```bash
-gcloud sql instances describe teable-db \
- --format='value(connectionName)'
-```
-Result: `your-project:region:teable-db`
-
-
-Create database:
-```bash
-gcloud sql databases create teable --instance=teable-db
-```
-
-### 1.3 Create Memorystore (Redis)
-
-```bash
-gcloud redis instances create teable-cache \
- --size=1 \
- --region=$REGION \
- --redis-version=redis_7_0
-```
-
-
-Get Redis host:
-```bash
-gcloud redis instances describe teable-cache \
- --region=$REGION \
- --format='value(host)'
-```
-
-
----
-
-## Step 2: Set up S3-compatible storage
-
-Since Google Cloud Storage is not S3-compatible, choose one of the following options:
-
-### Option A: Use AWS S3 (cross-cloud)
-
-1. **Create S3 buckets on AWS** (see [AWS deployment guide](/en/deploy/aws) steps 1.3-1.4)
-2. **Configure public bucket** (see [Object Storage guide](/en/deploy/storage))
-
-Environment variables:
-```bash
-BACKEND_STORAGE_PROVIDER=s3
-BACKEND_STORAGE_S3_REGION=us-west-2
-BACKEND_STORAGE_S3_ENDPOINT=https://s3.us-west-2.amazonaws.com
-BACKEND_STORAGE_S3_ACCESS_KEY=
-BACKEND_STORAGE_S3_SECRET_KEY=
-BACKEND_STORAGE_PUBLIC_BUCKET=teable-public-
-BACKEND_STORAGE_PRIVATE_BUCKET=teable-private-
-STORAGE_PREFIX=https://teable-public-.s3.us-west-2.amazonaws.com
-```
-
-### Option B: Deploy MinIO on GCP
-
-Deploy MinIO on a GCE instance or GKE cluster to provide S3-compatible storage.
-
-**Recommended image**: `minio/minio:RELEASE.2025-04-22T22-12-26Z`
-
-**Quick setup (GCE VM)**:
-
-```bash
-# Create VM
-gcloud compute instances create minio-server \
- --machine-type=e2-medium \
- --zone=us-central1-a \
- --image-family=ubuntu-2204-lts \
- --image-project=ubuntu-os-cloud \
- --boot-disk-size=100GB
-
-# SSH and install MinIO
-gcloud compute ssh minio-server --zone=us-central1-a
-
-# On the VM:
-wget https://dl.min.io/server/minio/release/linux-amd64/minio
-chmod +x minio
-sudo mv minio /usr/local/bin/
-
-export MINIO_ROOT_USER=admin
-export MINIO_ROOT_PASSWORD=
-minio server /data --console-address ":9001"
-```
-
-Create buckets and configure access (see Azure guide Option B for details).
-
----
-
-## Step 3: Prepare environment variables
-
-Create `.env` file:
-
-```bash
-# Core
-PUBLIC_ORIGIN=https://teable.yourcompany.com
-SECRET_KEY=
-
-# Database (Cloud SQL)
-PRISMA_DATABASE_URL=postgresql://postgres:@/teable?host=/cloudsql/
-
-# Redis (Memorystore)
-BACKEND_CACHE_PROVIDER=redis
-BACKEND_CACHE_REDIS_URI=redis://:6379/0
-BACKEND_PERFORMANCE_CACHE=redis://:6379/0
-
-# Storage (S3-compatible)
-# For Option A (AWS S3):
-BACKEND_STORAGE_PROVIDER=s3
-BACKEND_STORAGE_S3_REGION=us-west-2
-BACKEND_STORAGE_S3_ENDPOINT=https://s3.us-west-2.amazonaws.com
-BACKEND_STORAGE_S3_ACCESS_KEY=
-BACKEND_STORAGE_S3_SECRET_KEY=
-BACKEND_STORAGE_PUBLIC_BUCKET=teable-public-
-BACKEND_STORAGE_PRIVATE_BUCKET=teable-private-
-STORAGE_PREFIX=https://teable-public-.s3.us-west-2.amazonaws.com
-```
-
----
-
-## Step 4: Deploy to Cloud Run
-
-### 4.1 Build and push container (or use pre-built image)
-
-```bash
-# Option 1: Use pre-built image
-export IMAGE=ghcr.io/teableio/teable:latest
-
-# Option 2: Build and push to GCR
-# gcloud builds submit --tag gcr.io/$PROJECT_ID/teable
-# export IMAGE=gcr.io/$PROJECT_ID/teable
-```
-
-### 4.2 Deploy to Cloud Run
-
-```bash
-gcloud run deploy teable \
- --image=$IMAGE \
- --platform=managed \
- --region=$REGION \
- --allow-unauthenticated \
- --port=3000 \
- --set-env-vars="PUBLIC_ORIGIN=https://teable.yourcompany.com" \
- --set-env-vars="SECRET_KEY=" \
- --set-env-vars="PRISMA_DATABASE_URL=postgresql://..." \
- --set-env-vars="BACKEND_CACHE_PROVIDER=redis" \
- --set-env-vars="BACKEND_CACHE_REDIS_URI=redis://..." \
- --set-env-vars="BACKEND_STORAGE_PROVIDER=s3" \
- --set-env-vars="BACKEND_STORAGE_S3_REGION=us-west-2" \
- --set-env-vars="BACKEND_STORAGE_S3_ENDPOINT=https://s3.us-west-2.amazonaws.com" \
- --set-env-vars="BACKEND_STORAGE_S3_ACCESS_KEY=***" \
- --set-env-vars="BACKEND_STORAGE_S3_SECRET_KEY=***" \
- --set-env-vars="BACKEND_STORAGE_PUBLIC_BUCKET=teable-public-xxx" \
- --set-env-vars="BACKEND_STORAGE_PRIVATE_BUCKET=teable-private-xxx" \
- --set-env-vars="STORAGE_PREFIX=https://teable-public-xxx.s3.us-west-2.amazonaws.com" \
- --add-cloudsql-instances= \
- --vpc-connector=
-```
-
-
-For Cloud SQL Unix socket access, use `--add-cloudsql-instances`.
-For Memorystore access, create a VPC connector first.
-
-
----
-
-## Step 5: Verify deployment
-
-1. **Get service URL**:
-
-```bash
-gcloud run services describe teable \
- --region=$REGION \
- --format='value(status.url)'
-```
-
-2. **Test health check**:
-
-```bash
-curl https:///health
-```
-
-Expected: `{"status":"ok"}`
-
-3. **View logs**:
-
-```bash
-gcloud run services logs read teable --region=$REGION
-```
-
----
-
-## Production best practices
-
-
-For detailed production recommendations including resource sizing, high availability, and scaling strategies, see [Self-Hosted Overview](/en/deploy/production-overview).
-
-
-**GCP-specific tips**:
-- Enable Cloud Run minimum instances (2+) for high availability
-- Use Secret Manager for sensitive values
-- Enable Cloud Monitoring and set up alerts
-- Map a custom domain to Cloud Run service
-
----
-
-## Related documentation
-
-- [Self-Hosted Overview](/en/deploy/production-overview) — Architecture, sizing, and scaling
-- [Environment Variables Reference](/en/deploy/env)
-- [Object Storage (S3-compatible)](/en/deploy/storage)
diff --git a/en/deploy/k8s.mdx b/en/deploy/k8s.mdx
deleted file mode 100644
index de1c7ffc..00000000
--- a/en/deploy/k8s.mdx
+++ /dev/null
@@ -1,426 +0,0 @@
----
-title: "Kubernetes Deployment"
----
-
-
-**Recommended for:** Production deployments with 50+ users
-
-
-
-For resource sizing recommendations (CPU, memory, replicas), see [Self-Hosted Overview → Resource Recommendations](/en/deploy/production-overview#resource-recommendations).
-
-
-## Prerequisites
-### Teable Images
-- Application image: `ghcr.io/teableio/teable:latest`
-
-### Runtime Environment
-- Running Kubernetes cluster
-
-### Required External Services
-#### Database Service
-- PostgreSQL database: postgres:15.4 (version > 12)
- - PG image: `postgres:15.4`
-
-#### Cache Service
-- Redis cache service: redis:7.2.4 (version > 5)
- - Redis image: `redis:7.2.4`
-
-#### Object Storage Service
-- MinIO object storage service: `minio/minio:RELEASE.2025-04-22T22-12-26Z`
-
-### Required Tools
-- kubectl command-line tool
-
-## Dependency Component Configuration
-### File Storage (MinIO)
-File storage service must be accessible from the public internet (directly accessible by end users)
-
-Two buckets need to be created in advance for file storage:
-
-| Bucket | Environment Variable | Permission |
-|--------|---------------------|------------|
-| Public bucket | `BACKEND_STORAGE_PUBLIC_BUCKET=teable-pub` | **Public read (anonymous access required)** |
-| Private bucket | `BACKEND_STORAGE_PRIVATE_BUCKET=teable-pvt` | Private (default) |
-
-
-The public bucket **must** have anonymous read access enabled. Without this, users cannot view shared images, avatars, and other public files.
-
-
-#### Create Buckets Using MinIO Client (mc)
-
-Before deploying Teable, create the required buckets:
-
-```sh
-# Set up MinIO client alias
-mc alias set teable-minio https://minio.example.com YOUR_ACCESS_KEY YOUR_SECRET_KEY
-
-# Create public bucket and set anonymous read access
-mc mb --ignore-existing teable-minio/teable-pub
-mc anonymous set public teable-minio/teable-pub
-
-# Create private bucket
-mc mb --ignore-existing teable-minio/teable-pvt
-
-# Verify buckets exist
-mc ls teable-minio
-# Expected output:
-# [2024-01-01 00:00:00 UTC] 0B teable-pub/
-# [2024-01-01 00:00:00 UTC] 0B teable-pvt/
-```
-
-#### Teable MinIO Environment Variables Overview
-
-```sh
-# Fixed value
-BACKEND_STORAGE_PROVIDER=minio
-# Public bucket
-BACKEND_STORAGE_PUBLIC_BUCKET=teable-pub
-# Private bucket
-BACKEND_STORAGE_PRIVATE_BUCKET=teable-pvt
-# Public endpoint, important! Must be accessible by end users
-BACKEND_STORAGE_MINIO_ENDPOINT=minio.example.com
-# Same as above but with protocol
-STORAGE_PREFIX=https://minio.example.com
-# Internal network endpoint (Kubernetes DNS format: ..svc.cluster.local)
-# ⚠️ Replace with your actual namespace, e.g., minio.teable.svc.cluster.local
-BACKEND_STORAGE_MINIO_INTERNAL_ENDPOINT=minio.teable.svc.cluster.local
-# Public port, typically 443 or 9000
-BACKEND_STORAGE_MINIO_PORT=443
-# Internal network port, typically 80 or 9000
-BACKEND_STORAGE_MINIO_INTERNAL_PORT=80
-# Enable HTTPS, note: if Teable uses HTTPS, MinIO must also use HTTPS to avoid CORS issues
-BACKEND_STORAGE_MINIO_USE_SSL="true"
-# Admin account
-BACKEND_STORAGE_MINIO_ACCESS_KEY=root
-# Admin password
-BACKEND_STORAGE_MINIO_SECRET_KEY=rootPassword
-```
-
-### Database
-Create a database account with administrative privileges, a database, and set a password.
-Environment variables example:
- - Database name: teable
- - Password: your-password
- - Username: postgres
- - Port: 5432
-```sh
-PRISMA_DATABASE_URL="postgresql://postgres:your-password@your-postgres-host:5432/teable"
-```
-
-### Redis Cache
-Teable only needs the internal network address for Redis cache configuration. (Note: Redis manages both cache and queues, it's essential. Data should be backed up regularly)
-Environment variables example:
-```sh
-BACKEND_CACHE_REDIS_URI="redis://username:password@your-redis-host:6379/0"
-```
-
-## Create Configuration Files
-
-```yaml teable-config.yaml (Non-sensitive configuration)
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: teable-config
- namespace: teable # Replace with your namespace
-data:
- # Application base configuration, public access domain
- PUBLIC_ORIGIN: "https://your-domain.com"
-
- # Storage configuration
- BACKEND_STORAGE_PROVIDER: "minio"
- # Bucket names (must be created in MinIO before deployment)
- BACKEND_STORAGE_PUBLIC_BUCKET: "teable-pub"
- BACKEND_STORAGE_PRIVATE_BUCKET: "teable-pvt"
- # Public endpoint, important! Must be accessible by end users
- BACKEND_STORAGE_MINIO_ENDPOINT: "minio.example.com"
- # Same as above but with protocol
- STORAGE_PREFIX: "https://minio.example.com"
- # Internal endpoint (Kubernetes DNS format: ..svc.cluster.local)
- # ⚠️ Replace 'teable' with your actual namespace
- BACKEND_STORAGE_MINIO_INTERNAL_ENDPOINT: "minio.teable.svc.cluster.local"
- # Public port, typically 443 or 9000
- BACKEND_STORAGE_MINIO_PORT: "443"
- # Internal port, typically 80 or 9000
- BACKEND_STORAGE_MINIO_INTERNAL_PORT: "80"
- # Enable HTTPS, note: if Teable uses HTTPS, MinIO must also use HTTPS to avoid CORS issues
- BACKEND_STORAGE_MINIO_USE_SSL: "true"
-
- # Cache configuration, fixed value
- BACKEND_CACHE_PROVIDER: "redis"
-
- # Other configurations, fixed values
- NEXT_ENV_IMAGES_ALL_REMOTE: "true"
- PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING: "1"
- # Keep this when using self-signed certificates
- NODE_TLS_REJECT_UNAUTHORIZED: '0'
-```
-
-```yaml teable-secrets.yaml (Sensitive information)
-apiVersion: v1
-kind: Secret
-metadata:
- name: teable-secrets
- namespace: teable # Replace with your namespace
-type: Opaque
-stringData:
- # Database sensitive information
- PRISMA_DATABASE_URL: "postgresql://postgres:your-password@your-postgres-host:5432/teable"
-
- # Application secrets
- BACKEND_JWT_SECRET: "your-jwt-secret"
- BACKEND_SESSION_SECRET: "your-session-secret"
-
- # MinIO authentication
- BACKEND_STORAGE_MINIO_ACCESS_KEY: "your-minio-access-key"
- BACKEND_STORAGE_MINIO_SECRET_KEY: "your-minio-secret-key"
-
- # Redis authentication
- BACKEND_CACHE_REDIS_URI: "redis://username:password@your-redis-host:6379/0"
-```
-
-```yaml teable-deployment.yaml
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: teable
- namespace: teable # Replace with your namespace
-spec:
- replicas: 1 # Configure as needed
- selector:
- matchLabels:
- app: teable
- template:
- metadata:
- labels:
- app: teable
- spec:
- # Add initContainers for database migration
- initContainers:
- - name: db-migrate
- image: ghcr.io/teableio/teable:latest
- args:
- - migrate-only
- envFrom:
- - configMapRef:
- name: teable-config
- - secretRef:
- name: teable-secrets
- resources:
- requests:
- cpu: 100m
- memory: 102Mi
- limits:
- cpu: 1000m
- memory: 1024Mi
- containers:
- - name: teable
- image: ghcr.io/teableio/teable:latest
- args:
- - skip-migrate
- ports:
- - containerPort: 3000
- envFrom:
- - configMapRef:
- name: teable-config
- - secretRef:
- name: teable-secrets
- resources:
- requests:
- cpu: 200m
- memory: 400Mi
- limits:
- cpu: 2000m
- memory: 4096Mi
- startupProbe:
- httpGet:
- path: /health
- port: 3000
- initialDelaySeconds: 10
- periodSeconds: 10
- timeoutSeconds: 5
- failureThreshold: 30
- successThreshold: 1
- livenessProbe:
- httpGet:
- path: /health
- port: 3000
- initialDelaySeconds: 30
- periodSeconds: 30
- timeoutSeconds: 5
- failureThreshold: 3
- successThreshold: 1
- readinessProbe:
- httpGet:
- path: /health
- port: 3000
- initialDelaySeconds: 15
- periodSeconds: 10
- timeoutSeconds: 5
- failureThreshold: 3
- successThreshold: 1
-```
-
-```yaml teable-service.yaml
-apiVersion: v1
-kind: Service
-metadata:
- name: teable
- namespace: teable # Replace with your namespace
-spec:
- ports:
- - port: 3000
- targetPort: 3000
- selector:
- app: teable
-```
-
-```yaml teable-ingress.yaml (Optional)
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: teable
- namespace: teable # Replace with your namespace
- # Example using nginx, if using other ingress class, please replace
- annotations:
- nginx.ingress.kubernetes.io/proxy-body-size: "100m"
- nginx.ingress.kubernetes.io/proxy-buffer-size: "128k"
- nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
- nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
- nginx.ingress.kubernetes.io/proxy-request-buffering: "off"
-spec:
- ingressClassName: nginx # Change to your ingress class if different
- rules:
- - host: your-domain.com # Replace with your domain
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: teable
- port:
- number: 3000
- tls:
- - hosts:
- - your-domain.com # Replace with your domain
- secretName: your-tls-secret
-```
-
-
-Do **NOT** add `nginx.ingress.kubernetes.io/rewrite-target` annotation. This will break Teable's internal routing.
-
-
-
-## Deployment Steps
-
-
-Before deploying Teable, ensure that:
-1. MinIO buckets (`teable-pub` and `teable-pvt`) are created
-2. Public bucket has anonymous read access enabled
-3. PostgreSQL database `teable` exists
-4. Redis is accessible
-
-
-1. Create namespace (if not exists):
-```sh
-kubectl create namespace teable
-```
-
-2. Create configuration and secrets:
-```sh
-kubectl apply -f teable-config.yaml
-kubectl apply -f teable-secrets.yaml
-```
-
-3. Deploy application:
-```sh
-kubectl apply -f teable-deployment.yaml
-kubectl apply -f teable-service.yaml
-kubectl apply -f teable-ingress.yaml # Optional, if using Ingress
-```
-
-4. Verify deployment:
-```sh
-# Check Pod status
-kubectl get pods -n teable -l app=teable
-
-# Wait for pods to be ready
-kubectl rollout status deployment/teable -n teable
-
-# View application logs
-kubectl logs -n teable -l app=teable
-```
-
-### Configuration Notes
-
-1. Sensitive Information Management
- - All password, secret-related information should be managed through Secrets
-
-2. Database Configuration
- - Ensure that the teable database exists in the database
- - The database user needs to have appropriate permissions
- - It's recommended to use a connection pool to manage database connections
-
-3. MinIO Configuration
- - Ensure that the storage bucket exists and the permissions are correct, one public bucket, one private bucket
- - The public bucket needs to be completely publicly readable
- - The internal and external access address configuration is correct
-
-4. Redis Configuration
- - It's recommended to enable Redis persistence
- - Configure appropriate memory limits
- - Consider using Redis cluster to improve availability
-
-5. Security Recommendations
- - Use strong passwords and secrets
- - Enable TLS/SSL encryption
- - Regularly update certificates
- - Limit network access scope
-
-6. Resource Configuration
- - Adjust resource limits based on actual load
- - Monitor resource usage
- - Configure appropriate health check parameters
-
-### Troubleshooting
-
-#### Common Issues
-
-| Error | Cause | Solution |
-|-------|-------|----------|
-| `ECONNREFUSED` to MinIO | MinIO internal endpoint incorrect or unreachable | Verify `BACKEND_STORAGE_MINIO_INTERNAL_ENDPOINT` uses correct format: `..svc.cluster.local` |
-| `Bucket not found` | MinIO buckets not created | Create buckets using `mc mb` command before deployment |
-| `Access Denied` on file upload | MinIO credentials incorrect | Verify `BACKEND_STORAGE_MINIO_ACCESS_KEY` and `SECRET_KEY` |
-| `Page not found` on web access | Ingress `rewrite-target` configured | Remove `rewrite-target` annotation from Ingress |
-| Pod stuck in `CrashLoopBackOff` | Backend failed to start | Check logs for MinIO, database, or Redis connectivity issues |
-
-#### Diagnostic Commands
-
-1. Check Pod status:
-```sh
-kubectl describe pod -n teable -l app=teable
-```
-
-2. View application logs:
-```sh
-kubectl logs -n teable -l app=teable
-kubectl logs -n teable -l app=teable --previous # If pod crashed
-```
-
-3. Verify configuration:
-```sh
-kubectl describe configmap teable-config -n teable
-kubectl describe secret teable-secrets -n teable
-```
-
-4. Check network connection:
-```sh
-kubectl exec -it -n teable -- curl -v localhost:3000/health
-```
-
-5. Test MinIO connectivity from inside the cluster:
-```sh
-kubectl run test-minio --rm -it --image=curlimages/curl --restart=Never -n teable -- \
- curl -v http://minio.teable.svc.cluster.local/minio/health/live
-```
diff --git a/en/deploy/one-key.mdx b/en/deploy/one-key.mdx
deleted file mode 100644
index bf38c110..00000000
--- a/en/deploy/one-key.mdx
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: "One-Click Cloud Deployment"
-description: "Deploy Teable quickly using cloud provider templates, then subscribe to unlock paid features and activate your license."
----
-
-## One-Click Cloud Deployment
-
-One-click templates help you bootstrap a Teable environment quickly. After deployment, if you want paid features (for self-hosted plans), you should **subscribe** and **activate your license** using your Instance ID.
-
-## Step 1: Deploy with a template
-
-Choose a template below and deploy.
-
-[](https://railway.app/template/NtH5uD?referralCode=rE4BjB)
-
-[](https://zeabur.com/templates/QF8695)
-
-[](https://repocloud.io/details/?app_id=273)
-
-[](https://elest.io/open-source/teable)
-
-## Step 2: Subscribe (paid features)
-
-If you are deploying **self-hosted** and need paid features, subscribe with your **Instance ID**:
-
-1. Open the Admin Panel in your deployed instance and copy the **Instance ID**
-2. Go to the self-hosted pricing page and subscribe: `https://app.teable.ai/public/pricing?host=self-hosted`
-3. After subscribing, you will get a **License Key**
-
-Then activate it in your instance:
-
-- Documentation: [Subscribe and Activate License](/en/deploy/activate)
-
-
-If you are using **Teable Cloud** (hosted by Teable), manage your plan in-app:
-see [Billing & Subscription](/en/basic/space/billing).
-
-
-## Need help?
-
-If you have questions about subscription or licensing, contact `support@teable.ai`.
diff --git a/en/deploy/production-overview.mdx b/en/deploy/production-overview.mdx
deleted file mode 100644
index c9e0269c..00000000
--- a/en/deploy/production-overview.mdx
+++ /dev/null
@@ -1,172 +0,0 @@
----
-title: "Overview"
-description: "Architecture, sizing, and deployment path selection for production Teable deployments"
----
-
-
-**Recommended for:** Production deployments with 50+ users
-
-
-## Architecture Overview
-
-Teable uses a **stateless application tier** with externalized state services. This design enables horizontal scaling and high availability.
-
-```mermaid
-graph TB
- subgraph "Application Tier (Stateless)"
- App1["Teable Pod 1"]
- App2["Teable Pod 2"]
- AppN["Teable Pod N..."]
- end
-
- subgraph "Data Tier (Stateful)"
- DB["PostgreSQL
(Master + Replica)"]
- Redis1["Redis
Queue & Cache"]
- Redis2["Redis
Performance Cache"]
- S3["S3 / MinIO
Object Storage"]
- end
-
- App1 --> DB
- App2 --> DB
- AppN --> DB
- App1 --> Redis1
- App1 --> Redis2
- App1 --> S3
-
- style App1 fill:#0D9373,stroke:#0a7a5e,color:#fff
- style App2 fill:#0D9373,stroke:#0a7a5e,color:#fff
- style AppN fill:#0D9373,stroke:#0a7a5e,color:#fff
- style DB fill:#336791,stroke:#264d73,color:#fff
- style Redis1 fill:#dc382d,stroke:#a82a22,color:#fff
- style Redis2 fill:#dc382d,stroke:#a82a22,color:#fff
- style S3 fill:#ff9900,stroke:#cc7a00,color:#fff
-```
-
-### Components
-
-| Component | Purpose | Managed Service Examples |
-|-----------|---------|-------------------------|
-| **Teable App** | Stateless web application | K8s, AWS ECS, Azure App Service, GCP Cloud Run |
-| **PostgreSQL** | Primary data storage | AWS RDS, Azure PostgreSQL, Google Cloud SQL |
-| **Redis (Queue)** | Background jobs & cache | ElastiCache, Azure Cache, Memorystore |
-| **Redis (Perf)** | Performance cache for reads | Same or separate Redis instance |
-| **Object Storage** | Files & attachments | AWS S3, MinIO, any S3-compatible |
-
-
-**Key insight**: The Teable application holds no persistent state. You can scale horizontally by adding pods, and any pod can handle any request.
-
-
----
-
-## Resource Recommendations
-
-
-These are **production** recommendations from the Teable engineering team. For evaluation/testing, see [Docker Quick Start](/en/deploy/docker).
-
-
-### Application Tier (Teable Pods)
-
-| Setting | Recommended Value |
-|---------|-------------------|
-| CPU per pod | 2 vCPU |
-| Memory per pod | 4 GB |
-| Minimum replicas | 2 |
-| Auto-scale trigger | 50% CPU utilization |
-
-
-Use Kubernetes with Horizontal Pod Autoscaler (HPA), or equivalent auto-scaling on AWS ECS / Azure App Service / GCP Cloud Run.
-
-
-### Database (PostgreSQL)
-
-| Setting | Recommended Value |
-|---------|-------------------|
-| CPU | 4 vCPU |
-| Memory | 16 GB |
-| Topology | 1 Master + 1 Replica |
-| Backup | Daily automated |
-| Version | 15+ recommended |
-
-
-Always deploy with a replica for high availability. Use managed database services for automatic failover.
-
-
-### Cache (Redis)
-
-Teable uses **two separate Redis instances** for different purposes:
-
-| Purpose | Environment Variable | CPU | Memory |
-|---------|---------------------|-----|--------|
-| Queue & Cache | `BACKEND_CACHE_REDIS_URI` | 1 vCPU | 2 GB |
-| Performance Cache | `BACKEND_PERFORMANCE_CACHE` | 2 vCPU | 4 GB |
-
-
-The Performance Cache (`BACKEND_PERFORMANCE_CACHE`) is optional but **strongly recommended** for multi-user collaboration. It significantly improves read performance in busy workspaces.
-
-
-### Object Storage
-
-- **Type**: S3-compatible (AWS S3, MinIO, etc.)
-- **Buckets**: 2 required (public + private)
-- **Capacity**: Scales automatically with managed S3
-
-See [Object Storage Guide](/en/deploy/storage) for bucket configuration details.
-
----
-
-## Scaling Strategy
-
-| Component | Scaling Type | When to Scale |
-|-----------|--------------|---------------|
-| Teable App | **Automatic** (horizontal) | CPU > 50% (add pods) |
-| PostgreSQL | **Manual** (vertical) | CPU > 70% sustained |
-| Redis | **Manual** (vertical) | Memory > 80% or CPU > 60% |
-
-
-**Application tier**: Stateless design allows automatic horizontal scaling. Kubernetes HPA or cloud auto-scaling handles this automatically based on CPU metrics.
-
-**Database & Redis**: These are stateful services where vertical scaling (bigger instance) is simpler and safer than horizontal scaling. Monitor metrics and resize when thresholds are exceeded.
-
-
----
-
-## Minimum vs. Production Comparison
-
-| | Minimum (PoC) | Production |
-|---|---------------|------------|
-| Teable App | 1 instance, 2c4g | 2+ pods, 2c4g each, auto-scaling |
-| PostgreSQL | 2c4g, single instance | 4c16g, 1 master + 1 replica |
-| Redis | 1 instance, 1c2g | 2 instances (queue + performance) |
-| Storage | S3-compatible object storage | S3-compatible object storage |
-| Availability | None (single point of failure) | High availability with redundancy |
-
-
-The "Minimum" setup is for **evaluation only**. It has no redundancy—data loss is possible if the server fails.
-
-
----
-
-## Next Steps: Choose Your Platform
-
-
-
- Deploy on any K8s cluster with full control over infrastructure.
-
-
- ECS + RDS + ElastiCache + S3. Recommended for 50+ users.
-
-
- App Service + PostgreSQL + Redis + S3-compatible storage.
-
-
- Cloud Run + Cloud SQL + Memorystore + Cloud Storage.
-
-
-
----
-
-## Related Documentation
-
-- [Environment Variables Reference](/en/deploy/env) — All configuration options
-- [Object Storage Setup](/en/deploy/storage) — S3 bucket configuration
-- [License Activation](/en/deploy/activate) — Activate your self-hosted license
diff --git a/en/deploy/storage.mdx b/en/deploy/storage.mdx
deleted file mode 100644
index 9a036989..00000000
--- a/en/deploy/storage.mdx
+++ /dev/null
@@ -1,122 +0,0 @@
----
-title: "Object Storage (S3-compatible)"
-description: "Production storage guidance for Teable: public/private buckets, permissions, and CORS"
----
-
-
-For production deployments, use **S3-compatible object storage** (such as S3, MinIO, OSS/OBS/COS with S3-compatible endpoints, or another S3-compatible service) with **public/private dual buckets**.
-
-
-## Why two buckets?
-
-Teable stores different types of files in different buckets:
-
-- **Public bucket**: avatars, form cover images, and other assets that must be publicly accessible.
-- **Private bucket**: attachments, app files, record-history cold parts, and other content that should be protected.
-
-## Required environment variables
-
-At minimum, configure:
-
-- **Provider**
- - `BACKEND_STORAGE_PROVIDER`: `s3` or `minio`
-- **Buckets**
- - `BACKEND_STORAGE_PUBLIC_BUCKET`
- - `BACKEND_STORAGE_PRIVATE_BUCKET`
-- **Public access base URL**
- - `STORAGE_PREFIX`: should be the **public bucket** access base URL (or CDN in front of it)
-
-### S3 provider
-
-```bash
-BACKEND_STORAGE_PROVIDER=s3
-BACKEND_STORAGE_S3_REGION=us-west-2
-BACKEND_STORAGE_S3_ENDPOINT=https://s3.us-west-2.amazonaws.com
-BACKEND_STORAGE_S3_ACCESS_KEY=***REDACTED***
-BACKEND_STORAGE_S3_SECRET_KEY=***REDACTED***
-
-BACKEND_STORAGE_PUBLIC_BUCKET=your-public-bucket
-BACKEND_STORAGE_PRIVATE_BUCKET=your-private-bucket
-
-# Public bucket base URL (or CDN)
-STORAGE_PREFIX=https://your-public-bucket.s3.us-west-2.amazonaws.com
-```
-
-### MinIO provider
-
-```bash
-BACKEND_STORAGE_PROVIDER=minio
-BACKEND_STORAGE_MINIO_ENDPOINT=minio.example.com
-BACKEND_STORAGE_MINIO_PORT=443
-BACKEND_STORAGE_MINIO_USE_SSL=true
-BACKEND_STORAGE_MINIO_ACCESS_KEY=***REDACTED***
-BACKEND_STORAGE_MINIO_SECRET_KEY=***REDACTED***
-
-BACKEND_STORAGE_PUBLIC_BUCKET=public
-BACKEND_STORAGE_PRIVATE_BUCKET=private
-STORAGE_PREFIX=https://minio.example.com
-```
-
-## Public bucket requirements (must-do)
-
-### 1) Public read access
-
-The **public bucket must allow public read** for objects.
-
-If you use AWS S3, you can set a bucket policy like:
-
-```json
-{
- "Version": "2012-10-17",
- "Statement": [
- {
- "Sid": "PublicReadGetObject",
- "Effect": "Allow",
- "Principal": "*",
- "Action": "s3:GetObject",
- "Resource": "arn:aws:s3:::your-public-bucket/*"
- }
- ]
-}
-```
-
-
-AWS S3 may require you to adjust **Block Public Access** settings for the public bucket. Please follow your organization’s security policy.
-
-
-### 2) CORS (allow any origin)
-
-For browser access, configure CORS on the **public bucket** to allow cross-origin requests.
-
-AWS S3 example:
-
-```json
-[
- {
- "AllowedHeaders": ["*"],
- "AllowedMethods": ["GET", "HEAD"],
- "AllowedOrigins": ["*"],
- "ExposeHeaders": ["ETag", "x-amz-request-id", "x-amz-id-2"],
- "MaxAgeSeconds": 3000
- }
-]
-```
-
-If you use **direct browser uploads** (presigned PUT), you may also need `PUT` in `AllowedMethods`.
-
-## Private bucket guidance
-
-- Keep the **private bucket** non-public.
-- Teable serves private objects through **signed URLs** or backend reads, depending on the feature.
-- Record-history cold storage writes compressed history parts to the private bucket. Keep bucket backup and retention policies aligned with your record-history requirements.
-- If your provider supports “bucket endpoint” for private access, you can configure:
- - `BACKEND_STORAGE_PRIVATE_BUCKET_ENDPOINT` (optional)
-
-## Azure / GCP note
-
-Teable uses **S3 APIs** for object storage. Azure Blob Storage and Google Cloud Storage are **not S3-native**.
-
-- If you are on **Azure** or **GCP**, you can still use `BACKEND_STORAGE_PROVIDER=s3` as long as you point to an S3 endpoint (for example, AWS S3) and your Teable runtime can reach it.
-- Or use an **S3-compatible** storage:
- - MinIO (self-managed) as the S3 endpoint
- - Another managed S3-compatible service (your choice)
diff --git a/en/deploy/upgrade.mdx b/en/deploy/upgrade.mdx
index f9200055..cd0894c5 100644
--- a/en/deploy/upgrade.mdx
+++ b/en/deploy/upgrade.mdx
@@ -2,135 +2,94 @@
title: "Version Upgrade"
---
-This document describes how to upgrade your self-hosted Teable deployment.
+This document describes how to upgrade a self-hosted Teable deployment.
-## Update Frequency
+## Release channels and version tags
-Teable releases updates on an irregular schedule, often at a high frequency. We may ship multiple updates in a week, so the release frequency could be very high. You have full control over when to update your self-hosted Teable instance. You can choose to upgrade weekly or monthly. Whenever a new version is released, you can flexibly decide whether to upgrade. You can view all available versions on [GitHub Packages](https://github.com/teableio/teable-enterprise/pkgs/container/teable-ee).
+The Teable app publishes **date-based release tags** in the form
+`release..` (for example
+`release.2026-07-14T12-24-39Z.2228`), plus two floating channels:
+
+| Tag | Meaning |
+|---|---|
+| `latest` | The **stable** channel — always points at the most recent stable release |
+| `beta` | The rolling channel — the newest build, ahead of stable |
+| `release..` | An immutable, specific release |
+
+Releases ship frequently (often several per week); you decide when to upgrade.
+All tags are listed on
+[GitHub Packages](https://github.com/teableio/teable/pkgs/container/teable).
Before performing any upgrade, we strongly recommend backing up your data first.
-## Docker Compose Upgrade
-
-If you deployed Teable using Docker Compose, follow these steps to upgrade:
+## Routine updates: follow the changelog
-### Backup Data (Recommended)
+New features and fixes are announced in the [Changelog](/en/changelog), and
+every Teable release tag carries its build date — so "do I have this yet?" is
+just a date comparison. To pick up something you read about, move your Teable
+image to any release dated at or after that entry:
-We recommend backing up your entire cloud server, or backing up the PostgreSQL / Redis / storage volumes you're using.
+- **Docker deployments** can simply ride the `latest` channel:
-### Navigate to Deployment Directory
+ ```bash
+ cd teable # your deployment directory
+ docker compose pull
+ docker compose up -d
+ ```
-```bash
-cd teable # Navigate to your teable deployment directory
-```
+ Containers are recreated on the new image; your data lives in Docker volumes
+ (or your external database) and is not touched.
-### Pull Latest Images
+- **Kubernetes deployments** should not run a floating tag: keep the Teable
+ image pinned and **bump the pinned tag deliberately on each update**. The
+ deployment repository's `pin-image.sh` resolves which concrete release
+ `latest` currently points to.
-```bash
-docker-compose pull
-```
+## Best practice: upgrade the whole platform together
-### Restart Services
+A full-featured deployment has two version lines — the Teable app and the
+platform itself (see [Architecture](/en/deploy/architecture)). The most
+reliable routine ties them together, with
+[`VERSIONS.md`](https://github.com/teableio/teable-deployment/blob/main/VERSIONS.md)
+as the upgrade sheet. On each round:
-```bash
-docker-compose up -d
-```
+1. Upgrade the runtime plane to the **newest platform release**
+ (`v..`): each git tag is a verified snapshot of every
+ runtime component, and its
+ [`CHANGELOG.md`](https://github.com/teableio/teable-deployment/blob/main/CHANGELOG.md)
+ entry states what changed and what, if anything, you must do (most releases
+ are hot-swappable). Work from the repository checked out at that tag.
+2. Move the Teable app to the **concrete release tag that `latest` currently
+ corresponds to** (`pin-image.sh` resolves it) — a pinned, verified
+ combination instead of a floating channel.
+3. Run the bundled **doctor** — it checks health and compares what is actually
+ running against the platform release manifest (compatible / upgrade the
+ Teable app / unknown combination).
-The system will automatically recreate containers using the latest images. Your data is stored in Docker volumes and will not be lost.
+## Database migration
-### Verify Upgrade
+Teable executes database migrations automatically on startup; no manual step
+is required. If anything looks wrong after an upgrade, check the logs:
```bash
-# Check container status
-docker-compose ps
-
-# View logs to confirm successful startup
-docker-compose logs -f teable
-```
-
-Visit your Teable instance to confirm the service is running properly.
-
-## Upgrade to Specific Version
-
-If you want to upgrade to a specific version instead of the latest, modify the image tag in `docker-compose.yaml`:
-
-```yaml
-services:
- teable:
- image: ghcr.io/teableio/teable-ee:0.5.0-alpha-1.x.x-build.xxx # Specify version
-```
-
-Then execute:
-
-```bash
-docker-compose pull
-docker-compose up -d
-```
-
-
-You can view all available versions on the [GitHub Releases](https://github.com/teableio/teable-enterprise/pkgs/container/teable-ee) page.
-
-
-## Kubernetes Upgrade
-
-If you deployed Teable using Kubernetes, follow these steps to upgrade:
-
-### Manual Image Update
-
-If you're using custom Kubernetes configuration, you can directly update the image version in your Deployment:
-
-```bash
-kubectl set image deployment/teable teable=ghcr.io/teableio/teable-ee:0.5.0-alpha-1.x.x-build.xxx -n teable
-```
-
-### Verify Upgrade
-
-```bash
-# Check Pod status
-kubectl get pods -n teable
-
-# Check rollout status
-kubectl rollout status deployment/teable -n teable
-
-# View logs
-kubectl logs -f deployment/teable -n teable
-```
-
-## Database Migration
-
-Teable automatically executes database migrations on startup, no manual intervention required. If you encounter issues after upgrading, check the logs to confirm migration was successful:
-
-```bash
-# Docker Compose
-docker-compose logs teable | grep -i migration
-
-# Kubernetes
-kubectl logs deployment/teable -n teable | grep -i migration
+docker compose logs teable | grep -i migration
```
## Rollback
-If you encounter issues after upgrading, you can rollback to the previous version.
-
-### Docker Compose Rollback
+If you hit issues after upgrading:
-1. Modify the image tag in `docker-compose.yaml` to the previous version
-2. Execute `docker-compose up -d`
+1. Set the image tag in `docker-compose.yaml` back to the previous release tag
+ (this is why pinning beats `latest`: the previous version is written down).
+2. `docker compose up -d`
-### Kubernetes Rollback
-
-```bash
-# View rollout history
-kubectl rollout history deployment/teable -n teable
-
-# Rollback to previous version
-kubectl rollout undo deployment/teable -n teable
-
-# Rollback to specific revision
-kubectl rollout undo deployment/teable -n teable --to-revision=
-```
+
+Rolling back **after** a release that migrated the database schema may not be
+safe — restore from your pre-upgrade backup in that case. This is the main
+reason for the backup recommendation above.
+
## FAQ
@@ -147,18 +106,18 @@ Typically, pulling new images takes a few minutes (depending on network speed),
-Using `docker-compose up -d` or Kubernetes rolling update, there will be a brief service interruption (usually a few seconds to tens of seconds). For zero-downtime upgrades, we recommend using Kubernetes with appropriate rolling update strategies configured.
+Using `docker compose up -d` there will be a brief service interruption (usually a few seconds to tens of seconds).
You can check the current version by:
- Viewing the version number at the bottom left of the Teable interface
- Using an admin account to access the admin panel
-- Running `docker inspect teable-teable-1 --format='{{.Config.Image}}'` to check the image version
+- Running `docker inspect --format='{{.Config.Image}}'` to check the image version. If you run the `latest` channel, the full-featured deployment ships a `pin-image.sh` helper that resolves which release `latest` currently is.
-1. First check container logs to troubleshoot: `docker-compose logs teable`
+1. First check container logs to troubleshoot: `docker compose logs teable`
2. If it's a database migration issue, try restoring from backup
3. If the issue persists, rollback to the previous version
4. Contact support at support@teable.ai
diff --git a/images/selfhosted/database-connection/2026-05-29-database-connection-overview-en.png b/images/selfhosted/database-connection/2026-05-29-database-connection-overview-en.png
deleted file mode 100644
index a8bb5e1e..00000000
Binary files a/images/selfhosted/database-connection/2026-05-29-database-connection-overview-en.png and /dev/null differ
diff --git a/images/selfhosted/database-connection/2026-05-29-database-connection-overview-zh.png b/images/selfhosted/database-connection/2026-05-29-database-connection-overview-zh.png
deleted file mode 100644
index ff24d8ad..00000000
Binary files a/images/selfhosted/database-connection/2026-05-29-database-connection-overview-zh.png and /dev/null differ
diff --git a/zh/api-doc/sql-query.mdx b/zh/api-doc/sql-query.mdx
index 6b54e81e..20b1b481 100644
--- a/zh/api-doc/sql-query.mdx
+++ b/zh/api-doc/sql-query.mdx
@@ -4,7 +4,7 @@ noindex: true
---
-**仅适用于私有化部署**:无连接数限制。开启方式请查看[数据库连接](/zh/deploy/database-connection)。
+**仅适用于私有化部署**:无连接数限制。
Teable 允许您通过外部工具连接底层 PostgreSQL 数据库进行只读查询。支持 BI 工具(PowerBI、Metabase、Superset)、数据库客户端(DataGrip、Navicat、TablePlus)、低代码平台(Appsmith、Budibase)以及应用程序代码。
diff --git a/zh/basic/admin-panel/ai-setting.mdx b/zh/basic/admin-panel/ai-setting.mdx
index 47223cc7..68e79142 100644
--- a/zh/basic/admin-panel/ai-setting.mdx
+++ b/zh/basic/admin-panel/ai-setting.mdx
@@ -12,7 +12,7 @@ description: "为私有化部署实例配置 AI 对话、AI 字段、AI 自动
## 开始前的准备
-在进入 AI 配置页之前,先确认下面这些准备项已经就绪。私有化部署如需使用 AI 对话和应用构建器,请先按照[部署 Agent Runtime](/zh/deploy/agent-runtime)完成部署。
+在进入 AI 配置页之前,先确认下面这些准备项已经就绪。私有化部署如需使用 AI 对话和应用构建器,请先部署运行平面,见 [架构](/zh/deploy/architecture)。
| 准备项 | 是否必需 | 说明 |
|------|------|------|
@@ -77,7 +77,7 @@ description: "为私有化部署实例配置 AI 对话、AI 字段、AI 自动
### 配置 Agent Runtime 与应用构建器
-私有化部署如需使用 **AI 对话** 和 **应用构建器**,需要先完成 Agent Runtime 配置,并配置兼容的聊天模型。使用自带 Key 时,聊天模型必须来自 **OpenAI Compatible**(OpenAI 兼容)或 **Anthropic** 类型的提供商。Agent Runtime 的私有化部署仍处于早期阶段,配置流程较繁琐。请按照[部署 Agent Runtime](/zh/deploy/agent-runtime)部署所需服务,该文档会根据实际部署反馈持续迭代。如需协助,请联系 **support@teable.ai**。
+私有化部署如需使用 **AI 对话** 和 **应用构建器**,需要先完成 Agent Runtime 配置,并配置兼容的聊天模型。使用自带 Key 时,聊天模型必须来自 **OpenAI Compatible**(OpenAI 兼容)或 **Anthropic** 类型的提供商。请先部署运行平面 —— 见 [架构](/zh/deploy/architecture) 与 [teable-deployment](https://github.com/teableio/teable-deployment) 仓库。如需协助,请联系 **support@teable.ai**。
@@ -125,7 +125,7 @@ description: "为私有化部署实例配置 AI 对话、AI 字段、AI 自动
-请检查当前部署是否已经按照[部署 Agent Runtime](/zh/deploy/agent-runtime)完成部署,并配置所需的 Teable 环境变量。如需协助,请联系 **support@teable.ai**。
+请检查运行平面是否已部署并接通(见 [架构](/zh/deploy/architecture)),以及所需的 Teable 环境变量是否配置 —— 部署仓库自带的 doctor 脚本可以整链验证。如需协助,请联系 **support@teable.ai**。
diff --git a/zh/basic/admin-panel/sandbox-agent.mdx b/zh/basic/admin-panel/sandbox-agent.mdx
index 776890ef..c0de5239 100644
--- a/zh/basic/admin-panel/sandbox-agent.mdx
+++ b/zh/basic/admin-panel/sandbox-agent.mdx
@@ -10,7 +10,7 @@ description: "配置和管理沙箱 Agent。"
**沙箱 Agent** 页面包含 **设置** 和 **沙箱** 两个页签,用于配置 AI 对话的沙箱运行方式。
-私有化部署请先完成[部署 Agent Runtime](/zh/deploy/agent-runtime),再配置此页面。
+私有化部署请先部署全功能运行平面,见 [架构](/zh/deploy/architecture)。
## 运行限制
diff --git a/zh/basic/ai/app-builder.mdx b/zh/basic/ai/app-builder.mdx
index 9048cf36..66be4e77 100644
--- a/zh/basic/ai/app-builder.mdx
+++ b/zh/basic/ai/app-builder.mdx
@@ -246,7 +246,7 @@ Teable 自动跟踪每一次部署。
- 如果您使用私有化部署的 Teable,请参考 [AI 配置](/zh/basic/admin-panel/ai-setting) 页面完成配置。如需让应用构建器使用自带 Key,聊天模型必须来自 **OpenAI Compatible**(OpenAI 兼容)或 **Anthropic** 类型的提供商。Agent Runtime 的私有化部署仍处于早期阶段,配置流程较繁琐;请联系 Teable:**support@teable.ai**,获取部署协助。
+ 如果您使用私有化部署的 Teable,请参考 [AI 配置](/zh/basic/admin-panel/ai-setting) 页面完成配置。如需让应用构建器使用自带 Key,聊天模型必须来自 **OpenAI Compatible**(OpenAI 兼容)或 **Anthropic** 类型的提供商。如需部署协助,请联系 Teable:**support@teable.ai**。
发布前,请先确认 Teable 和对象存储(MinIO / S3)都能被公网访问;不确定时,可以在 [AI 配置](/zh/basic/admin-panel/ai-setting) 页面使用 **测试公网访问** 进行验证。
diff --git a/zh/deploy/activate.mdx b/zh/deploy/activate.mdx
index 50d8e395..b3c6bbd5 100644
--- a/zh/deploy/activate.mdx
+++ b/zh/deploy/activate.mdx
@@ -25,8 +25,7 @@ Teable 为自托管部署提供了不同的订阅计划,每个计划都有其
如果您还未安装 Teable,请按照以下安装指南之一进行操作:
- [Docker 部署](/zh/deploy/docker)(推荐快速安装)
-- [Kubernetes 部署](/zh/deploy/k8s)(适用于生产环境)
-- [一键部署](/zh/deploy/one-key)(简化安装流程)
+- [全功能平台](/zh/deploy/architecture)(AI 能力与 App Builder,Docker 或 Kubernetes)
在进行下一步之前,请确保您的 Teable 实例已成功启动并运行。
diff --git a/zh/deploy/agent-runtime.mdx b/zh/deploy/agent-runtime.mdx
deleted file mode 100644
index 1294f215..00000000
--- a/zh/deploy/agent-runtime.mdx
+++ /dev/null
@@ -1,773 +0,0 @@
----
-title: "部署 Agent Runtime"
-description: "使用 Docker Compose 在 Linux 服务器上部署私有化 Teable Agent Runtime。"
----
-
-私有化部署商业版及以上适用
-
-Teable Agent Runtime 为 **AI 对话** 和 **应用构建器** 提供沙箱及应用运行时服务。本指南介绍如何使用 Docker Compose,在一台 Linux 服务器上部署完整服务栈。
-
-部署内容包括 AI 沙箱引擎、App Runtime、Git 仓库服务、制品存储和 TLS 网关。本文提供全部配置文件,无需 Kubernetes 或额外的代码仓库。
-
-
-Agent Runtime 的私有化部署仍处于早期阶段。本指南面向愿意率先体验的用户,并会根据实际部署反馈持续迭代。当前运行时通过 Teable Infra 使用 OpenSandbox,不再使用 Vercel Sandbox 或 Vercel Snapshot。如需部署协助,请联系 **support@teable.ai**。
-
-
-如需使用应用构建器预览和发布应用,请部署本文提供的完整服务栈。只运行 `opensandbox-server` 无法提供应用构建器所需的应用运行时、Git 仓库、制品存储和网关。
-
-## 架构
-
-对外只暴露 Caddy 网关的 80/443 端口,其余服务均在内部 Docker 网络中:
-
-| 服务 | 说明 | 内部端口 |
-|---|---|---|
-| **caddy** | TLS 终止 + 全部路由(控制台、沙箱/应用预览、S3、git) | 对外 80/443 |
-| **opensandbox-server** | AI 沙箱引擎(Docker 模式),通过宿主 `docker.sock` 按需创建沙箱容器 | 8090 |
-| **infra-service** | 控制台 UI + Infra API + App Runtime Docker 后端 + 内置应用网关 | 8080 |
-| **git-registry** | App Builder 的 git smart-http 服务(与 infra-service 共用镜像) | 8080 |
-| **minio** *(可选)* | 内置 S3 兼容制品存储(可换成外部 S3,请参阅[选择制品存储](#选择制品存储)) | 9000 / 9001 |
-| **minio-init** *(可选)* | 一次性任务:等待 MinIO 就绪并创建制品桶 | 不适用 |
-
-域名路由(均由根域名 `BASE_DOMAIN` 自动拼出):
-
-| 地址 | 用途 |
-|---|---|
-| `https://` | 控制台 UI + Infra API + 沙箱引擎 API(`/v1/*`) |
-| `https://{appId}.app.` | 已部署应用的访问入口 |
-| `https://{sandboxId}-{port}.sandbox.` | 沙箱端口预览 |
-| `https://s3.` | 制品存储(内置 MinIO 模式;预签名 URL 指向这里) |
-| `https://git.` | git smart-http(外部手动 clone 用,可选) |
-
-## 开始前的准备
-
-### 服务器要求
-
-| | 最低 | 推荐 |
-|---|---|---|
-| vCPU | 4 | 8 |
-| 内存 | 8 GB | 16 GB |
-| 磁盘 | 80 GB NVMe | 120+ GB NVMe |
-| 操作系统 | Ubuntu 22.04/24.04(x86_64) | 同左 |
-| 软件 | Docker Engine 24+、Docker Compose v2.24+、OpenSSL | 同左 |
-
-容量背景:每个活跃的构建会话运行一个沙箱容器(上限 2 vCPU / 4 GiB);每个已部署应用同样上限
-2 vCPU / 4 GiB(实际常用几百 MB)。基础服务共占约 1 到 1.5 GiB 内存。磁盘大头是容器镜像
-(预热后约 15 到 20 GB)加沙箱/应用的可写层,建议监控剩余空间。
-
-### DNS 与防火墙
-
-在 DNS 供应商处添加 **4 条 A 记录**,全部指向云主机公网 IP(通配证书只覆盖一级子域名,
-所以 4 条都需要):
-
-```
- A → <公网IP>
-*. A → <公网IP>
-*.app. A → <公网IP>
-*.sandbox. A → <公网IP>
-```
-
-域名托管在 Cloudflare 时,这 4 条记录请设置为**仅 DNS(灰云)**,不要开代理(橙云)。
-
-防火墙只放行入站 **22(SSH)、80、443**,其余端口一律不对外。
-
-### 容器镜像
-
-本部署默认使用 **GHCR + Docker Hub**。**所有镜像均为公开仓库,无需
-`docker login`**。Teable 镜像中的 `` 不是固定值;请分别打开对应的 GHCR Package 页面,
-使用该页面 Installation 命令中显示的版本标签。不同镜像的标签需要分别确认,不要假设相同。
-
-#### Docker Compose 管理的镜像
-
-| 用途 | 镜像模板 | Package page |
-|---|---|---|
-| 控制台 + Infra API + App Runtime(**infra-service 与 git-registry 共用**,后者只是换了启动入口) | `ghcr.io/teableio/teable-infra-service:` | [GHCR](https://github.com/orgs/teableio/packages/container/package/teable-infra-service) |
-| AI 沙箱引擎本体(OpenSandbox,Docker 运行时模式;Teable 构建版) | `ghcr.io/teableio/opensandbox-server:` | [GHCR](https://github.com/orgs/teableio/packages/container/package/opensandbox-server) |
-| TLS 边缘网关(自备证书模式用官方镜像;Cloudflare 模式本地构建,请参阅[选择 TLS 模式](#选择-tls-模式)) | `caddy:2.9.1` | [Docker Hub](https://hub.docker.com/_/caddy) |
-| 内置制品存储(仅内置 MinIO 模式;生产建议钉 digest) | `minio/minio:latest` | [Docker Hub](https://hub.docker.com/r/minio/minio) |
-| 一次性建桶工具(仅内置 MinIO 模式) | `minio/mc:latest` | [Docker Hub](https://hub.docker.com/r/minio/mc) |
-
-#### 运行时镜像
-
-以下镜像不由 compose 启动,而是由服务在运行期通过宿主 `docker.sock` 按需创建容器时使用。
-均为公开镜像,守护进程可直接匿名拉取;建议按照[预拉取运行时镜像](#预拉取运行时镜像)预拉到本地,避免首次创建沙箱/部署应用时的
-冷启动拉取延迟:
-
-| 用途 | 镜像模板 | Package page |
-|---|---|---|
-| 沙箱基准镜像(每个 AI 构建会话在其中运行) | `ghcr.io/teableio/teable-sandbox-agent:` | [GHCR](https://github.com/orgs/teableio/packages/container/package/teable-sandbox-agent) |
-| 应用运行基准镜像(每个已部署应用的容器镜像;**不配置则应用无法部署**) | `ghcr.io/teableio/teable-app-runtime:` | [GHCR](https://github.com/orgs/teableio/packages/container/package/teable-app-runtime) |
-| 沙箱内执行代理 execd(引擎自动注入进每个沙箱容器) | `ghcr.io/teableio/opensandbox-execd:v1.0.19-fix-1064` | [GHCR](https://github.com/orgs/teableio/packages/container/package/opensandbox-execd) |
-| 沙箱出网 sidecar egress(DNS 模式,引擎按需为每个沙箱创建) | `opensandbox/egress:v1.0.12` | [Docker Hub](https://hub.docker.com/r/opensandbox/egress) |
-
-execd 必须使用上表中由 Teable 构建的修复版镜像 `opensandbox-execd:v1.0.19-fix-1064`,不要替换为上游的 `opensandbox/execd` 镜像。
-
-### 选择制品存储
-
-| 模式 | 配置 | 说明 |
-|---|---|---|
-| **内置 MinIO**(默认) | `.env` 中 `S3_ENDPOINT` 留空、`COMPOSE_PROFILES=minio` | 自动启动 MinIO 并建桶;预签名 URL 统一走 `https://s3.`。 |
-| **外部 S3** | `S3_ENDPOINT` 填供应商 URL、`COMPOSE_PROFILES=`(置空) | 内置 MinIO 不再启动;`S3_ACCESS_KEY` / `S3_SECRET_KEY` / `S3_BUCKET` 须填供应商签发的值,**桶要预建**;供应商若仅支持 virtual-host style 另填 `S3_FORCE_PATH_STYLE=false`。 |
-
-## 创建部署文件
-
-### 部署目录
-
-在服务器上创建一个部署目录(下文以 `teable-runtime/` 为例),[配置文件](#配置文件)部分提供前四个文件的完整内容:
-
-```
-teable-runtime/
-├── .env # 根据部署环境修改
-├── compose.yaml # 服务编排,原样复制
-├── Caddyfile # 网关路由,按 TLS 模式调整两处
-├── opensandbox.toml # 沙箱引擎配置,原样复制
-├── compose.override.yaml # 部署时生成,Git 服务签名密钥
-├── certs/ # 仅自备证书(static)模式
-│ ├── fullchain.pem
-│ └── privkey.pem
-└── Dockerfile.caddy # 仅 Cloudflare TLS 模式
-```
-
-含密钥的文件是 `.env` 与 `compose.override.yaml`,请勿外发、勿提交到版本库。
-
-### 配置文件
-
-#### `.env`
-
-```bash .env
-# ============================================================================
-# Teable Agent Runtime 环境配置,唯一需要按部署环境修改的文件。
-# ============================================================================
-
-# === 域名与 TLS ===
-# 部署根域名,app.、sandbox.、s3. 和 git. 子域名由此生成。
-BASE_DOMAIN=teable.example.com
-# 控制台访问 Host,通常与 BASE_DOMAIN 相同,仅在需要单独域名时修改。
-INFRA_HOST=teable.example.com
-# 仅 cloudflare TLS 模式使用(static 模式留空):
-ACME_EMAIL=
-CLOUDFLARE_API_TOKEN=
-
-# === 密钥 ===
-# 整栈共用的一把 API Key(引擎鉴权 / Infra API / 控制台登录 / git 内部)。
-OPENSANDBOX_API_KEY=
-# 控制台会话签名密钥。
-SESSION_SECRET=
-# 内置 MinIO:生成的值将作为 MinIO root 账号。
-# 外部 S3:填写服务商签发的 access key 和 secret key。
-S3_ACCESS_KEY=
-S3_SECRET_KEY=
-
-# === 镜像,均为公开仓库,无需 docker login ===
-# Teable 镜像的 请分别从对应 GHCR package 页面的 Installation 命令复制。
-# infra-service 与 git-registry 共用此镜像。
-INFRA_SERVICE_IMAGE=ghcr.io/teableio/teable-infra-service:
-# 沙箱引擎。
-OPENSANDBOX_SERVER_IMAGE=ghcr.io/teableio/opensandbox-server:
-# 沙箱基准镜像(每个 AI 构建会话在其中运行)。
-SANDBOX_OPENSANDBOX_IMAGE=ghcr.io/teableio/teable-sandbox-agent:
-# 应用运行基准镜像(不配置则应用无法部署)。
-APP_RUNTIME_DEFAULT_IMAGE=ghcr.io/teableio/teable-app-runtime:
-# 允许部署的应用镜像前缀白名单,多个前缀以逗号分隔,必须包含上方默认镜像的前缀。
-APP_RUNTIME_ALLOWED_IMAGE_PREFIXES=ghcr.io/teableio/
-
-# TLS 网关镜像。static 模式使用官方镜像;Cloudflare 模式使用本地构建的 teable-caddy-cloudflare:2.9.1。
-CADDY_IMAGE=caddy:2.9.1
-# 第三方镜像默认使用 :latest。生产环境建议固定 digest,例如:
-# MINIO_IMAGE=minio/minio@sha256:...
-# MINIO_MC_IMAGE=minio/mc@sha256:...
-
-# === 制品存储(S3 / MinIO) ===
-# "minio" 表示启用内置 MinIO。改用外部 S3 时置空。
-COMPOSE_PROFILES=minio
-# 留空 = 内置 MinIO(预签名走 https://s3.)。
-# 填写外部 S3 兼容服务 URL(如 https://s3.your-provider.com)即可改用外部存储。
-# 同时将 COMPOSE_PROFILES 置空,并在服务商侧预先创建存储桶。
-S3_ENDPOINT=
-S3_BUCKET=teable-app-artifacts
-S3_REGION=us-east-1
-# 内置 MinIO 必须设置为 true。外部 S3 仅支持 virtual-host style 时设置为 false。
-S3_FORCE_PATH_STYLE=true
-
-# === Docker 网络(一般不改;SANDBOX_DOCKER_NETWORK 须与 opensandbox.toml
-# 的 network_mode 一致) ===
-APP_RUNTIME_DOCKER_NETWORK=teable-appnet
-SANDBOX_DOCKER_NETWORK=teable-sandbox-net
-```
-
-#### `compose.yaml`
-
-原样复制,无需修改(所有环境相关的值都取自 `.env`):
-
-```yaml
-# Teable Agent Runtime 单机 Docker 服务栈。
-name: teable-agent-runtime
-
-networks:
- # 控制面网:infra-service 与它拉起的应用容器同挂,内置网关才能按 IP 直达应用。
- teable-appnet:
- name: ${APP_RUNTIME_DOCKER_NETWORK:-teable-appnet}
- driver: bridge
- # 沙箱专用网:沙箱起在此网,与控制面隔离;opensandbox-server 同接以按容器 IP 直达。
- teable-sandbox-net:
- name: ${SANDBOX_DOCKER_NETWORK:-teable-sandbox-net}
- driver: bridge
-
-volumes:
- opensandbox-state:
- infra-state:
- git-registry-data:
- minio-data:
- caddy-data: # TLS 证书 + ACME 账号,务必持久化
- caddy-config:
- # Agent 共享工作区。external:先手动创建一次
- # docker volume create teable-agent-juicefs
- teable-agent-juicefs:
- external: true
-
-services:
- # AI 沙箱引擎(Docker 模式)。
- opensandbox-server:
- image: ${OPENSANDBOX_SERVER_IMAGE:?set in .env}
- container_name: opensandbox-server
- restart: unless-stopped
- networks: [teable-appnet, teable-sandbox-net]
- volumes:
- - /var/run/docker.sock:/var/run/docker.sock # 在宿主上创建沙箱
- - ./opensandbox.toml:/etc/opensandbox/config.toml:ro
- - opensandbox-state:/data
- environment:
- SANDBOX_CONFIG_PATH: /etc/opensandbox/config.toml
- # API key 经环境变量注入(不写进 toml)。
- OPENSANDBOX_SERVER_API_KEY: ${OPENSANDBOX_API_KEY:?set in .env}
-
- # 控制台 + Infra API + App Runtime Docker 后端 + 内置应用网关。
- infra-service:
- image: ${INFRA_SERVICE_IMAGE:?set in .env}
- container_name: infra-service
- restart: unless-stopped
- networks: [teable-appnet]
- volumes:
- - /var/run/docker.sock:/var/run/docker.sock # 起/管应用容器
- - infra-state:/var/lib/teable-app-runtime
- - teable-agent-juicefs:/mnt/juicefs
- environment:
- # --- 后端选择 ---
- APP_RUNTIME_BACKEND: docker
- K8S_IN_CLUSTER: "false"
- PORT: "8080"
- # --- 鉴权 / 会话(整栈共用一把 key) ---
- AUTH_PROVIDER: api-key
- SESSION_SECRET: ${SESSION_SECRET:?set in .env}
- OPENSANDBOX_API_KEY: ${OPENSANDBOX_API_KEY:?set in .env}
- INFRA_API_KEY: ${OPENSANDBOX_API_KEY}
- # --- 沙箱引擎 ---
- OPENSANDBOX_RUNTIME_URL: http://opensandbox-server:8090
- SANDBOX_OPENSANDBOX_IMAGE: ${SANDBOX_OPENSANDBOX_IMAGE:?set in .env}
- OPENSANDBOX_PREVIEW_WILDCARD_DOMAIN: "*.sandbox.${BASE_DOMAIN}"
- # --- App Runtime(Docker 后端) ---
- APP_RUNTIME_DOCKER_SOCKET_PATH: /var/run/docker.sock
- APP_RUNTIME_DOCKER_NETWORK: ${APP_RUNTIME_DOCKER_NETWORK:-teable-appnet}
- APP_RUNTIME_STATE_DIR: /var/lib/teable-app-runtime
- APP_RUNTIME_INGRESS_MODE: gateway
- APP_RUNTIME_HOST_MATCH_MODE: suffix
- APP_RUNTIME_DOMAIN: app.${BASE_DOMAIN:?set in .env} # 应用跑在 {appId}.app.<域名>
- APP_RUNTIME_PUBLIC_SCHEME: https
- APP_RUNTIME_DEFAULT_IMAGE: ${APP_RUNTIME_DEFAULT_IMAGE:-}
- APP_RUNTIME_ALLOWED_IMAGE_PREFIXES: ${APP_RUNTIME_ALLOWED_IMAGE_PREFIXES:-ghcr.io/teableio/}
- APP_RUNTIME_ARTIFACT_PUBLIC_ORIGIN: http://infra-service:8080 # 应用容器经内网服务名回源拉制品
- # --- 制品存储(S3 / 内置 MinIO) ---
- APP_RUNTIME_ARTIFACT_STORE_PROVIDER: s3
- APP_RUNTIME_ARTIFACT_S3_ENDPOINT: ${S3_ENDPOINT:-https://s3.${BASE_DOMAIN}}
- APP_RUNTIME_ARTIFACT_BUCKET: ${S3_BUCKET:-teable-app-artifacts}
- APP_RUNTIME_ARTIFACT_S3_REGION: ${S3_REGION:-us-east-1}
- APP_RUNTIME_ARTIFACT_S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY:?set in .env}
- APP_RUNTIME_ARTIFACT_S3_ACCESS_KEY_SECRET: ${S3_SECRET_KEY:?set in .env}
- APP_RUNTIME_ARTIFACT_S3_FORCE_PATH_STYLE: ${S3_FORCE_PATH_STYLE:-true}
- # --- git registry(JWT 密钥经 compose.override.yaml 注入) ---
- GIT_REGISTRY_ENABLED: "true"
- GIT_REGISTRY_INTERNAL_URL: http://git-registry:8080
- GIT_REGISTRY_SANDBOX_URL: http://git-registry:8080 # 沙箱走内网 clone
- GIT_REGISTRY_PUBLIC_URL: https://git.${BASE_DOMAIN} # 仅外部/手动 clone
- # --- 文件页 / S3 兼容接口 ---
- FILE_BROWSER_ENABLED: "true"
- FILE_BROWSER_ROOT: /mnt/juicefs
- S3_COMPAT_ENABLED: "true"
- healthcheck:
- test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:8080/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
- interval: 30s
- timeout: 5s
- retries: 5
- start_period: 40s
- depends_on:
- opensandbox-server:
- condition: service_started
- minio-init: # 等建好制品桶再启动
- condition: service_completed_successfully
- required: false # 外部 S3 模式(minio profile 停用)时忽略
-
- # App Builder 的 git smart-http(与 infra-service 同镜像,换启动入口)。
- git-registry:
- image: ${INFRA_SERVICE_IMAGE:?set in .env}
- container_name: git-registry
- restart: unless-stopped
- command: ["node", ".output/git-registry/server.mjs"]
- networks: [teable-appnet, teable-sandbox-net] # sandbox-net:沙箱直接内网 clone
- volumes:
- - git-registry-data:/data
- environment:
- GIT_REGISTRY_PORT: "8080"
- GIT_REGISTRY_DATA_DIR: /data
- GIT_REGISTRY_INTERNAL_API_KEY: ${OPENSANDBOX_API_KEY:?set in .env}
- # GIT_REGISTRY_JWT_PUBLIC_KEY 经 compose.override.yaml 注入
- healthcheck:
- test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:8080/healthz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
- interval: 30s
- timeout: 5s
- retries: 5
- start_period: 20s
-
- # 内置制品存储(profile "minio";外部 S3 模式停用)。
- minio:
- profiles: ["minio"]
- image: ${MINIO_IMAGE:-minio/minio:latest}
- container_name: minio
- restart: unless-stopped
- networks: [teable-appnet]
- command: server /data --console-address ":9001"
- volumes:
- - minio-data:/data
- environment:
- MINIO_ROOT_USER: ${S3_ACCESS_KEY:?set in .env}
- MINIO_ROOT_PASSWORD: ${S3_SECRET_KEY:?set in .env}
- MINIO_REGION: ${S3_REGION:-us-east-1}
- # 一次性建桶;infra-service 以它作启动门控。
- minio-init:
- profiles: ["minio"]
- image: ${MINIO_MC_IMAGE:-minio/mc:latest}
- container_name: minio-init
- restart: "no"
- networks: [teable-appnet]
- depends_on:
- - minio
- entrypoint: ["/bin/sh", "-c"]
- command:
- - >
- until mc alias set local http://minio:9000 "$$S3_ACCESS_KEY" "$$S3_SECRET_KEY" >/dev/null 2>&1; do
- echo 'waiting for minio...'; sleep 2;
- done;
- mc mb --ignore-existing "local/$$S3_BUCKET";
- echo "bucket $$S3_BUCKET ready";
- environment:
- S3_ACCESS_KEY: ${S3_ACCESS_KEY:?set in .env}
- S3_SECRET_KEY: ${S3_SECRET_KEY:?set in .env}
- S3_BUCKET: ${S3_BUCKET:-teable-app-artifacts}
-
-# TLS 边缘网关和路由,唯一对公网开放的服务。
- caddy:
- image: ${CADDY_IMAGE:-caddy:2.9.1}
- container_name: caddy
- restart: unless-stopped
- networks:
- teable-appnet:
- aliases:
- - s3.${BASE_DOMAIN} # 让 infra-service 在容器网内以预签名 host 直达 caddy
- ports:
- - "80:80" # ACME + http->https 跳转
- - "443:443"
- - "443:443/udp" # HTTP/3(QUIC),可选
- volumes:
- - ./Caddyfile:/etc/caddy/Caddyfile:ro
- - ./certs:/certs:ro # static TLS 模式的证书;cloudflare 模式空目录无害
- - caddy-data:/data
- - caddy-config:/config
- environment:
- BASE_DOMAIN: ${BASE_DOMAIN:?set in .env}
- INFRA_HOST: ${INFRA_HOST:?set in .env}
- ACME_EMAIL: ${ACME_EMAIL:-} # 仅 cloudflare 模式
- CLOUDFLARE_API_TOKEN: ${CLOUDFLARE_API_TOKEN:-} # 仅 cloudflare 模式
- OPENSANDBOX_API_KEY: ${OPENSANDBOX_API_KEY:?set in .env} # 沙箱预览请求服务端注入
- SANDBOX_PREVIEW_HOST: sandbox.${BASE_DOMAIN}
- depends_on:
- # caddy 不门控在上游健康上:它要先起来跑 ACME,上游未就绪时 reverse_proxy 会自动重试。
- opensandbox-server:
- condition: service_started
- infra-service:
- condition: service_started
- minio:
- condition: service_started
- required: false # 外部 S3 模式 minio 停用
- git-registry:
- condition: service_started
-```
-
-#### `Caddyfile`
-
-默认按 **static**(自备证书)模式写好;**cloudflare** 模式按照文件顶部注释和[选择 TLS 模式](#选择-tls-模式)调整两处:
-
-```caddyfile Caddyfile
-# Teable Agent Runtime 边缘网关。
-# 默认 TLS 模式 "static"(自备通配证书挂载在 /certs)。
-# 改用 "cloudflare"(DNS-01 自动签发)模式时:
-# 1. 取消下面全局块的注释;
-# 2. 删除 (site_tls) 片段里的 `tls /certs/...` 一行。
-
-# {
-# email {$ACME_EMAIL}
-# acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
-# }
-
-# 站点级 TLS(static 模式)。cloudflare 模式此片段留空。
-(site_tls) {
- tls /certs/fullchain.pem /certs/privkey.pem
-}
-
-# 控制台 + Infra API + 沙箱端口预览改写。
-# 引擎的端口预览接口(/v1/sandboxes/{id}/endpoints/{port})被改写为根路径子域名
-# {id}-{port}.sandbox.<域名>(不带 scheme,由消费方自行补全)。
-(infra_and_v1) {
- @endpoints path_regexp ep ^/v1/sandboxes/([a-z0-9-]+)/endpoints/([0-9]+)/?$
- handle @endpoints {
- header Content-Type application/json
- respond `{"endpoint":"{re.ep.1}-{re.ep.2}.{$SANDBOX_PREVIEW_HOST}"}` 200
- }
- # 沙箱引擎 API(鉴权头透传)
- handle /v1/* {
- reverse_proxy opensandbox-server:8090
- }
- # 控制台 / Infra API;应用预览也落这里(内置网关按 Host 命中)
- handle {
- reverse_proxy infra-service:8080
- }
-}
-
-# 沙箱预览(每个 沙箱+端口 是独立 origin):
-# Host = {id}-{port}.sandbox.<域名> -> 引擎 server-proxy。
-# API key 服务端注入(浏览器顶层导航带不了请求头);
-# Accept-Encoding=identity 关压缩避免多跳解码错;WebSocket 默认透传。
-(sandbox_preview) {
- @sbx header_regexp sbx Host ^([a-z0-9-]+)-([0-9]+)\.
- handle @sbx {
- rewrite * /v1/sandboxes/{re.sbx.1}/proxy/{re.sbx.2}{uri}
- reverse_proxy opensandbox-server:8090 {
- header_up OPEN-SANDBOX-API-KEY {env.OPENSANDBOX_API_KEY}
- header_up Accept-Encoding identity
- }
- }
- handle {
- respond 404
- }
-}
-
-# ---- 站点 ----
-
-# 控制台 + Infra API + 引擎 API(Teable 的 TEABLE_INFRA_API_URL 指向这里)
-{$INFRA_HOST} {
- import site_tls
- import infra_and_v1
-}
-
-# 已部署应用
-*.app.{$BASE_DOMAIN} {
- import site_tls
- reverse_proxy infra-service:8080
-}
-
-# 沙箱预览
-*.sandbox.{$BASE_DOMAIN} {
- import site_tls
- import sandbox_preview
-}
-
-# 制品存储(内置 MinIO 模式;预签名 URL 的 host 与此站点一致。
-# 外部 S3 模式下此块闲置,无害。)
-s3.{$BASE_DOMAIN} {
- import site_tls
- reverse_proxy minio:9000
-}
-
-# git smart-http(可选,外部手动 clone 用)
-git.{$BASE_DOMAIN} {
- import site_tls
- reverse_proxy git-registry:8080
-}
-```
-
-#### `opensandbox.toml`
-
-原样复制:
-
-```toml opensandbox.toml
-# OpenSandbox 引擎配置(Docker 运行时模式)。
-# API key 不写入此文件,由 Compose 环境变量 OPENSANDBOX_SERVER_API_KEY 注入。
-
-[server]
-host = "0.0.0.0"
-port = 8090
-api_key = "" # 经 env 注入,留空即可
-max_sandbox_timeout_seconds = 86400
-
-[runtime]
-type = "docker"
-# execd:注入进每个沙箱容器的执行代理。使用 Teable 构建的修复版,勿换上游官方镜像。
-execd_image = "ghcr.io/teableio/opensandbox-execd:v1.0.19-fix-1064"
-
-[store]
-type = "sqlite"
-path = "/data/opensandbox.db" # 落在 opensandbox-state 卷
-
-[storage]
-allowed_host_paths = [] # bind-mount 白名单(空 = 全放;生产建议锁定)
-volume_default_size = "1Gi"
-
-[docker]
-# 须与 .env 的 SANDBOX_DOCKER_NETWORK 一致(compose 创建的沙箱网);
-# 引擎经此网按容器 IP 直达沙箱。
-network_mode = "teable-sandbox-net"
-host_ip = "127.0.0.1" # direct 端口映射绑回环;预览统一走 Caddy
-drop_capabilities = ["AUDIT_WRITE", "MKNOD", "NET_ADMIN", "NET_RAW", "SYS_ADMIN", "SYS_MODULE", "SYS_PTRACE", "SYS_TIME", "SYS_TTY_CONFIG"]
-no_new_privileges = false # 允许沙箱内 setuid
-pids_limit = 4096 # 防 fork 炸弹
-
-[ingress]
-mode = "direct" # Docker 运行时仅支持 direct
-
-[egress]
-# 沙箱出网 sidecar,引擎按需为每个沙箱创建。
-image = "opensandbox/egress:v1.0.12"
-mode = "dns"
-```
-
-## 部署 Agent Runtime
-
-### 配置 `.env` 并生成密钥
-
-编辑[配置文件](#配置文件)中的 `.env`,填写以下必填项:
-
-- `BASE_DOMAIN` / `INFRA_HOST`:填写根域名,`INFRA_HOST` 通常与 `BASE_DOMAIN` 相同。
-- 镜像:按照[容器镜像](#容器镜像)中的清单填写;每个 Teable 镜像的 `` 从对应 GHCR package 页面的 Installation 命令复制;
-- 密钥项,用下面的命令生成后填入:
-
-```bash
-openssl rand -hex 32 # → OPENSANDBOX_API_KEY(整栈共用的一把 API Key)
-openssl rand -hex 32 # → SESSION_SECRET(控制台会话签名)
-openssl rand -hex 12 # → S3_ACCESS_KEY(内置 MinIO 模式;外部 S3 填供应商值)
-openssl rand -hex 24 # → S3_SECRET_KEY(同上)
-```
-
-### 选择 TLS 模式
-
-| 模式 | 准备 | 证书续期 |
-|---|---|---|
-| **static**(自备证书,默认) | 把 `fullchain.pem` + `privkey.pem` 放进 `certs/`。须为**单张多 SAN 证书**,覆盖 `` / `*.` / `*.app.` / `*.sandbox.` 四个名字(通配符只盖一级)。 | 手动:替换 `certs/` 文件后执行 `docker compose exec caddy caddy reload -c /etc/caddy/Caddyfile` |
-| **cloudflare**(DNS-01 自动签发) | 域名 DNS 托管在 Cloudflare;准备一个 API Token(权限 **Zone:Read + DNS:Edit**)。 | Caddy 全自动 |
-
-**static 模式**:上方配置文件默认使用此模式,放好证书即可,无需其他改动。
-可用以下命令自检证书与私钥是否匹配、SAN 是否覆盖四个名字:
-
-```bash
-openssl x509 -in certs/fullchain.pem -noout -text | grep -A1 'Subject Alternative Name'
-diff <(openssl x509 -in certs/fullchain.pem -noout -pubkey) \
- <(openssl pkey -in certs/privkey.pem -pubout) && echo "证书与私钥匹配"
-```
-
-**cloudflare 模式**需做 4 处调整:
-
-1. 官方 Caddy 镜像不带 DNS 插件,先把下面内容存为 `Dockerfile.caddy` 并在本机构建一次:
-
- ```dockerfile Dockerfile.caddy
- # 带 Cloudflare DNS 插件的 Caddy(通配证书须走 DNS-01,官方镜像无 DNS 插件)。
- # 请使用 Caddy 2.9.x。2.8.x 的 builder 会因 xcaddy 依赖漂移而编译失败。
- FROM caddy:2.9.1-builder AS builder
- RUN xcaddy build --with github.com/caddy-dns/cloudflare
-
- FROM caddy:2.9.1
- COPY --from=builder /usr/bin/caddy /usr/bin/caddy
- ```
-
- ```bash
- docker build -t teable-caddy-cloudflare:2.9.1 -f Dockerfile.caddy .
- ```
-
-2. `.env`:`CADDY_IMAGE=teable-caddy-cloudflare:2.9.1`,并填 `ACME_EMAIL` 与 `CLOUDFLARE_API_TOKEN`;
-3. `Caddyfile`:按文件顶部注释,取消全局块(`email` + `acme_dns cloudflare`)的注释;
-4. `Caddyfile`:删除 `(site_tls)` 片段里的 `tls /certs/...` 一行(证书改由 ACME 全自动管理)。
-
-Cloudflare 模式必须持久化 `caddy-data` 卷。该卷用于存储证书和 ACME 账号;如果丢失,Caddy 会在重建后重新申请证书,可能触发 Let's Encrypt 的频率限制。
-
-### 生成 Git 服务签名密钥
-
-git 服务使用一对 Ed25519 密钥签发/验证访问令牌。多行 PEM 放不进 `.env`,因此通过
-`compose.override.yaml` 注入(Docker Compose 会自动加载它)。在部署目录执行:
-
-```bash
-openssl genpkey -algorithm ed25519 -out git-jwt.key
-openssl pkey -in git-jwt.key -pubout -out git-jwt.pub
-{
- echo "services:"
- echo " infra-service:"
- echo " environment:"
- echo " GIT_REGISTRY_JWT_PRIVATE_KEY: |"
- sed 's/^/ /' git-jwt.key
- echo " git-registry:"
- echo " environment:"
- echo " GIT_REGISTRY_JWT_PUBLIC_KEY: |"
- sed 's/^/ /' git-jwt.pub
-} > compose.override.yaml
-rm -f git-jwt.key git-jwt.pub
-```
-
-生成的 `compose.override.yaml` 结构如下(PEM 内容为你生成的密钥):
-
-```yaml compose.override.yaml
-services:
- infra-service:
- environment:
- GIT_REGISTRY_JWT_PRIVATE_KEY: |
- -----BEGIN PRIVATE KEY-----
- ...你生成的私钥...
- -----END PRIVATE KEY-----
- git-registry:
- environment:
- GIT_REGISTRY_JWT_PUBLIC_KEY: |
- -----BEGIN PUBLIC KEY-----
- ...你生成的公钥...
- -----END PUBLIC KEY-----
-```
-
-要轮换密钥,重新执行本节命令即可。
-
-> 若 `openssl genpkey` 报 `Algorithm ed25519 not found`(如 macOS 自带的 LibreSSL),
-> 可改用 Docker 生成密钥对,再执行上面的拼装命令:
->
-> ```bash
-> docker run --rm node:22-slim node -e 'const c=require("crypto");const{privateKey}=c.generateKeyPairSync("ed25519");process.stdout.write(privateKey.export({type:"pkcs8",format:"pem"}))' > git-jwt.key
-> docker run --rm -v "$PWD:/w" node:22-slim node -e 'const c=require("crypto"),fs=require("fs");const k=c.createPrivateKey(fs.readFileSync("/w/git-jwt.key"));fs.writeFileSync("/w/git-jwt.pub",c.createPublicKey(k).export({type:"spki",format:"pem"}))'
-> ```
-
-### 创建共享工作区卷
-
-Agent 共享工作区使用一个外部卷(compose 声明为 `external`,不会自动创建/删除):
-
-```bash
-docker volume create teable-agent-juicefs
-```
-
-### 预拉取运行时镜像
-
-全部为公开镜像,无需 docker login:
-
-```bash
-set -a; . ./.env; set +a
-docker pull "$OPENSANDBOX_SERVER_IMAGE"
-docker pull "$SANDBOX_OPENSANDBOX_IMAGE"
-docker pull "$APP_RUNTIME_DEFAULT_IMAGE"
-docker pull ghcr.io/teableio/opensandbox-execd:v1.0.19-fix-1064
-docker pull opensandbox/egress:v1.0.12
-```
-
-execd 和 egress 的镜像地址必须与 `opensandbox.toml` 中的配置完全一致。
-
-### 启动服务
-
-```bash
-docker compose up -d
-docker compose ps # 全部服务应为 running / healthy,minio-init 为 exited(0)
-
-# cloudflare 模式首次启动看证书签发(约十几秒~1分钟)
-docker compose logs -f caddy
-```
-
-## 验证部署
-
-### 检查服务状态
-
-```bash
-KEY=$(grep '^OPENSANDBOX_API_KEY=' .env | cut -d= -f2)
-
-# 沙箱引擎
-curl -s -H "OPEN-SANDBOX-API-KEY: $KEY" https:///v1/sandboxes; echo
-# Infra API
-curl -s -o /dev/null -w "health -> %{http_code}\n" https:///api/health
-```
-
-控制台 UI:浏览器打开 `https://`(或你填的 `INFRA_HOST`),用 api-key 登录,
-key 即 `.env` 中的 `OPENSANDBOX_API_KEY`。
-
-### 对接 Teable
-
-在 Teable 部署中添加以下环境变量:
-
-```bash
-TEABLE_INFRA_API_URL=https://
-TEABLE_INFRA_API_KEY=
-SANDBOX_OPENSANDBOX_IMAGE=ghcr.io/teableio/teable-sandbox-agent:
-APP_DEPLOY_PROVIDER=docker-runtime
-```
-
-`TEABLE_INFRA_API_KEY` 必须与 Agent Runtime `.env` 中的 `OPENSANDBOX_API_KEY` 使用相同的值。`SANDBOX_OPENSANDBOX_IMAGE` 也必须与 Agent Runtime 配置的沙箱镜像一致。
-
-`TEABLE_INFRA_API_URL` 必须指向 Teable Infra 根地址,不能包含路径。更新环境变量后,重启 Teable。
-
-## 故障排查
-
-| 问题 | 检查项 |
-|---|---|
-| Teable 提示 Agent Runtime 未配置 | 确认上方 4 个 Teable 环境变量均已设置,然后重启 Teable。 |
-| 沙箱或应用预览出现 DNS、TLS 或 404 错误 | 确认 4 条 DNS 记录均指向服务器,并且证书覆盖所有必需域名。 |
-| 首次创建沙箱或部署应用较慢 | 在首次使用前预拉取全部运行时镜像。 |
-| 服务状态异常 | 运行 `docker compose ps`,再通过 `docker compose logs ` 查看对应服务日志。 |
-
-
-如需部署协助,请联系 **support@teable.ai**,并提供 `docker compose ps` 的输出和相关服务日志。
-
-
-## 日常运维
-
-### 查看日志和管理服务
-
-```bash
-docker compose logs -f infra-service # / opensandbox-server / caddy / git-registry
-docker compose restart infra-service
-docker compose down # 停止服务,保留数据卷
-```
-
-### 升级
-
-修改 `.env` 中的镜像 tag,然后执行 `docker compose pull && docker compose up -d`。
-
-沙箱、应用基准镜像或 execd/egress 更新后,请按照[预拉取运行时镜像](#预拉取运行时镜像)重新拉取。
-
-### 备份数据
-
-建议定期备份以下数据卷,尤其是 `minio-data` 与 `caddy-data`。
-
-| 卷 | 内容 |
-|---|---|
-| `opensandbox-state` | 沙箱引擎状态(SQLite) |
-| `infra-state` | App Runtime 状态与草稿 |
-| `git-registry-data` | git 仓库数据 |
-| `minio-data` | 制品文件(内置 MinIO 模式) |
-| `teable-agent-juicefs` | Agent 共享工作区(external 卷,部署时创建) |
-| `caddy-data` / `caddy-config` | TLS 证书、ACME 账号、Caddy 配置 |
-
-`docker compose down -v` 会同时删除数据卷,包括制品、Git 仓库和证书。请谨慎使用。
-
-## 安全与限制
-
-### 安全须知
-
-- 含密钥的文件只有 `.env` 与 `compose.override.yaml`,**切勿提交到版本库或外发**。
-- 整栈共用一把 `OPENSANDBOX_API_KEY`;如需分权,请分别替换各服务的对应环境变量。
-- `docker.sock` 挂载进 opensandbox-server 与 infra-service(Docker 后端必需),等价于宿主 root
- 权限,请只在专用、可信的主机上部署。
-- 唯一公网面是 Caddy 的 80/443;MinIO 控制台(9001)不对外,需要时用 SSH 隧道访问。
-- 沙箱与宿主共享内核,**不是多租户强隔离边界**;对外开放多租户场景请为沙箱引擎配置
- gVisor / Kata 等强隔离运行时。
-
-### 能力边界
-
-**可用**:沙箱引擎全功能;应用主链路(创建 → 激活 → 网关访问 → 删除,含 dashboard、日志、
-S3 制品);git 推拉;控制台 api-key 登录 + Infra API;文件页与 S3 兼容接口。
-
-**不可用 / 受限**(Docker 模式取舍):应用 `host-prefix` 改名(返回 501)、`scale-to-zero`
-闲置缩容(no-op)、引擎 key 轮换 / server 滚动升级、控制台 Kubernetes 观测页(显示为空属正常)。
diff --git a/zh/deploy/architecture.mdx b/zh/deploy/architecture.mdx
new file mode 100644
index 00000000..78953fb3
--- /dev/null
+++ b/zh/deploy/architecture.mdx
@@ -0,0 +1,143 @@
+---
+title: "架构"
+description: "私有化部署的 Teable 由什么组成:应用与数据服务,以及支撑 AI 会话、App Builder 与应用部署的运行平面。"
+---
+
+Teable 本身就是 AI 产品:**AI Chat**、**App Builder** 与**应用部署**是平台的
+一部分,不是外挂。因此一套私有化部署,除了 Teable 应用与它的数据服务,还包括
+支撑这些 AI 能力的**运行平面**。本页讲各部分如何协同;可部署资产(compose、
+Helm chart、values)全部在
+[teableio/teable-deployment](https://github.com/teableio/teable-deployment)
+仓库中维护,那里是唯一事实源 —— 本页没有任何需要复制的内容。
+
+AI 能力面向私有化部署 Business 及以上套餐提供。
+
+## 一套部署包含什么
+
+| 服务 | 职责 |
+|---|---|
+| **Teable 应用** | Web 界面、API、自动化、AI 对话 —— 单一镜像:`ghcr.io/teableio/teable` |
+| **PostgreSQL** | 数据事实源:表、视图、元数据 |
+| **Redis** | 缓存、队列、实时协作 |
+| **对象存储** | S3 兼容,三个桶:**public**(头像与公开资源)、**private**(附件)、**build artifacts**(App Builder 构建产物) |
+| **Infra Service** | 控制台与 API —— Teable 应用唯一的对接点;编排构建与应用部署 |
+| **沙箱引擎** | 每个 AI 会话都在独立的沙箱容器中运行 |
+| **Git 仓库服务** | 你构建的应用的源码事实源(App Builder 推送至此) |
+| **预览网关** | 在浏览器中提供沙箱预览与已部署应用的访问 |
+
+后四个服务构成**运行平面**;部署资产会把以上全部作为一个平台一次装好。
+
+## 如何协同
+
+```mermaid
+graph LR
+ U["浏览器"]
+ subgraph "应用与数据"
+ T["Teable 应用"]
+ P[("PostgreSQL")]
+ R[("Redis")]
+ S[("对象存储")]
+ end
+ subgraph "运行平面"
+ I["Infra Service"]
+ E["沙箱 —— 每个 AI 会话一个"]
+ A["已部署应用 —— 每个一个容器"]
+ G["Git 仓库服务"]
+ W["预览网关"]
+ end
+ U --> T
+ T --> P
+ T --> R
+ T -- "附件" --> S
+ T -- "AI 会话" --> I
+ I -- "启动" --> E
+ I -- "部署" --> A
+ E -. "源码" .-> G
+ E -. "构建产物" .-> S
+ U -- "沙箱预览" --> W
+ U -- "已部署应用" --> W
+ W --> E
+ W --> A
+
+ style T fill:#0D9373,stroke:#0a7a5e,color:#fff
+ style E fill:#F59E0B,stroke:#b45309,color:#fff
+ style A fill:#F59E0B,stroke:#b45309,color:#fff
+```
+
+Teable 应用只通过**一个连接**触达运行平面:Infra Service
+(`TEABLE_INFRA_API_URL` / `TEABLE_INFRA_API_KEY`),其余全部是平面内部细节。
+平面上真正运行的,是两类负载:
+
+- **沙箱** —— 每个 AI 对话、每次 App Builder 构建会话,都按需启动一个独立
+ 容器,会话结束即销毁。这是平台最主要且突发性的负载:机器规格要按
+ **AI 会话峰值并发**来估,而不是按用户数(单个沙箱的资源限额可在管理面板配置)。
+- **已部署应用** —— 每个被部署出去的应用都是一个长驻容器,经 `*.app.`
+ 对外服务。沙箱来了又走,已部署应用则不断累积、持续运行。
+
+其余都是配套管线:构建在会话的沙箱内完成,Git 仓库服务与对象存储负责沉淀
+它产出的源码与构建产物,网关把浏览器路由到对应的沙箱或应用。
+
+## 一个域名,四条 DNS 记录
+
+一切派生自**一个基础域名** —— 通常是你组织域名的子域,例如 `teable.example.com`:
+
+| 记录 | 用途 |
+|---|---|
+| `` | Teable 应用 |
+| `infra.` | Infra 控制台与 API —— git(`/git` 路径)与对象存储(桶路径)共用此主机 |
+| `*.app.` | 你构建并部署的应用 |
+| `*.sandbox.` | 浏览器中的沙箱预览 |
+
+每个名字都只是默认值,任何主机名均可单独覆盖(见部署仓库的 values 示例)。
+
+## Agent 如何与应用保持同步
+
+沙箱 agent 镜像配置为**不带 tag 的前缀**。Teable 应用启动 AI 会话时会拼上
+**自身的发布版本 tag**,因此 agent 永远与应用版本配对 —— 并且应用会经
+Infra Service 预热这个镜像,首次会话不必现场拉取数 GB 镜像。
+你永远不需要手动拉取或钉定 agent。
+
+## 版本体系
+
+平台以部署仓库的**平台版本**(`v<年>.<月>.<序号>`)形式发布:
+
+- **tag** 是已验证的快照:`versions.yaml` 钉定每个组件镜像(含 digest),
+ 仓库的 `CHANGELOG.md` 写明每版变了什么、你需要做什么;
+- 仓库 `main` 分支是滚动最新;
+- 自带的 **doctor** 脚本会把你实际运行的组合与版本清单比对,给出三态结论:
+ 兼容 / 需升级 Teable 应用 / 未知(未经验证的)组合。
+
+Teable 应用有自己独立的发版线(日期型 tag;`latest` 为稳定通道)——
+见[版本升级](/zh/deploy/upgrade)。平台版本会声明应用兼容窗口,doctor 替你检查。
+
+## 部署
+
+两条路径安装的是同一套完整平台,部署仓库内有完整指引:
+
+
+
+ 一台机器装下一切 —— 首次全功能部署,支持 local / server 两种模式。
+
+
+ 一个伞形 chart 装进现有集群;只需设置 global.baseDomain。
+
+
+
+暂时不需要 AI?也可以只运行应用与 PostgreSQL、Redis、存储 ——
+即**基础版**部署([Docker 部署](/zh/deploy/docker)),之后随时把运行平面
+挂到旁边,数据原地不动。
+
+相关主题(均在部署仓库中维护):
+
+- **已在运行基础版 Teable?** 数据原地不动,运行平面挂在旁边即可:
+ [迁移指南](https://github.com/teableio/teable-deployment/blob/main/migration/2026-07-basic-to-full-featured.md)
+- **私有/企业 CA**:沙箱必须信任你入口的证书 ——
+ [private-ca.md](https://github.com/teableio/teable-deployment/blob/main/helm/private-ca.md)
+- **容量、版本与镜像加速**:[VERSIONS.md](https://github.com/teableio/teable-deployment/blob/main/VERSIONS.md) ·
+ [images/README.md](https://github.com/teableio/teable-deployment/blob/main/images/README.md)
+- **出问题时**:先跑 doctor,再看
+ [TROUBLESHOOTING.md](https://github.com/teableio/teable-deployment/blob/main/TROUBLESHOOTING.md)
+
+部署完成后,用 `TEABLE_INFRA_API_URL` / `TEABLE_INFRA_API_KEY` 把 Teable 应用接到
+运行平面(部署指引中有说明),然后在
+[管理面板 → Sandbox Agent](/zh/basic/admin-panel/sandbox-agent) 配置运行限制。
diff --git a/zh/deploy/aws.mdx b/zh/deploy/aws.mdx
deleted file mode 100644
index ac6d30ba..00000000
--- a/zh/deploy/aws.mdx
+++ /dev/null
@@ -1,384 +0,0 @@
----
-title: "在 AWS 上部署"
-description: "分步指引:在 AWS 上使用 ECS、RDS PostgreSQL、ElastiCache 与 S3 部署 Teable"
----
-
-
-**推荐场景**:50+ 用户的生产环境
-
-
-## 架构概览
-
-```mermaid
-graph TB
- ECS["AWS ECS
(Fargate 或 EC2)
Teable 应用: 4+ 副本
Sandbox: 2+ 副本 (可选)"]
-
- RDS["Amazon RDS
Aurora PostgreSQL"]
- ElastiCache["Amazon ElastiCache
(Valkey/Redis)
队列 & 缓存"]
- S3["Amazon S3
Public + Private 双桶"]
-
- ECS --> RDS
- ECS --> ElastiCache
- ECS --> S3
-
- style ECS fill:#ff9900,stroke:#cc7a00,color:#fff
- style RDS fill:#527fff,stroke:#3d5fd9,color:#fff
- style ElastiCache fill:#c925d1,stroke:#a01ba8,color:#fff
- style S3 fill:#569a31,stroke:#3f7224,color:#fff
-```
-
-## 前置要求
-
-- 已安装并配置 AWS CLI
-- AWS 账号具备 ECS、RDS、ElastiCache、S3、IAM 权限
-- Docker 镜像仓库访问权(或 ECR)
-
----
-
-## 步骤 1:创建 AWS 资源
-
-### 1.1 创建 RDS PostgreSQL
-
-```bash
-aws rds create-db-instance \
- --db-instance-identifier teable-db \
- --db-instance-class db.t3.medium \
- --engine postgres \
- --engine-version 16 \
- --master-username teableadmin \
- --master-user-password '<你的强密码>' \
- --allocated-storage 100 \
- --vpc-security-group-ids sg-xxxxxx \
- --db-subnet-group-name your-subnet-group \
- --publicly-accessible false
-```
-
-
-等待实例状态变为 `available`。获取 endpoint:
-```bash
-aws rds describe-db-instances \
- --db-instance-identifier teable-db \
- --query 'DBInstances[0].Endpoint.Address' --output text
-```
-
-
-### 1.2 创建 ElastiCache Redis(用于队列)
-
-```bash
-aws elasticache create-cache-cluster \
- --cache-cluster-id teable-cache \
- --engine redis \
- --cache-node-type cache.t3.small \
- --num-cache-nodes 1 \
- --engine-version 7.0 \
- --security-group-ids sg-xxxxxx \
- --cache-subnet-group-name your-subnet-group
-```
-
-
-获取 endpoint:
-```bash
-aws elasticache describe-cache-clusters \
- --cache-cluster-id teable-cache \
- --show-cache-node-info \
- --query 'CacheClusters[0].CacheNodes[0].Endpoint.Address' --output text
-```
-
-
-### 1.3 创建 S3 bucket(public + private)
-
-```bash
-# 创建 public bucket
-aws s3api create-bucket \
- --bucket teable-public-<你的唯一后缀> \
- --region us-west-2 \
- --create-bucket-configuration LocationConstraint=us-west-2
-
-# 创建 private bucket
-aws s3api create-bucket \
- --bucket teable-private-<你的唯一后缀> \
- --region us-west-2 \
- --create-bucket-configuration LocationConstraint=us-west-2
-```
-
-**必做:配置 public bucket**
-
-1. **Public read 策略**:
-
-```bash
-cat > public-bucket-policy.json </*"
- }
- ]
-}
-EOF
-
-aws s3api put-bucket-policy \
- --bucket teable-public-<你的唯一后缀> \
- --policy file://public-bucket-policy.json
-```
-
-2. **关闭 public bucket 的"阻止公共访问"**:
-
-```bash
-aws s3api put-public-access-block \
- --bucket teable-public-<你的唯一后缀> \
- --public-access-block-configuration \
- BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false
-```
-
-3. **CORS 配置**(允许任意跨域):
-
-```bash
-cat > cors.json < \
- --cors-configuration file://cors.json
-```
-
-
-**安全提醒**:public bucket 必须允许公开读。请确保符合你们公司的安全规范。private bucket 保持私有即可。
-
-
-### 1.4 创建 IAM 用户/角色用于 S3 访问
-
-```bash
-# 创建 IAM 用户
-aws iam create-user --user-name teable-s3-user
-
-# 附加 S3 完全访问策略(或创建自定义策略)
-aws iam attach-user-policy \
- --user-name teable-s3-user \
- --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
-
-# 创建访问密钥
-aws iam create-access-key --user-name teable-s3-user
-```
-
-
-保存输出中的 `AccessKeyId` 和 `SecretAccessKey`。
-
-
----
-
-## 步骤 2:准备环境变量
-
-创建 `.env` 文件(或 ECS 任务定义的环境变量):
-
-```bash
-# Core
-PUBLIC_ORIGIN=https://teable.yourcompany.com
-SECRET_KEY=<生成32位随机字符串>
-
-# Database
-PRISMA_DATABASE_URL=postgresql://teableadmin:@:5432/teable
-
-# Redis(队列依赖)
-BACKEND_CACHE_PROVIDER=redis
-BACKEND_CACHE_REDIS_URI=redis://:6379/0
-
-# 性能缓存(可选;可指向同一个 Redis 或单独集群)
-BACKEND_PERFORMANCE_CACHE=redis://:6379/0
-
-# Storage(S3 双桶)
-BACKEND_STORAGE_PROVIDER=s3
-BACKEND_STORAGE_S3_REGION=us-west-2
-BACKEND_STORAGE_S3_ENDPOINT=https://s3.us-west-2.amazonaws.com
-BACKEND_STORAGE_S3_ACCESS_KEY=<步骤1.4的access-key>
-BACKEND_STORAGE_S3_SECRET_KEY=<步骤1.4的secret-key>
-BACKEND_STORAGE_PUBLIC_BUCKET=teable-public-<你的唯一后缀>
-BACKEND_STORAGE_PRIVATE_BUCKET=teable-private-<你的唯一后缀>
-STORAGE_PREFIX=https://teable-public-<你的唯一后缀>.s3.us-west-2.amazonaws.com
-
-# 可选:Sandbox 服务(如果单独部署)
-# SANDBOX_URL=http://teable-sandbox:7070
-```
-
-
-生成强 `SECRET_KEY`:
-```bash
-openssl rand -base64 32
-```
-
-
----
-
-## 步骤 3:部署到 ECS
-
-### 方案 A:使用 ECS Fargate(推荐,简单)
-
-1. **创建 ECS 集群**:
-
-```bash
-aws ecs create-cluster --cluster-name teable-cluster
-```
-
-2. **创建任务定义** (`teable-task.json`):
-
-```json
-{
- "family": "teable",
- "networkMode": "awsvpc",
- "requiresCompatibilities": ["FARGATE"],
- "cpu": "2048",
- "memory": "4096",
- "containerDefinitions": [
- {
- "name": "teable",
- "image": "ghcr.io/teableio/teable:latest",
- "portMappings": [
- {
- "containerPort": 3000,
- "protocol": "tcp"
- }
- ],
- "environment": [
- {"name": "PUBLIC_ORIGIN", "value": "https://teable.yourcompany.com"},
- {"name": "SECRET_KEY", "value": "***REDACTED***"},
- {"name": "PRISMA_DATABASE_URL", "value": "postgresql://..."},
- {"name": "BACKEND_CACHE_PROVIDER", "value": "redis"},
- {"name": "BACKEND_CACHE_REDIS_URI", "value": "redis://..."},
- {"name": "BACKEND_STORAGE_PROVIDER", "value": "s3"},
- {"name": "BACKEND_STORAGE_S3_REGION", "value": "us-west-2"},
- {"name": "BACKEND_STORAGE_S3_ENDPOINT", "value": "https://s3.us-west-2.amazonaws.com"},
- {"name": "BACKEND_STORAGE_S3_ACCESS_KEY", "value": "***"},
- {"name": "BACKEND_STORAGE_S3_SECRET_KEY", "value": "***"},
- {"name": "BACKEND_STORAGE_PUBLIC_BUCKET", "value": "teable-public-xxx"},
- {"name": "BACKEND_STORAGE_PRIVATE_BUCKET", "value": "teable-private-xxx"},
- {"name": "STORAGE_PREFIX", "value": "https://teable-public-xxx.s3.us-west-2.amazonaws.com"}
- ],
- "logConfiguration": {
- "logDriver": "awslogs",
- "options": {
- "awslogs-group": "/ecs/teable",
- "awslogs-region": "us-west-2",
- "awslogs-stream-prefix": "teable"
- }
- }
- }
- ]
-}
-```
-
-3. **注册任务定义**:
-
-```bash
-aws ecs register-task-definition --cli-input-json file://teable-task.json
-```
-
-4. **创建 ECS 服务**:
-
-```bash
-aws ecs create-service \
- --cluster teable-cluster \
- --service-name teable-service \
- --task-definition teable \
- --desired-count 2 \
- --launch-type FARGATE \
- --network-configuration "awsvpcConfiguration={subnets=[subnet-xxx,subnet-yyy],securityGroups=[sg-xxx],assignPublicIp=ENABLED}" \
- --load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:...,containerName=teable,containerPort=3000"
-```
-
-
-你需要单独创建 Application Load Balancer (ALB) 和目标组,然后在 `--load-balancers` 中引用。
-
-
----
-
-## 步骤 4:验证部署
-
-1. **检查 ECS 服务状态**:
-
-```bash
-aws ecs describe-services \
- --cluster teable-cluster \
- --services teable-service
-```
-
-2. **查看日志**:
-
-```bash
-aws logs tail /ecs/teable --follow
-```
-
-3. **访问健康检查**:
-
-```bash
-curl https://teable.yourcompany.com/health
-```
-
-预期返回:
-```json
-{"status":"ok"}
-```
-
-4. **浏览器访问 Teable**:`https://teable.yourcompany.com`
-
----
-
-## 故障排查
-
-### 数据库连接错误
-
-- 验证 RDS 安全组允许来自 ECS 任务的流量
-- 检查 `PRISMA_DATABASE_URL` 格式:`postgresql://user:pass@endpoint:5432/dbname`
-
-### Redis 连接错误
-
-- 验证 ElastiCache 安全组允许来自 ECS 的流量
-- 使用 **主节点 endpoint**(不是只读副本)
-
-### S3 访问错误
-
-- 验证 IAM 用户具有 `s3:GetObject`、`s3:PutObject`、`s3:DeleteObject` 权限
-- 检查 bucket 名称在 `BACKEND_STORAGE_PUBLIC_BUCKET` / `BACKEND_STORAGE_PRIVATE_BUCKET` 中完全匹配
-- 确保 public bucket 已配置 public read 策略与 CORS
-
-### 容器启动失败
-
-- 检查 CloudWatch Logs:`/ecs/teable`
-- 验证所有必需环境变量已设置
-- 确保 `SECRET_KEY` 已设置(不为空)
-
----
-
-## 生产环境最佳实践
-
-
-详细的生产环境建议(包括配置、高可用、扩展策略)请参考 [私有化部署概览](/zh/deploy/production-overview)。
-
-
-**AWS 特定建议**:
-- 使用 AWS Secrets Manager 存储敏感值
-- 启用 RDS 静态加密
-- 使用 VPC endpoint 访问 S3/ECR 避免公网流量
-- 启用 CloudWatch Container Insights for ECS
-
----
-
-## 相关文档
-
-- [私有化部署概览](/zh/deploy/production-overview) — 架构、配置与扩展
-- [环境变量参考](/zh/deploy/env)
-- [对象存储(S3-compatible)](/zh/deploy/storage)
diff --git a/zh/deploy/azure.mdx b/zh/deploy/azure.mdx
deleted file mode 100644
index 4890175d..00000000
--- a/zh/deploy/azure.mdx
+++ /dev/null
@@ -1,820 +0,0 @@
----
-title: "在 Azure 上部署"
-description: "分步指引:在 Azure 上使用 App Service 或 AKS 部署 Teable,搭配 PostgreSQL Flexible Server、Azure Cache for Redis 与 S3-compatible 存储"
----
-
-
-**推荐场景**:50+ 用户的生产环境
-
-
-## 架构概览
-
-```mermaid
-graph TB
- AppService["Azure App Service
(Linux 容器)
Teable 应用
(按需扩展)"]
-
- DB["Azure Database for
PostgreSQL Flexible Server"]
- Redis["Azure Cache for Redis
(队列 & 缓存)"]
- S3["S3-compatible 存储
(AWS S3 或 MinIO)
Public + Private 双桶"]
-
- AppService --> DB
- AppService --> Redis
- AppService --> S3
-
- style AppService fill:#0078d4,stroke:#005a9e,color:#fff
- style DB fill:#0078d4,stroke:#005a9e,color:#fff
- style Redis fill:#0078d4,stroke:#005a9e,color:#fff
- style S3 fill:#ff9900,stroke:#cc7a00,color:#fff
-```
-
-
-**重要**:Teable 需要 **S3-compatible 存储**。你可以选择:
-- **AWS S3**(跨云方案)
-- **MinIO**(在 Azure VM/AKS 自建)
-- 其他 S3-compatible 服务
-
-Azure Blob Storage **不直接支持**,因为它使用不同的 API。
-
-
-## 前置要求
-
-- 已安装并登录 Azure CLI
-- Azure 订阅具备 App Service、PostgreSQL、Redis 权限
-- 具备 **S3-compatible 存储**访问权(例如 AWS S3 账号或 MinIO 部署)
-
----
-
-## 步骤 1:创建 Azure 资源
-
-### 1.1 创建资源组
-
-```bash
-az group create \
- --name teable-rg \
- --location eastus
-```
-
-### 1.2 创建 PostgreSQL Flexible Server
-
-```bash
-az postgres flexible-server create \
- --resource-group teable-rg \
- --name teable-db \
- --location eastus \
- --admin-user teableadmin \
- --admin-password '<你的强密码>' \
- --sku-name Standard_B2s \
- --tier Burstable \
- --storage-size 128 \
- --version 16 \
- --public-access 0.0.0.0-255.255.255.255
-```
-
-
-等待预配完成。获取连接字符串:
-```bash
-az postgres flexible-server show \
- --resource-group teable-rg \
- --name teable-db \
- --query "fullyQualifiedDomainName" --output tsv
-```
-结果:`teable-db.postgres.database.azure.com`
-
-
-### 1.3 创建 Azure Cache for Redis
-
-```bash
-az redis create \
- --resource-group teable-rg \
- --name teable-cache \
- --location eastus \
- --sku Basic \
- --vm-size c0 \
- --minimum-tls-version 1.2
-```
-
-
-获取访问密钥:
-```bash
-az redis list-keys \
- --resource-group teable-rg \
- --name teable-cache \
- --query "primaryKey" --output tsv
-```
-
-
----
-
-## 步骤 2:设置 S3-compatible 存储
-
-由于 Azure Blob Storage 不兼容 S3,请选择以下方案之一:
-
-### 方案 A:使用 AWS S3(跨云)
-
-如果你已有 AWS 访问权或不想管理 MinIO,这是最简单的方案。
-
-1. **在 AWS 上创建 S3 bucket**(参见 [AWS 部署指引](/zh/deploy/aws) 步骤 1.3-1.4)
- - Public bucket:`teable-public-<唯一后缀>`
- - Private bucket:`teable-private-<唯一后缀>`
-
-2. **配置 public bucket**(参见 [对象存储指引](/zh/deploy/storage)):
- - 启用 public read 访问
- - 配置 CORS 允许任意跨域
-
-你将使用这些环境变量:
-```bash
-BACKEND_STORAGE_PROVIDER=s3
-BACKEND_STORAGE_S3_REGION=us-west-2
-BACKEND_STORAGE_S3_ENDPOINT=https://s3.us-west-2.amazonaws.com
-BACKEND_STORAGE_S3_ACCESS_KEY=
-BACKEND_STORAGE_S3_SECRET_KEY=
-BACKEND_STORAGE_PUBLIC_BUCKET=teable-public-<后缀>
-BACKEND_STORAGE_PRIVATE_BUCKET=teable-private-<后缀>
-STORAGE_PREFIX=https://teable-public-<后缀>.s3.us-west-2.amazonaws.com
-```
-
-### 方案 B:在 Azure 上部署 MinIO
-
-如果希望所有资源都在 Azure,可部署 MinIO 作为 S3-compatible 网关。
-
-**推荐镜像**:`minio/minio:RELEASE.2025-04-22T22-12-26Z`
-
-**快速设置(Azure VM)**:
-
-1. 创建 VM 并安装 MinIO:
-```bash
-wget https://dl.min.io/server/minio/release/linux-amd64/minio
-chmod +x minio
-sudo mv minio /usr/local/bin/
-
-# 启动 MinIO
-export MINIO_ROOT_USER=admin
-export MINIO_ROOT_PASSWORD=<强密码>
-minio server /data --console-address ":9001"
-```
-
-2. 通过 MinIO 控制台(端口 9001)或 CLI 创建 bucket:
-```bash
-mc alias set myminio http://your-vm-ip:9000 admin <密码>
-mc mb myminio/public
-mc mb myminio/private
-mc policy set download myminio/public
-```
-
-你将使用这些环境变量:
-```bash
-BACKEND_STORAGE_PROVIDER=minio
-BACKEND_STORAGE_MINIO_ENDPOINT=
-BACKEND_STORAGE_MINIO_PORT=443
-BACKEND_STORAGE_MINIO_USE_SSL=true
-BACKEND_STORAGE_MINIO_ACCESS_KEY=admin
-BACKEND_STORAGE_MINIO_SECRET_KEY=<密码>
-BACKEND_STORAGE_PUBLIC_BUCKET=public
-BACKEND_STORAGE_PRIVATE_BUCKET=private
-STORAGE_PREFIX=https://
-```
-
----
-
-## 步骤 3:准备环境变量
-
-创建文件 `app-settings.txt`,包含所有必需变量:
-
-```bash
-# Core
-PUBLIC_ORIGIN=https://teable-app.azurewebsites.net
-SECRET_KEY=<生成32位随机字符串>
-
-# Database
-PRISMA_DATABASE_URL=postgresql://teableadmin:<密码>@teable-db.postgres.database.azure.com:5432/postgres?sslmode=require
-
-# Redis(队列依赖)
-BACKEND_CACHE_PROVIDER=redis
-BACKEND_CACHE_REDIS_URI=rediss://:@teable-cache.redis.cache.windows.net:6380/0
-
-# 性能缓存(可选;可指向同一个 Redis)
-BACKEND_PERFORMANCE_CACHE=rediss://:@teable-cache.redis.cache.windows.net:6380/0
-
-# Storage(S3-compatible)
-# 方案 A(AWS S3):
-BACKEND_STORAGE_PROVIDER=s3
-BACKEND_STORAGE_S3_REGION=us-west-2
-BACKEND_STORAGE_S3_ENDPOINT=https://s3.us-west-2.amazonaws.com
-BACKEND_STORAGE_S3_ACCESS_KEY=
-BACKEND_STORAGE_S3_SECRET_KEY=
-BACKEND_STORAGE_PUBLIC_BUCKET=teable-public-<后缀>
-BACKEND_STORAGE_PRIVATE_BUCKET=teable-private-<后缀>
-STORAGE_PREFIX=https://teable-public-<后缀>.s3.us-west-2.amazonaws.com
-
-# 方案 B(MinIO):
-# BACKEND_STORAGE_PROVIDER=minio
-# BACKEND_STORAGE_MINIO_ENDPOINT=
-# BACKEND_STORAGE_MINIO_PORT=443
-# BACKEND_STORAGE_MINIO_USE_SSL=true
-# BACKEND_STORAGE_MINIO_ACCESS_KEY=admin
-# BACKEND_STORAGE_MINIO_SECRET_KEY=<密码>
-# BACKEND_STORAGE_PUBLIC_BUCKET=public
-# BACKEND_STORAGE_PRIVATE_BUCKET=private
-# STORAGE_PREFIX=https://
-```
-
-
-生成强 `SECRET_KEY`:
-```bash
-openssl rand -base64 32
-```
-
-
----
-
-## 步骤 4:部署到 Azure App Service
-
-### 4.1 创建 App Service Plan
-
-```bash
-az appservice plan create \
- --resource-group teable-rg \
- --name teable-plan \
- --location eastus \
- --is-linux \
- --sku P1v3
-```
-
-### 4.2 创建 Web App(容器方式)
-
-```bash
-az webapp create \
- --resource-group teable-rg \
- --plan teable-plan \
- --name teable-app \
- --deployment-container-image-name ghcr.io/teableio/teable:latest
-```
-
-### 4.3 配置容器设置
-
-```bash
-az webapp config container set \
- --resource-group teable-rg \
- --name teable-app \
- --docker-custom-image-name ghcr.io/teableio/teable:latest \
- --docker-registry-server-url https://ghcr.io
-```
-
-### 4.4 设置环境变量
-
-```bash
-# 将 app-settings.txt 转为 JSON 格式并应用
-az webapp config appsettings set \
- --resource-group teable-rg \
- --name teable-app \
- --settings \
- WEBSITES_PORT=3000 \
- PUBLIC_ORIGIN="https://teable-app.azurewebsites.net" \
- SECRET_KEY="<你的secret>" \
- PRISMA_DATABASE_URL="postgresql://..." \
- BACKEND_CACHE_PROVIDER="redis" \
- BACKEND_CACHE_REDIS_URI="rediss://..." \
- BACKEND_PERFORMANCE_CACHE="rediss://..." \
- BACKEND_STORAGE_PROVIDER="s3" \
- BACKEND_STORAGE_S3_REGION="us-west-2" \
- BACKEND_STORAGE_S3_ENDPOINT="https://s3.us-west-2.amazonaws.com" \
- BACKEND_STORAGE_S3_ACCESS_KEY="***" \
- BACKEND_STORAGE_S3_SECRET_KEY="***" \
- BACKEND_STORAGE_PUBLIC_BUCKET="teable-public-xxx" \
- BACKEND_STORAGE_PRIVATE_BUCKET="teable-private-xxx" \
- STORAGE_PREFIX="https://teable-public-xxx.s3.us-west-2.amazonaws.com"
-```
-
-### 4.5 配置健康检查
-
-```bash
-az webapp config set \
- --resource-group teable-rg \
- --name teable-app \
- --generic-configurations '{"healthCheckPath": "/health"}'
-```
-
-### 4.6 重启应用
-
-```bash
-az webapp restart \
- --resource-group teable-rg \
- --name teable-app
-```
-
----
-
-## 步骤 5:验证部署
-
-1. **检查应用状态**:
-
-```bash
-az webapp show \
- --resource-group teable-rg \
- --name teable-app \
- --query "state" --output tsv
-```
-
-预期:`Running`
-
-2. **查看日志**:
-
-```bash
-az webapp log tail \
- --resource-group teable-rg \
- --name teable-app
-```
-
-3. **测试健康检查**:
-
-```bash
-curl https://teable-app.azurewebsites.net/health
-```
-
-预期返回:
-```json
-{"status":"ok"}
-```
-
-4. **浏览器访问 Teable**:`https://teable-app.azurewebsites.net`
-
----
-
-## 故障排查
-
-### 数据库连接错误
-
-- 验证 PostgreSQL 防火墙允许 Azure 服务
-- 检查连接字符串包含 `?sslmode=require`
-- 确保数据库名称正确(默认是 `postgres`,不是 `teable`)
-
-### Redis 连接错误
-
-- 使用 `rediss://`(双's')进行 TLS 连接
-- 使用端口 **6380**(不是 6379)连接 Azure Cache for Redis
-- 验证访问密钥正确
-
-### S3 访问错误(方案 A:AWS S3)
-
-- 验证 AWS 凭据正确
-- 检查 bucket 名称完全匹配
-- 确保 public bucket 已配置 public read 策略与 CORS
-- 测试 S3 从 Azure 的访问:`curl https://s3.us-west-2.amazonaws.com` 应该可用
-
-### 容器启动失败
-
-- 检查日志:`az webapp log tail ...`
-- 验证所有必需环境变量已设置
-- 确保 `WEBSITES_PORT=3000` 已设置
-
----
-
-## 生产环境最佳实践
-
-
-详细的生产环境建议(包括配置、高可用、扩展策略)请参考 [私有化部署概览](/zh/deploy/production-overview)。
-
-
-**Azure 特定建议**:
-- 使用 Azure Key Vault 存储敏感值
-- 启用仅 HTTPS:`az webapp update --https-only true`
-- 使用 VNet Integration 限制数据库/redis 访问
-- 启用 Application Insights 监控
-
-**自定义域名配置**:
-```bash
-# 添加自定义域名
-az webapp config hostname add \
- --resource-group teable-rg \
- --webapp-name teable-app \
- --hostname teable.yourcompany.com
-
-# 创建托管 SSL 证书
-az webapp config ssl create \
- --resource-group teable-rg \
- --name teable-app \
- --hostname teable.yourcompany.com
-```
-
----
-
-## 替代方案:在 AKS 上部署(Azure Kubernetes Service)
-
-对于大规模部署或已使用 Kubernetes 的团队,AKS 提供更好的可扩展性和控制能力。
-
-### AKS 架构
-
-```mermaid
-graph TB
- subgraph AKS["Azure Kubernetes Service"]
- Ingress["Ingress Controller
(AGIC 或 NGINX)"]
- Pods["Teable Pods
(水平扩展)"]
- end
-
- DB["Azure Database for
PostgreSQL Flexible Server"]
- Redis["Azure Cache for Redis"]
- S3["S3-compatible 存储
(MinIO 或 AWS S3)"]
-
- Ingress --> Pods
- Pods --> DB
- Pods --> Redis
- Pods --> S3
-
- style AKS fill:#326ce5,stroke:#1a4ba0,color:#fff
- style DB fill:#0078d4,stroke:#005a9e,color:#fff
- style Redis fill:#0078d4,stroke:#005a9e,color:#fff
- style S3 fill:#ff9900,stroke:#cc7a00,color:#fff
-```
-
-### 步骤 1:创建 AKS 集群
-
-```bash
-# 创建 AKS 集群
-az aks create \
- --resource-group teable-rg \
- --name teable-aks \
- --location eastus \
- --node-count 2 \
- --node-vm-size Standard_D4s_v3 \
- --enable-managed-identity \
- --generate-ssh-keys
-
-# 获取凭据
-az aks get-credentials \
- --resource-group teable-rg \
- --name teable-aks
-```
-
-### 步骤 2:创建 Azure 托管服务
-
-使用与 [步骤 1.2](#12-创建-postgresql-flexible-server) 和 [步骤 1.3](#13-创建-azure-cache-for-redis) 相同的命令创建 PostgreSQL 和 Redis。
-
-
-对于 AKS,建议启用 VNet 集成以保护连接:
-
-```bash
-# 获取 AKS VNet ID
-AKS_VNET=$(az aks show \
- --resource-group teable-rg \
- --name teable-aks \
- --query "networkProfile.networkPlugin" -o tsv)
-
-# 配置 PostgreSQL 接受来自 AKS VNet 的连接
-az postgres flexible-server vnet-rule create \
- --resource-group teable-rg \
- --server-name teable-db \
- --name aks-access \
- --vnet-name \
- --subnet
-```
-
-
-### 步骤 3:在 AKS 中部署 MinIO(可选)
-
-如果希望存储保持在 Azure 内部,可以在 AKS 中部署 MinIO:
-
-```yaml
-# minio-deployment.yaml
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: minio
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: minio
- template:
- metadata:
- labels:
- app: minio
- spec:
- containers:
- - name: minio
- image: minio/minio:latest
- args:
- - server
- - /data
- - --console-address
- - ":9001"
- env:
- - name: MINIO_ROOT_USER
- value: "minioadmin"
- - name: MINIO_ROOT_PASSWORD
- valueFrom:
- secretKeyRef:
- name: minio-secrets
- key: password
- ports:
- - containerPort: 9000
- - containerPort: 9001
- volumeMounts:
- - name: data
- mountPath: /data
- volumes:
- - name: data
- persistentVolumeClaim:
- claimName: minio-pvc
----
-apiVersion: v1
-kind: Service
-metadata:
- name: minio
-spec:
- ports:
- - name: api
- port: 9000
- targetPort: 9000
- - name: console
- port: 9001
- targetPort: 9001
- selector:
- app: minio
----
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- name: minio-pvc
-spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 50Gi
- storageClassName: managed-premium
-```
-
-
-对于生产环境的 MinIO 部署,建议使用 [MinIO Operator](https://min.io/docs/minio/kubernetes/upstream/) 实现分布式模式与数据冗余。
-
-
-### 步骤 4:创建 Kubernetes 配置
-
-创建包含 Azure 特定设置的 ConfigMap:
-
-```yaml
-# teable-config.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: teable-config
-data:
- PUBLIC_ORIGIN: "https://teable.yourcompany.com"
-
- # 存储(AKS 内的 MinIO)
- BACKEND_STORAGE_PROVIDER: "minio"
- BACKEND_STORAGE_MINIO_ENDPOINT: "minio.yourcompany.com"
- STORAGE_PREFIX: "https://minio.yourcompany.com"
- BACKEND_STORAGE_MINIO_INTERNAL_ENDPOINT: "minio.default.svc.cluster.local"
- BACKEND_STORAGE_MINIO_PORT: "443"
- BACKEND_STORAGE_MINIO_INTERNAL_PORT: "9000"
- BACKEND_STORAGE_MINIO_USE_SSL: "true"
-
- # 缓存
- BACKEND_CACHE_PROVIDER: "redis"
-
- # 其他
- NEXT_ENV_IMAGES_ALL_REMOTE: "true"
- PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING: "1"
-```
-
-创建包含 Azure 服务凭据的 Secrets:
-
-```yaml
-# teable-secrets.yaml
-apiVersion: v1
-kind: Secret
-metadata:
- name: teable-secrets
-type: Opaque
-stringData:
- # PostgreSQL (Azure Flexible Server)
- PRISMA_DATABASE_URL: "postgresql://teableadmin:<密码>@teable-db.postgres.database.azure.com:5432/postgres?sslmode=require"
-
- # 应用密钥
- SECRET_KEY: "<你的密钥>"
-
- # MinIO 凭据
- BACKEND_STORAGE_PUBLIC_BUCKET: "public"
- BACKEND_STORAGE_PRIVATE_BUCKET: "private"
- BACKEND_STORAGE_MINIO_ACCESS_KEY: "minioadmin"
- BACKEND_STORAGE_MINIO_SECRET_KEY: ""
-
- # Redis (Azure Cache for Redis)
- BACKEND_CACHE_REDIS_URI: "rediss://:@teable-cache.redis.cache.windows.net:6380/0"
-```
-
-### 步骤 5:部署 Teable
-
-```yaml
-# teable-deployment.yaml
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: teable
-spec:
- replicas: 2 # 按需扩展
- selector:
- matchLabels:
- app: teable
- template:
- metadata:
- labels:
- app: teable
- spec:
- initContainers:
- - name: db-migrate
- image: ghcr.io/teableio/teable:latest
- args:
- - migrate-only
- envFrom:
- - configMapRef:
- name: teable-config
- - secretRef:
- name: teable-secrets
- resources:
- limits:
- cpu: 1000m
- memory: 1024Mi
- containers:
- - name: teable
- image: ghcr.io/teableio/teable:latest
- args:
- - skip-migrate
- ports:
- - containerPort: 3000
- envFrom:
- - configMapRef:
- name: teable-config
- - secretRef:
- name: teable-secrets
- resources:
- requests:
- cpu: 500m
- memory: 1Gi
- limits:
- cpu: 2000m
- memory: 4Gi
- livenessProbe:
- httpGet:
- path: /health
- port: 3000
- initialDelaySeconds: 30
- periodSeconds: 30
- readinessProbe:
- httpGet:
- path: /health
- port: 3000
- initialDelaySeconds: 15
- periodSeconds: 10
----
-apiVersion: v1
-kind: Service
-metadata:
- name: teable
-spec:
- ports:
- - port: 3000
- targetPort: 3000
- selector:
- app: teable
-```
-
-### 步骤 6:配置 Ingress
-
-**方案 A:使用 NGINX Ingress Controller**
-
-```bash
-# 安装 NGINX Ingress
-helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
-helm install ingress-nginx ingress-nginx/ingress-nginx \
- --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz
-```
-
-```yaml
-# teable-ingress.yaml
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: teable
- annotations:
- kubernetes.io/ingress.class: nginx
- nginx.ingress.kubernetes.io/proxy-body-size: "100m"
- cert-manager.io/cluster-issuer: letsencrypt-prod
-spec:
- tls:
- - hosts:
- - teable.yourcompany.com
- secretName: teable-tls
- rules:
- - host: teable.yourcompany.com
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: teable
- port:
- number: 3000
-```
-
-**方案 B:使用 Azure Application Gateway Ingress Controller (AGIC)**
-
-```bash
-# 启用 AGIC 插件
-az aks enable-addons \
- --resource-group teable-rg \
- --name teable-aks \
- --addons ingress-appgw \
- --appgw-name teable-appgw \
- --appgw-subnet-cidr "10.225.0.0/16"
-```
-
-```yaml
-# teable-ingress-agic.yaml
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: teable
- annotations:
- kubernetes.io/ingress.class: azure/application-gateway
- appgw.ingress.kubernetes.io/backend-path-prefix: "/"
- appgw.ingress.kubernetes.io/ssl-redirect: "true"
-spec:
- tls:
- - hosts:
- - teable.yourcompany.com
- secretName: teable-tls
- rules:
- - host: teable.yourcompany.com
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: teable
- port:
- number: 3000
-```
-
-### 步骤 7:应用所有配置
-
-```bash
-# 应用配置
-kubectl apply -f teable-config.yaml
-kubectl apply -f teable-secrets.yaml
-kubectl apply -f minio-deployment.yaml # 如果在 AKS 中使用 MinIO
-kubectl apply -f teable-deployment.yaml
-kubectl apply -f teable-ingress.yaml
-
-# 验证部署
-kubectl get pods -l app=teable
-kubectl logs -l app=teable
-```
-
-### AKS 生产环境建议
-
-1. **自动扩缩容**:
-```bash
-# 启用 Horizontal Pod Autoscaler
-kubectl autoscale deployment teable --cpu-percent=70 --min=2 --max=10
-
-# 启用集群自动扩缩容
-az aks update \
- --resource-group teable-rg \
- --name teable-aks \
- --enable-cluster-autoscaler \
- --min-count 2 \
- --max-count 5
-```
-
-2. **使用 Azure Key Vault** 替代 Kubernetes secrets 存储敏感信息:
-```bash
-# 启用 Key Vault secrets provider
-az aks enable-addons \
- --resource-group teable-rg \
- --name teable-aks \
- --addons azure-keyvault-secrets-provider
-```
-
-3. **启用 Azure Monitor**:
-```bash
-az aks enable-addons \
- --resource-group teable-rg \
- --name teable-aks \
- --addons monitoring
-```
-
-4. **使用 Azure Private Link** 连接 PostgreSQL 和 Redis,保持流量在 Azure 网络内。
-
----
-
-## 相关文档
-
-- [私有化部署概览](/zh/deploy/production-overview) — 架构、配置与扩展
-- [环境变量参考](/zh/deploy/env)
-- [对象存储(S3-compatible)](/zh/deploy/storage)
-- [Kubernetes 部署](/zh/deploy/k8s)(通用 K8s 指南)
-- [AWS 部署](/zh/deploy/aws)(如使用跨云存储需参考 S3 设置)
diff --git a/zh/deploy/choose.mdx b/zh/deploy/choose.mdx
new file mode 100644
index 00000000..56f0497a
--- /dev/null
+++ b/zh/deploy/choose.mdx
@@ -0,0 +1,42 @@
+---
+title: "部署"
+description: "在 Teable Cloud、基础版自部署与全功能自部署之间做选择。"
+---
+
+运行 Teable 有三种方式,按需选择:
+
+| | **Teable Cloud** | **全功能自部署** | **基础版自部署** |
+|---|---|---|---|
+| 表格、协作、API、自动化 | ✅ | ✅ | ✅ |
+| AI 能力(对话、智能体) | ✅ | ✅ | ❌ |
+| App Builder(构建并部署应用) | ✅ | ✅ | ❌ |
+| 沙箱 / 预览 | ✅ | ✅ | ❌ |
+| 运行位置 | [teable.ai](https://teable.ai) —— 无需部署 | 一台机器(Docker)或 Kubernetes 集群 | 一台机器:应用 + PostgreSQL |
+| 从这里开始 | [teable.ai](https://teable.ai) | [架构](/zh/deploy/architecture) → [teableio/teable-deployment](https://github.com/teableio/teable-deployment) | [Docker 部署](/zh/deploy/docker) |
+
+
+基础版与全功能不是二选一的岔路:全功能平台是**在你现有基础版 Teable 旁边挂载一个
+运行平面** —— 业务数据原地不动。今天先跑基础版,以后随时加 AI:
+[迁移指南](https://github.com/teableio/teable-deployment/blob/main/migration/2026-07-basic-to-full-featured.md)。
+
+
+## 交给 AI agent 部署
+
+部署仓库本身就是按「可由 AI agent 驱动」来写的。把
+[teableio/teable-deployment](https://github.com/teableio/teable-deployment)
+交给你的 agent harness(Claude Code、Codex 等),说明你要部署到什么环境,
+它就能端到端完成部署。只需准备三样东西:
+
+1. **一个域名** —— 一切派生自一个基础域名,例如 `teable.example.com`;
+2. **DNS 平台 token** —— 域名托管平台(阿里云解析、DNSPod、Cloudflare 等)的
+ API token,用于自动创建解析记录与签发 TLS 证书,建议只授权这一个 zone;
+3. **部署目标的访问权限:**
+
+| 目标 | 交给 agent 的权限 |
+|---|---|
+| 本机 —— Docker 单机全栈 `local` 模式 | 本机装好 Docker 即可 —— 无需域名与 DNS token(全部走 `*.localhost`) |
+| 一台云服务器 —— Docker 单机全栈 | 机器的 SSH 访问 |
+| 托管集群 —— 阿里云(ACK)/ 腾讯云(TKE) | 创建一个集群,把它的 `kubeconfig` 交给 agent |
+| 任何现有 Kubernetes 集群 | 一份能安装 Helm release 的 `kubeconfig` |
+
+准备好这些就够了 —— 仓库内的指引、doctor 脚本与版本清单会带着 agent 走完其余全部。
diff --git a/zh/deploy/database-connection.mdx b/zh/deploy/database-connection.mdx
deleted file mode 100644
index bd5c4bb3..00000000
--- a/zh/deploy/database-connection.mdx
+++ /dev/null
@@ -1,22 +0,0 @@
----
-title: "启用外部数据库连接"
-description: "在应用中自动创建数据库角色允许外部应用对表格数据的安全访问功能"
----
-
-
-
-要启用此功能,需要额外配置 `PUBLIC_DATABASE_PROXY` 环境变量
-
-要将该参数配置为外部可访问的数据库 ip 或域名 + 端口号。如果你使用前面的 docker-compose 部署,则外部访问端口为 42345。其他方式请根据具体配置来进行
-
-```
-PUBLIC_DATABASE_PROXY=db-proxy.example.com:port
-```
-
-## 更多环境变量配置
-
-[环境变量](/zh/deploy/env)
diff --git a/zh/deploy/docker.mdx b/zh/deploy/docker.mdx
index 4ad3cbf5..093e4227 100644
--- a/zh/deploy/docker.mdx
+++ b/zh/deploy/docker.mdx
@@ -6,7 +6,7 @@ description: "使用 Docker Compose 部署 Teable,并配置常用部署选项
{/* mintlify-resync: 2026-05-14 */}
**Docker Compose 适合小团队和评估测试**(50 人以内)。
-生产环境部署请先阅读 [概览](/zh/deploy/production-overview),然后选择 [Kubernetes](/zh/deploy/k8s) 或云服务部署方案。
+不确定该选哪条路径?请先看[部署](/zh/deploy/choose)页。需要 AI 能力或 App Builder?请改用[全功能平台](/zh/deploy/architecture)。
## Docker Compose 部署
@@ -177,8 +177,6 @@ BACKEND_CACHE_REDIS_URI=redis://default:${REDIS_PASSWORD}@${REDIS_HOST}:${REDIS_
生产环境请使用 **S3-compatible 对象存储**(如 S3、MinIO、兼容 S3 的 OSS/OBS/COS 等),以获得更好的可靠性与扩展能力。
-详见:[对象存储(S3-compatible)](/zh/deploy/storage)
-
minio 提供了额外的存储管理界面(9001 端口)以及更强大的稳定的文件服务
@@ -448,8 +446,6 @@ POSTGRES_USER=teable
[配置邮件服务](/zh/deploy/email)
-[配置外部数据库连接](/zh/deploy/database-connection)
-
## 支持与反馈
如果您在部署过程中遇到任何问题,请联系我们的支持团队 support\@teable.ai 或[提交 issue](https://github.com/teableio/teable/issues)。
diff --git a/zh/deploy/env.mdx b/zh/deploy/env.mdx
index 31a4ed57..a903b1c0 100644
--- a/zh/deploy/env.mdx
+++ b/zh/deploy/env.mdx
@@ -4,19 +4,17 @@ description: "这里列举了Teable 所有可用的环境变量以及相关解
mode: "wide"
---
-{/* mintlify-resync: 2026-05-14 */}
-
-生产环境请使用 **S3-compatible 对象存储**(`s3` / `minio`),并按 **public/private 双桶**进行配置。同时请确保 public bucket 配置 **public-read + CORS**。详见:[对象存储(S3-compatible)](/zh/deploy/storage)。
-
-
| 环境变量 | 描述 | 默认值 | 必填 | 示例 |
| -------------------------------------------- | ------------------------------------------------------- | ---------------- | ---- | ------------------------------------------------ |
| **核心配置** | | | | |
| PUBLIC_ORIGIN | 用于生成完整 URL 的公共源,必须设置为您的应用程序访问地址 | - | 是 | https://app.teable.ai |
| SECRET_KEY | 用于 JWT、会话和共享的密钥,请使用强密码 | defaultSecretKey | 是 | yourStrongSecretKey |
+| BACKEND_STORAGE_ENCRYPTION_KEY | 存储令牌加密密钥。默认值是源码中的公开常量 —— 生产部署必须自行设置随机值(全功能部署资产会按主机自动生成) | 公开常量 | - | 16 位随机字符串 |
+| BACKEND_STORAGE_ENCRYPTION_IV | 与 BACKEND_STORAGE_ENCRYPTION_KEY 配对的加密 IV | 公开常量 | - | 16 位随机字符串 |
+| BACKEND_ACCESS_TOKEN_ENCRYPTION_KEY | 个人访问令牌加密密钥。同样注意:默认值公开,生产环境请自行设置 | 公开常量 | - | 16 位随机字符串 |
+| BACKEND_ACCESS_TOKEN_ENCRYPTION_IV | 与 BACKEND_ACCESS_TOKEN_ENCRYPTION_KEY 配对的加密 IV | 公开常量 | - | 16 位随机字符串 |
| PORT | 应用程序运行的端口 | 3000 | - | 3000 |
| LOG_LEVEL | 日志级别,可选值:fatal、error、warn、info、debug、trace | info | - | debug |
-| NEXT_ENV_IMAGES_ALL_REMOTE | 是否允许加载第三方图片 | false | - | true |
| **存储配置** | | | | |
| BACKEND_STORAGE_PROVIDER | 存储提供商,可选值:local、minio、s3、aliyun | local | - | s3 |
| BACKEND_STORAGE_LOCAL_PATH | 本地存储路径 | .assets/uploads | - | .assets/uploads |
@@ -79,7 +77,6 @@ mode: "wide"
| MAX_COPY_CELLS | 单次请求最大复制单元格数 | - | - | 50000 |
| MAX_READ_ROWS | 单次请求最大读取行数 | - | - | 10000 |
| MAX_ATTACHMENT_UPLOAD_SIZE | 附件上传最大大小(字节) | - | - | 2147483648 |
-| MAX_SPACE_OWNER_COUNT | 单个用户可作为所有者拥有或管理的最大空间数量 | 10 | - | 10 |
| TASK_MAX_FIELDS_PER_BATCH | 单次批量请求发送给模型的 AI 字段数量上限,取值会限制在 1 到 20 | 5 | - | 5 |
| TASK_MAX_CONCURRENCY | 每轮调度最多派发的待处理 AI 字段任务运行数,取值会限制在 1 到 20 | 5 | - | 5 |
| TABLE_LIMIT_FIELD_OPTIONS_MAX_BYTES | 字段选项序列化后的最大字节数 | 262144 | - | 262144 |
@@ -105,6 +102,19 @@ mode: "wide"
| TABLE_LIMIT_VIEW_OPTIONS_MAX_BYTES | 视图配置序列化后的最大字节数 | 262144 | - | 262144 |
| TABLE_LIMIT_NAME_MAX_LENGTH | 支持的表对象显示名称最大长度 | 100 | - | 100 |
| TABLE_LIMIT_DESCRIPTION_MAX_LENGTH | 支持的表对象描述最大长度 | 2000 | - | 2000 |
+| **AI 与 App Builder(运行平面接入)** | | | | |
+| SANDBOX_PROVIDER | AI 会话的沙箱提供方;`opensandbox` 表示接入自部署运行平面 | - | - | opensandbox |
+| TEABLE_INFRA_API_URL | 运行平面入口 URL —— 必须是公共入口(它负责把 `/v1` 分流给沙箱引擎),不能填内部服务地址 | - | - | https://infra.teable.example.com |
+| TEABLE_INFRA_API_KEY | 与运行平面共享的 API 密钥 | - | - | your-infra-api-key |
+| TEABLE_INFRA_BUCKET | AI 工作区数据面使用的存储桶 | teable-agent | - | teable-agent |
+| SANDBOX_OPENSANDBOX_IMAGE | 沙箱 agent 镜像**前缀(不带 tag)** —— Teable 会拼上自身发布版本 tag,agent 永远与应用版本配对。中国部署使用阿里云镜像前缀 | - | - | ghcr.io/teableio/teable-sandbox-agent |
+| SANDBOX_OPENSANDBOX_RUNTIME | 沙箱引擎运行时类型:`kubernetes` 或 `docker`。Docker 部署必须设为 `docker` | kubernetes | - | docker |
+| SANDBOX_OPENSANDBOX_USE_SERVER_PROXY | 沙箱端点走引擎的路径代理而非按端口子域名(Docker local 模式使用) | false | - | true |
+| APP_DEPLOY_PROVIDER | App Builder 的部署后端;全功能自部署使用 `docker-runtime` | vercel | - | docker-runtime |
+| SANDBOX_JWT_SECRET | 沙箱会话签名密钥 —— 请按主机生成随机值 | - | - | 随机字符串 |
+| SANDBOX_CPU | 每个沙箱的 vCPU 数(管理面板中的设置优先) | 2 | - | 2 |
+| SANDBOX_MEMORY | 每个沙箱的内存(GiB,管理面板中的设置优先) | 4 | - | 4 |
+| SANDBOX_DISK | 每个沙箱的临时磁盘(GiB,管理面板中的设置优先) | 15 | - | 15 |
| **功能开关** | | | | |
| RECORD_HISTORY_DISABLED | 是否禁用记录历史,默认为 false | false | - | true |
| BACKEND_RECORD_HISTORY_COLD_DISABLED | 是否停止记录历史冷存储的定时迁移、合并和数据库缓冲区删除;读取仍会包含已迁移的历史 | false | - | true |
@@ -115,10 +125,7 @@ mode: "wide"
| TELEMETRY_REPORT_DISABLED | 禁用自托管遥测上报,包括联网实例的许可合规上报 | false | - | true |
| **数据库配置** | | | | |
| PRISMA_DATABASE_URL | 数据库连接 URL,必须配置 | - | 是 | postgresql://teable:teable@127.0.0.1:5432/teable |
+| PUBLIC_DATABASE_PROXY | 对外可达的数据库地址(host:port),Base「数据库连接」面板生成的连接凭据会使用该地址;配置后即可从外部进行只读 SQL 访问 | - | - | db.example.com:42345 |
| PRISMA_TRANSACTION_TIMEOUT | 事务运行超时时间(毫秒),对于长时间运行的事务(如包含多个外键的批量更新)可以增加此值 | 5000 | - | 60000 |
| PRISMA_TRANSACTION_MAX_WAIT | 从连接池获取事务的最大等待时间(毫秒) | 2000 | - | 5000 |
| BIG_TRANSACTION_TIMEOUT | 大型内部事务的超时时间(毫秒),例如导出大型数据库 | 600000 | - | 1200000 |
-
-
-如果自托管部署导出大型数据库时出现 Prisma interactive transaction timeout,可以调大 `BIG_TRANSACTION_TIMEOUT` 并重启 Teable 服务。合适的值取决于部署规模、数据库性能、记录数量、表复杂度和附件数量。请使用能在当前环境稳定工作的最小值。
-
diff --git a/zh/deploy/gcp.mdx b/zh/deploy/gcp.mdx
deleted file mode 100644
index f0d82d91..00000000
--- a/zh/deploy/gcp.mdx
+++ /dev/null
@@ -1,280 +0,0 @@
----
-title: "在 GCP 上部署"
-description: "分步指引:在 Google Cloud Platform 上使用 Cloud Run/GKE、Cloud SQL、Memorystore 与 S3-compatible 存储部署 Teable"
----
-
-
-**推荐场景**:50+ 用户的生产环境
-
-
-## 架构概览
-
-```mermaid
-graph TB
- CloudRun["Cloud Run / GKE
Teable 应用
(自动扩展)"]
-
- CloudSQL["Cloud SQL
PostgreSQL"]
- Memorystore["Memorystore for Redis
(队列 & 缓存)"]
- S3["S3-compatible 存储
(AWS S3 或 MinIO)
Public + Private 双桶"]
-
- CloudRun --> CloudSQL
- CloudRun --> Memorystore
- CloudRun --> S3
-
- style CloudRun fill:#4285f4,stroke:#2b5fab,color:#fff
- style CloudSQL fill:#4285f4,stroke:#2b5fab,color:#fff
- style Memorystore fill:#ea4335,stroke:#b8321e,color:#fff
- style S3 fill:#ff9900,stroke:#cc7a00,color:#fff
-```
-
-
-**重要**:Teable 需要 **S3-compatible 存储**。你可以选择:
-- **AWS S3**(跨云方案)
-- **MinIO**(在 GCE/GKE 自建)
-- 其他 S3-compatible 服务
-
-Google Cloud Storage (GCS) **不直接支持**,因为它使用不同的 API。
-
-
-## 前置要求
-
-- 已安装并认证 `gcloud` CLI
-- GCP 项目已启用计费
-- 具备 **S3-compatible 存储**访问权(例如 AWS S3 账号或 MinIO 部署)
-
----
-
-## 步骤 1:创建 GCP 资源
-
-### 1.1 设置项目和区域
-
-```bash
-export PROJECT_ID=your-project-id
-export REGION=us-central1
-
-gcloud config set project $PROJECT_ID
-```
-
-### 1.2 创建 Cloud SQL (PostgreSQL)
-
-```bash
-gcloud sql instances create teable-db \
- --database-version=POSTGRES_16 \
- --tier=db-custom-2-7680 \
- --region=$REGION \
- --root-password=<你的强密码> \
- --storage-type=SSD \
- --storage-size=100GB
-```
-
-
-获取连接名称:
-```bash
-gcloud sql instances describe teable-db \
- --format='value(connectionName)'
-```
-结果:`your-project:region:teable-db`
-
-
-创建数据库:
-```bash
-gcloud sql databases create teable --instance=teable-db
-```
-
-### 1.3 创建 Memorystore (Redis)
-
-```bash
-gcloud redis instances create teable-cache \
- --size=1 \
- --region=$REGION \
- --redis-version=redis_7_0
-```
-
-
-获取 Redis 主机地址:
-```bash
-gcloud redis instances describe teable-cache \
- --region=$REGION \
- --format='value(host)'
-```
-
-
----
-
-## 步骤 2:设置 S3-compatible 存储
-
-由于 Google Cloud Storage 不兼容 S3,请选择以下方案之一:
-
-### 方案 A:使用 AWS S3(跨云)
-
-1. **在 AWS 上创建 S3 bucket**(参见 [AWS 部署指引](/zh/deploy/aws) 步骤 1.3-1.4)
-2. **配置 public bucket**(参见 [对象存储指引](/zh/deploy/storage))
-
-环境变量:
-```bash
-BACKEND_STORAGE_PROVIDER=s3
-BACKEND_STORAGE_S3_REGION=us-west-2
-BACKEND_STORAGE_S3_ENDPOINT=https://s3.us-west-2.amazonaws.com
-BACKEND_STORAGE_S3_ACCESS_KEY=
-BACKEND_STORAGE_S3_SECRET_KEY=
-BACKEND_STORAGE_PUBLIC_BUCKET=teable-public-<后缀>
-BACKEND_STORAGE_PRIVATE_BUCKET=teable-private-<后缀>
-STORAGE_PREFIX=https://teable-public-<后缀>.s3.us-west-2.amazonaws.com
-```
-
-### 方案 B:在 GCP 上部署 MinIO
-
-在 GCE 实例或 GKE 集群上部署 MinIO 提供 S3-compatible 存储。
-
-**推荐镜像**:`minio/minio:RELEASE.2025-04-22T22-12-26Z`
-
-**快速设置(GCE VM)**:
-
-```bash
-# 创建 VM
-gcloud compute instances create minio-server \
- --machine-type=e2-medium \
- --zone=us-central1-a \
- --image-family=ubuntu-2204-lts \
- --image-project=ubuntu-os-cloud \
- --boot-disk-size=100GB
-
-# SSH 登录并安装 MinIO
-gcloud compute ssh minio-server --zone=us-central1-a
-
-# 在 VM 上:
-wget https://dl.min.io/server/minio/release/linux-amd64/minio
-chmod +x minio
-sudo mv minio /usr/local/bin/
-
-export MINIO_ROOT_USER=admin
-export MINIO_ROOT_PASSWORD=<强密码>
-minio server /data --console-address ":9001"
-```
-
-创建 bucket 并配置访问(详见 Azure 指引方案 B)。
-
----
-
-## 步骤 3:准备环境变量
-
-创建 `.env` 文件:
-
-```bash
-# Core
-PUBLIC_ORIGIN=https://teable.yourcompany.com
-SECRET_KEY=<生成32位随机字符串>
-
-# Database (Cloud SQL)
-PRISMA_DATABASE_URL=postgresql://postgres:<密码>@/teable?host=/cloudsql/
-
-# Redis (Memorystore)
-BACKEND_CACHE_PROVIDER=redis
-BACKEND_CACHE_REDIS_URI=redis://:6379/0
-BACKEND_PERFORMANCE_CACHE=redis://:6379/0
-
-# Storage (S3-compatible)
-# 方案 A (AWS S3):
-BACKEND_STORAGE_PROVIDER=s3
-BACKEND_STORAGE_S3_REGION=us-west-2
-BACKEND_STORAGE_S3_ENDPOINT=https://s3.us-west-2.amazonaws.com
-BACKEND_STORAGE_S3_ACCESS_KEY=
-BACKEND_STORAGE_S3_SECRET_KEY=
-BACKEND_STORAGE_PUBLIC_BUCKET=teable-public-<后缀>
-BACKEND_STORAGE_PRIVATE_BUCKET=teable-private-<后缀>
-STORAGE_PREFIX=https://teable-public-<后缀>.s3.us-west-2.amazonaws.com
-```
-
----
-
-## 步骤 4:部署到 Cloud Run
-
-### 4.1 构建并推送容器(或使用预构建镜像)
-
-```bash
-# 方案 1:使用预构建镜像
-export IMAGE=ghcr.io/teableio/teable:latest
-
-# 方案 2:构建并推送到 GCR
-# gcloud builds submit --tag gcr.io/$PROJECT_ID/teable
-# export IMAGE=gcr.io/$PROJECT_ID/teable
-```
-
-### 4.2 部署到 Cloud Run
-
-```bash
-gcloud run deploy teable \
- --image=$IMAGE \
- --platform=managed \
- --region=$REGION \
- --allow-unauthenticated \
- --port=3000 \
- --set-env-vars="PUBLIC_ORIGIN=https://teable.yourcompany.com" \
- --set-env-vars="SECRET_KEY=<你的secret>" \
- --set-env-vars="PRISMA_DATABASE_URL=postgresql://..." \
- --set-env-vars="BACKEND_CACHE_PROVIDER=redis" \
- --set-env-vars="BACKEND_CACHE_REDIS_URI=redis://..." \
- --set-env-vars="BACKEND_STORAGE_PROVIDER=s3" \
- --set-env-vars="BACKEND_STORAGE_S3_REGION=us-west-2" \
- --set-env-vars="BACKEND_STORAGE_S3_ENDPOINT=https://s3.us-west-2.amazonaws.com" \
- --set-env-vars="BACKEND_STORAGE_S3_ACCESS_KEY=***" \
- --set-env-vars="BACKEND_STORAGE_S3_SECRET_KEY=***" \
- --set-env-vars="BACKEND_STORAGE_PUBLIC_BUCKET=teable-public-xxx" \
- --set-env-vars="BACKEND_STORAGE_PRIVATE_BUCKET=teable-private-xxx" \
- --set-env-vars="STORAGE_PREFIX=https://teable-public-xxx.s3.us-west-2.amazonaws.com" \
- --add-cloudsql-instances= \
- --vpc-connector=
-```
-
-
-访问 Cloud SQL 使用 `--add-cloudsql-instances`。
-访问 Memorystore 需先创建 VPC connector。
-
-
----
-
-## 步骤 5:验证部署
-
-1. **获取服务 URL**:
-
-```bash
-gcloud run services describe teable \
- --region=$REGION \
- --format='value(status.url)'
-```
-
-2. **测试健康检查**:
-
-```bash
-curl https:///health
-```
-
-预期:`{"status":"ok"}`
-
-3. **查看日志**:
-
-```bash
-gcloud run services logs read teable --region=$REGION
-```
-
----
-
-## 生产环境最佳实践
-
-
-详细的生产环境建议(包括配置、高可用、扩展策略)请参考 [私有化部署概览](/zh/deploy/production-overview)。
-
-
-**GCP 特定建议**:
-- 启用 Cloud Run 最小实例数(2+)实现高可用
-- 使用 Secret Manager 存储敏感值
-- 启用 Cloud Monitoring 并设置告警
-- 将自定义域名映射到 Cloud Run 服务
-
----
-
-## 相关文档
-
-- [私有化部署概览](/zh/deploy/production-overview) — 架构、配置与扩展
-- [环境变量参考](/zh/deploy/env)
-- [对象存储(S3-compatible)](/zh/deploy/storage)
diff --git a/zh/deploy/k8s.mdx b/zh/deploy/k8s.mdx
deleted file mode 100644
index 92c6099b..00000000
--- a/zh/deploy/k8s.mdx
+++ /dev/null
@@ -1,429 +0,0 @@
----
-title: "K8s 部署"
----
-
-
-**推荐场景**:50+ 用户的生产环境
-
-
-
-配置建议(CPU、内存、副本数)请参考 [私有化部署概览 → 配置建议](/zh/deploy/production-overview#配置建议)。
-
-
-## 前置条件
-### Teable 镜像
-- 应用镜像: `registry.cn-shenzhen.aliyuncs.com/teable/teable:latest`
-
-### 运行环境
-- 运行中的 Kubernetes 集群
-
-### 已配置的外部服务
-#### 数据库服务
-- PostgreSQL 数据库: postgres:15.4(版本号大于 12)
- - PostgreSQL 镜像: `registry.cn-shenzhen.aliyuncs.com/teable/postgres:15.4`
-
-#### 缓存服务
-- Redis 缓存服务: redis:7.2.4(版本号大于 5)
- - Redis 镜像: `registry.cn-shenzhen.aliyuncs.com/teable/redis:7.2.4`
-
-#### 对象存储服务
-- MinIO 对象存储服务: minio:RELEASE.2024-10-13T13-34-11Z-cpuv1
- - MinIO 镜像: `registry.cn-shenzhen.aliyuncs.com/teable/minio:RELEASE.2024-10-13T13-34-11Z-cpuv1`
- - 注意: 可以直接使用最新版本,或者使用云存储,配置参考,下方示例使用 minio 来做例子。
-
-### 必要工具
-- kubectl 命令行工具
-
-## 依赖组件配置
-### 文件存储 MinIO
-文件存储服务需要支持外网访问(即终端用户可直接访问到)
-
-文件存储需要预先创建好两个 bucket:
-
-| Bucket | 环境变量 | 权限 |
-|--------|---------|------|
-| 公共桶 | `BACKEND_STORAGE_PUBLIC_BUCKET=teable-pub` | **公共可读(必须开启匿名访问)** |
-| 私有桶 | `BACKEND_STORAGE_PRIVATE_BUCKET=teable-pvt` | 私有(默认) |
-
-
-公共桶**必须**开启匿名读取权限。否则用户将无法查看共享图片、头像等公开文件。
-
-
-#### 使用 MinIO Client (mc) 创建 Bucket
-
-在部署 Teable 之前,请先创建所需的 bucket:
-
-```sh
-# 设置 MinIO 客户端别名
-mc alias set teable-minio https://minio.example.com YOUR_ACCESS_KEY YOUR_SECRET_KEY
-
-# 创建公共桶并设置匿名读取权限
-mc mb --ignore-existing teable-minio/teable-pub
-mc anonymous set public teable-minio/teable-pub
-
-# 创建私有桶
-mc mb --ignore-existing teable-minio/teable-pvt
-
-# 验证 bucket 是否创建成功
-mc ls teable-minio
-# 预期输出:
-# [2024-01-01 00:00:00 UTC] 0B teable-pub/
-# [2024-01-01 00:00:00 UTC] 0B teable-pvt/
-```
-
-#### Teable MinIO 环境变量总览
-
-```sh
-# 固定值
-BACKEND_STORAGE_PROVIDER=minio
-# 公共桶
-BACKEND_STORAGE_PUBLIC_BUCKET=teable-pub
-# 私有桶
-BACKEND_STORAGE_PRIVATE_BUCKET=teable-pvt
-# 外网端点,重要!需要终端用户可以直接访问到
-BACKEND_STORAGE_MINIO_ENDPOINT=minio.example.com
-# 与前面的值保持一样,但是要加个协议名称
-STORAGE_PREFIX=https://minio.example.com
-# 内网端点(Kubernetes DNS 格式:..svc.cluster.local)
-# ⚠️ 请将 替换为实际的命名空间,例如:minio.teable.svc.cluster.local
-BACKEND_STORAGE_MINIO_INTERNAL_ENDPOINT=minio.teable.svc.cluster.local
-# 外网端口,一般为 443 或者 9000
-BACKEND_STORAGE_MINIO_PORT=443
-# 内网端口,一般为 80 或者 9000
-BACKEND_STORAGE_MINIO_INTERNAL_PORT=80
-# 是否启用 HTTPS, 注意如果 Teable 启用了 https 则 minio 也必须启用 https 否则有跨域问题
-BACKEND_STORAGE_MINIO_USE_SSL="true"
-# 管理员账号
-BACKEND_STORAGE_MINIO_ACCESS_KEY=root
-# 管理员密码
-BACKEND_STORAGE_MINIO_SECRET_KEY=rootPassword
-```
-
-### 数据库
-需要创建一个具有管理员权限的数据库账户,以及一个数据库,并且设置密码。
-对应环境变量示例:
- - 数据库名称: teable
- - 密码:your-password
- - 账号: postgres
- - 端口: 5432
-```sh
-PRISMA_DATABASE_URL="postgresql://postgres:your-password@your-postgres-host:5432/teable"
-```
-
-### 缓存 Redis
-Teable 配置 redis 缓存只需要提供内网连接地址即可。(注意 Redis 不仅管理缓存还管理队列,不可或缺。数据需要定时备份)
-对应环境变量示例
-```sh
-BACKEND_CACHE_REDIS_URI="redis://username:password@your-redis-host:6379/0"
-```
-
-## 创建配置文件
-
-```yaml teable-config.yaml(非敏感配置)
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: teable-config
- namespace: teable # 请替换为你的命名空间
-data:
- # 应用基础配置,对外访问的域名
- PUBLIC_ORIGIN: "https://your-domain.com"
-
- # 存储配置
- BACKEND_STORAGE_PROVIDER: "minio"
- # Bucket 名称(需要在部署前于 MinIO 中创建)
- BACKEND_STORAGE_PUBLIC_BUCKET: "teable-pub"
- BACKEND_STORAGE_PRIVATE_BUCKET: "teable-pvt"
- # 外网端点,重要!需要终端用户可以直接访问到
- BACKEND_STORAGE_MINIO_ENDPOINT: "minio.example.com"
- # 与前面的值保持一样,但是要加个协议名称
- STORAGE_PREFIX: "https://minio.example.com"
- # 内网端点(Kubernetes DNS 格式:..svc.cluster.local)
- # ⚠️ 请将 'teable' 替换为实际的命名空间
- BACKEND_STORAGE_MINIO_INTERNAL_ENDPOINT: "minio.teable.svc.cluster.local"
- # 外网端口,一般为 443 或者 9000
- BACKEND_STORAGE_MINIO_PORT: "443"
- # 内网端口,一般为 80 或者 9000
- BACKEND_STORAGE_MINIO_INTERNAL_PORT: "80"
- # 是否启用 HTTPS, 注意如果 Teable 启用了 https 则 minio 也必须启用 https 否则有跨域问题
- BACKEND_STORAGE_MINIO_USE_SSL: "true"
-
- # 缓存配置, 固定值
- BACKEND_CACHE_PROVIDER: "redis"
-
- # 其他配置,固定值
- NEXT_ENV_IMAGES_ALL_REMOTE: "true"
- PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING: "1"
- # 使用自签发证书需要保留这个
- NODE_TLS_REJECT_UNAUTHORIZED: '0'
-```
-
-```yaml teable-secrets.yaml(敏感信息)
-apiVersion: v1
-kind: Secret
-metadata:
- name: teable-secrets
- namespace: teable # 请替换为你的命名空间
-type: Opaque
-stringData:
- # 数据库敏感信息
- PRISMA_DATABASE_URL: "postgresql://postgres:your-password@your-postgres-host:5432/teable"
-
- # 应用密钥
- BACKEND_JWT_SECRET: "your-jwt-secret"
- BACKEND_SESSION_SECRET: "your-session-secret"
-
- # MinIO 认证信息
- BACKEND_STORAGE_MINIO_ACCESS_KEY: "your-minio-access-key"
- BACKEND_STORAGE_MINIO_SECRET_KEY: "your-minio-secret-key"
-
- # Redis 认证信息
- BACKEND_CACHE_REDIS_URI: "redis://username:password@your-redis-host:6379/0"
-```
-
-
-```yaml teable-deployment.yaml
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: teable
- namespace: teable # 请替换为你的命名空间
-spec:
- replicas: 1 # 根据需要配置
- selector:
- matchLabels:
- app: teable
- template:
- metadata:
- labels:
- app: teable
- spec:
- # Add initContainers for database migration
- initContainers:
- - name: db-migrate
- image: registry.cn-shenzhen.aliyuncs.com/teable/teable:latest
- args:
- - migrate-only
- envFrom:
- - configMapRef:
- name: teable-config
- - secretRef:
- name: teable-secrets
- resources:
- requests:
- cpu: 100m
- memory: 102Mi
- limits:
- cpu: 1000m
- memory: 1024Mi
- containers:
- - name: teable
- image: registry.cn-shenzhen.aliyuncs.com/teable/teable:latest
- args:
- - skip-migrate
- ports:
- - containerPort: 3000
- envFrom:
- - configMapRef:
- name: teable-config
- - secretRef:
- name: teable-secrets
- resources:
- requests:
- cpu: 200m
- memory: 400Mi
- limits:
- cpu: 2000m
- memory: 4096Mi
- startupProbe:
- httpGet:
- path: /health
- port: 3000
- initialDelaySeconds: 10
- periodSeconds: 10
- timeoutSeconds: 5
- failureThreshold: 30
- successThreshold: 1
- livenessProbe:
- httpGet:
- path: /health
- port: 3000
- initialDelaySeconds: 30
- periodSeconds: 30
- timeoutSeconds: 5
- failureThreshold: 3
- successThreshold: 1
- readinessProbe:
- httpGet:
- path: /health
- port: 3000
- initialDelaySeconds: 15
- periodSeconds: 10
- timeoutSeconds: 5
- failureThreshold: 3
- successThreshold: 1
-```
-
-```yaml teable-service.yaml
-apiVersion: v1
-kind: Service
-metadata:
- name: teable
- namespace: teable # 请替换为你的命名空间
-spec:
- ports:
- - port: 3000
- targetPort: 3000
- selector:
- app: teable
-```
-
-```yaml teable-ingress.yaml (可选)
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: teable
- namespace: teable # 请替换为你的命名空间
- # 以 nginx 做示例,如果使用其他的 ingress class 请替换
- annotations:
- nginx.ingress.kubernetes.io/proxy-body-size: "100m"
- nginx.ingress.kubernetes.io/proxy-buffer-size: "128k"
- nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
- nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
- nginx.ingress.kubernetes.io/proxy-request-buffering: "off"
-spec:
- ingressClassName: nginx # 如果使用其他 ingress class 请修改
- rules:
- - host: your-domain.com # 请替换为你的域名
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: teable
- port:
- number: 3000
- tls:
- - hosts:
- - your-domain.com # 请替换为你的域名
- secretName: your-tls-secret
-```
-
-
-**请勿**添加 `nginx.ingress.kubernetes.io/rewrite-target` 注解,这会破坏 Teable 的内部路由。
-
-
-
-## 部署步骤
-
-
-在部署 Teable 之前,请确保:
-1. MinIO bucket(`teable-pub` 和 `teable-pvt`)已创建
-2. 公共桶已开启匿名读取权限
-3. PostgreSQL 数据库 `teable` 已存在
-4. Redis 服务可访问
-
-
-1. 创建命名空间(如果不存在):
-```sh
-kubectl create namespace teable
-```
-
-2. 创建配置和密钥:
-```sh
-kubectl apply -f teable-config.yaml
-kubectl apply -f teable-secrets.yaml
-```
-
-3. 部署应用:
-```sh
-kubectl apply -f teable-deployment.yaml
-kubectl apply -f teable-service.yaml
-kubectl apply -f teable-ingress.yaml # 可选,如果使用 Ingress
-```
-
-4. 验证部署:
-```sh
-# 检查 Pod 状态
-kubectl get pods -n teable -l app=teable
-
-# 等待 Pod 就绪
-kubectl rollout status deployment/teable -n teable
-
-# 查看应用日志
-kubectl logs -n teable -l app=teable
-```
-
-### 配置注意事项
-
-1. 敏感信息管理
- - 所有密码、密钥类信息应通过 Secrets 管理
-
-2. 数据库配置
- - 确保数据库已创建 teable 数据库
- - 数据库用户需要具备适当权限
- - 建议使用连接池管理数据库连接
-
-3. MinIO 配置
- - 确保存储桶已创建且权限正确, 一个公共桶,一个私有桶
- - 公共桶需要完全公开读
- - 内外部访问地址配置正确
-
-4. Redis 配置
- - 建议启用 Redis 持久化
- - 配置适当的内存限制
- - 考虑使用 Redis 集群提高可用性
-
-5. 安全建议
- - 使用强密码和密钥
- - 启用 TLS/SSL 加密
- - 定期更新证书
- - 限制网络访问范围
-
-6. 资源配置
- - 根据实际负载调整资源限制
- - 监控资源使用情况
- - 配置适当的健康检查参数
-
-### 故障排查
-
-#### 常见问题
-
-| 错误信息 | 原因 | 解决方案 |
-|---------|------|---------|
-| `ECONNREFUSED` 连接 MinIO 失败 | MinIO 内网端点配置错误或不可达 | 检查 `BACKEND_STORAGE_MINIO_INTERNAL_ENDPOINT` 格式是否正确:`..svc.cluster.local` |
-| `Bucket not found` | MinIO bucket 未创建 | 在部署前使用 `mc mb` 命令创建 bucket |
-| `Access Denied` 文件上传失败 | MinIO 凭证错误 | 检查 `BACKEND_STORAGE_MINIO_ACCESS_KEY` 和 `SECRET_KEY` |
-| 访问页面显示 `Page not found` | Ingress 配置了 `rewrite-target` | 移除 Ingress 中的 `rewrite-target` 注解 |
-| Pod 处于 `CrashLoopBackOff` 状态 | 后端启动失败 | 检查日志,确认 MinIO、数据库、Redis 连接是否正常 |
-
-#### 诊断命令
-
-1. 检查 Pod 状态:
-```sh
-kubectl describe pod -n teable -l app=teable
-```
-
-2. 查看应用日志:
-```sh
-kubectl logs -n teable -l app=teable
-kubectl logs -n teable -l app=teable --previous # 如果 Pod 崩溃
-```
-
-3. 验证配置:
-```sh
-kubectl describe configmap teable-config -n teable
-kubectl describe secret teable-secrets -n teable
-```
-
-4. 检查网络连接:
-```sh
-kubectl exec -it -n teable -- curl -v localhost:3000/health
-```
-
-5. 测试 MinIO 集群内部连接:
-```sh
-kubectl run test-minio --rm -it --image=curlimages/curl --restart=Never -n teable -- \
- curl -v http://minio.teable.svc.cluster.local/minio/health/live
-```
diff --git a/zh/deploy/one-key.mdx b/zh/deploy/one-key.mdx
deleted file mode 100644
index 42413fb5..00000000
--- a/zh/deploy/one-key.mdx
+++ /dev/null
@@ -1,36 +0,0 @@
----
-title: "一键云部署"
-description: "通过云服务商集成的配置模板,你可以一键部署完整的,可伸缩的 Teable 服务"
----
-| 优点 | 缺点 |
-| ----------- | ------ |
-| 无需任何配置,一键启动 | 依赖云服务商 |
-| 可以弹性伸缩 | |
-| 运维简单 | |
-
-**系统要求**:
-
-* 应用节点最低 1c/2g
-* 数据库最低 1c/2g
-
-#### Sealos
-
-有免费额度,对国内支持友好,按量计费
-
-[**一键部署**](https://cloud.sealos.io/?openapp=system-template%3FtemplateName%3Dteable)
-
-### 订阅与激活(付费功能)
-
-如果你是**自托管部署**并需要付费功能,请在部署完成后进行订阅并激活许可证:
-
-1. 在你部署好的 Teable 实例中进入管理员后台,复制 **Instance ID(实例 ID)**
-2. 打开自托管订阅页面完成订阅:`https://app.teable.ai/public/pricing?host=self-hosted`
-3. 订阅成功后会获得 **License Key(许可证密钥)**,回到实例中完成激活
-
-详情请见:[订阅和激活许可证](/zh/deploy/activate)
-
-### 下一步
-
-[配置邮件服务](/zh/deploy/email)
-
-[配置外部数据库连接](/zh/deploy/database-connection)
diff --git a/zh/deploy/production-overview.mdx b/zh/deploy/production-overview.mdx
deleted file mode 100644
index 76341bf2..00000000
--- a/zh/deploy/production-overview.mdx
+++ /dev/null
@@ -1,172 +0,0 @@
----
-title: "概览"
-description: "Teable 生产环境部署的架构、配置建议和部署路径选择"
----
-
-
-**推荐场景**:50+ 用户的生产环境
-
-
-## 架构概览
-
-Teable 采用**无状态应用层**配合**外部状态服务**的设计,支持水平扩展和高可用。
-
-```mermaid
-graph TB
- subgraph "应用层 (无状态)"
- App1["Teable Pod 1"]
- App2["Teable Pod 2"]
- AppN["Teable Pod N..."]
- end
-
- subgraph "数据层 (有状态)"
- DB["PostgreSQL
(主 + 从)"]
- Redis1["Redis
队列与缓存"]
- Redis2["Redis
性能缓存"]
- S3["S3 / MinIO
对象存储"]
- end
-
- App1 --> DB
- App2 --> DB
- AppN --> DB
- App1 --> Redis1
- App1 --> Redis2
- App1 --> S3
-
- style App1 fill:#0D9373,stroke:#0a7a5e,color:#fff
- style App2 fill:#0D9373,stroke:#0a7a5e,color:#fff
- style AppN fill:#0D9373,stroke:#0a7a5e,color:#fff
- style DB fill:#336791,stroke:#264d73,color:#fff
- style Redis1 fill:#dc382d,stroke:#a82a22,color:#fff
- style Redis2 fill:#dc382d,stroke:#a82a22,color:#fff
- style S3 fill:#ff9900,stroke:#cc7a00,color:#fff
-```
-
-### 组件说明
-
-| 组件 | 用途 | 托管服务示例 |
-|------|------|-------------|
-| **Teable 应用** | 无状态 Web 应用 | K8s, AWS ECS, Azure App Service, GCP Cloud Run |
-| **PostgreSQL** | 主数据存储 | AWS RDS, Azure PostgreSQL, Google Cloud SQL |
-| **Redis (队列)** | 后台任务与缓存 | ElastiCache, Azure Cache, Memorystore |
-| **Redis (性能)** | 读取性能缓存 | 可使用同一个或独立实例 |
-| **对象存储** | 文件与附件 | AWS S3, MinIO, 任何 S3 兼容存储 |
-
-
-**核心要点**:Teable 应用不持有任何持久化状态,可以通过增加 Pod 实现水平扩展,任何 Pod 都能处理任何请求。
-
-
----
-
-## 配置建议
-
-
-以下是 Teable 工程团队的**生产环境**配置建议。如需评估测试,请参考 [Docker 快速部署](/zh/deploy/docker)。
-
-
-### 应用层 (Teable Pods)
-
-| 配置项 | 建议值 |
-|--------|--------|
-| 每 Pod CPU | 2 vCPU |
-| 每 Pod 内存 | 4 GB |
-| 最小副本数 | 2 |
-| 自动扩容触发 | CPU 使用率 50% |
-
-
-使用 Kubernetes 的 Horizontal Pod Autoscaler (HPA),或 AWS ECS / Azure App Service / GCP Cloud Run 的等效自动扩缩容功能。
-
-
-### 数据库 (PostgreSQL)
-
-| 配置项 | 建议值 |
-|--------|--------|
-| CPU | 4 vCPU |
-| 内存 | 16 GB |
-| 拓扑 | 1 主 + 1 从 |
-| 备份 | 每日自动备份 |
-| 版本 | 15+ 推荐 |
-
-
-务必配置从库以实现高可用。使用托管数据库服务可获得自动故障转移能力。
-
-
-### 缓存 (Redis)
-
-Teable 使用**两个独立的 Redis 实例**:
-
-| 用途 | 环境变量 | CPU | 内存 |
-|------|----------|-----|------|
-| 队列与缓存 | `BACKEND_CACHE_REDIS_URI` | 1 vCPU | 2 GB |
-| 性能缓存 | `BACKEND_PERFORMANCE_CACHE` | 2 vCPU | 4 GB |
-
-
-性能缓存 (`BACKEND_PERFORMANCE_CACHE`) 可选但**强烈建议**配置,对多人协作场景能显著提升读取性能。
-
-
-### 对象存储
-
-- **类型**:S3 兼容存储(AWS S3, MinIO 等)
-- **存储桶**:需要 2 个(公开 + 私有)
-- **容量**:使用托管 S3 服务可自动扩展
-
-详见 [对象存储配置指南](/zh/deploy/storage)。
-
----
-
-## 扩容策略
-
-| 组件 | 扩容方式 | 扩容时机 |
-|------|----------|----------|
-| Teable 应用 | **自动**(水平扩展) | CPU > 50%(增加 Pod) |
-| PostgreSQL | **手动**(垂直扩展) | CPU > 70% 持续 |
-| Redis | **手动**(垂直扩展) | 内存 > 80% 或 CPU > 60% |
-
-
-**应用层**:无状态设计支持自动水平扩展。Kubernetes HPA 或云服务自动扩缩容会根据 CPU 指标自动处理。
-
-**数据库和 Redis**:这些是有状态服务,垂直扩展(更大的实例)比水平扩展更简单安全。监控指标,在超过阈值时进行扩容。
-
-
----
-
-## 最小配置 vs 生产配置
-
-| | 最小配置 (PoC) | 生产配置 |
-|---|----------------|----------|
-| Teable 应用 | 1 实例, 2c4g | 2+ Pod, 每个 2c4g, 自动扩缩容 |
-| PostgreSQL | 2c4g, 单实例 | 4c16g, 1 主 + 1 从 |
-| Redis | 1 实例, 1c2g | 2 实例(队列 + 性能) |
-| 存储 | S3 兼容对象存储 | S3 兼容对象存储 |
-| 可用性 | 无(单点故障) | 高可用冗余 |
-
-
-"最小配置"仅供**评估测试**使用,没有冗余——服务器故障可能导致数据丢失。
-
-
----
-
-## 下一步:选择部署平台
-
-
-
- 在任意 K8s 集群上部署,完全掌控基础设施。
-
-
- ECS + RDS + ElastiCache + S3,推荐 50+ 用户使用。
-
-
- App Service + PostgreSQL + Redis + S3 兼容存储。
-
-
- Cloud Run + Cloud SQL + Memorystore + Cloud Storage。
-
-
-
----
-
-## 相关文档
-
-- [环境变量参考](/zh/deploy/env) — 所有配置选项
-- [对象存储配置](/zh/deploy/storage) — S3 存储桶配置
-- [许可证激活](/zh/deploy/activate) — 激活私有化部署许可证
diff --git a/zh/deploy/storage.mdx b/zh/deploy/storage.mdx
deleted file mode 100644
index 69999d37..00000000
--- a/zh/deploy/storage.mdx
+++ /dev/null
@@ -1,122 +0,0 @@
----
-title: "对象存储(S3-compatible)"
-description: "Teable 生产环境存储指引:public/private 双桶、权限与跨域(CORS)"
----
-
-
-生产环境请使用 **S3-compatible 对象存储**(如 S3、MinIO、兼容 S3 的 OSS/OBS/COS 等),并按 **public/private 双桶**进行配置。
-
-
-## 为什么要两个 Bucket?
-
-Teable 会将不同类型的文件放在不同 bucket:
-
-- **Public bucket**:头像、表单头图等需要公开访问的资源。
-- **Private bucket**:附件、应用文件、记录历史冷存储分片等需要权限保护的资源。
-
-## 必需环境变量
-
-最少需要配置:
-
-- **Provider**
- - `BACKEND_STORAGE_PROVIDER`:`s3` 或 `minio`
-- **Buckets**
- - `BACKEND_STORAGE_PUBLIC_BUCKET`
- - `BACKEND_STORAGE_PRIVATE_BUCKET`
-- **公共访问前缀**
- - `STORAGE_PREFIX`:建议设置为 **public bucket 的访问基址**(或其前面的 CDN 域名)
-
-### S3 Provider 示例
-
-```bash
-BACKEND_STORAGE_PROVIDER=s3
-BACKEND_STORAGE_S3_REGION=us-west-2
-BACKEND_STORAGE_S3_ENDPOINT=https://s3.us-west-2.amazonaws.com
-BACKEND_STORAGE_S3_ACCESS_KEY=***REDACTED***
-BACKEND_STORAGE_S3_SECRET_KEY=***REDACTED***
-
-BACKEND_STORAGE_PUBLIC_BUCKET=your-public-bucket
-BACKEND_STORAGE_PRIVATE_BUCKET=your-private-bucket
-
-# public bucket 的访问基址(或 CDN)
-STORAGE_PREFIX=https://your-public-bucket.s3.us-west-2.amazonaws.com
-```
-
-### MinIO Provider 示例
-
-```bash
-BACKEND_STORAGE_PROVIDER=minio
-BACKEND_STORAGE_MINIO_ENDPOINT=minio.example.com
-BACKEND_STORAGE_MINIO_PORT=443
-BACKEND_STORAGE_MINIO_USE_SSL=true
-BACKEND_STORAGE_MINIO_ACCESS_KEY=***REDACTED***
-BACKEND_STORAGE_MINIO_SECRET_KEY=***REDACTED***
-
-BACKEND_STORAGE_PUBLIC_BUCKET=public
-BACKEND_STORAGE_PRIVATE_BUCKET=private
-STORAGE_PREFIX=https://minio.example.com
-```
-
-## Public bucket 必做项
-
-### 1)Public Read(公共读)
-
-**public bucket 必须允许公开读**对象。
-
-以 AWS S3 为例,可配置 Bucket Policy:
-
-```json
-{
- "Version": "2012-10-17",
- "Statement": [
- {
- "Sid": "PublicReadGetObject",
- "Effect": "Allow",
- "Principal": "*",
- "Action": "s3:GetObject",
- "Resource": "arn:aws:s3:::your-public-bucket/*"
- }
- ]
-}
-```
-
-
-AWS S3 可能需要调整 public bucket 的 **Block Public Access** 相关选项。请遵循你们公司的安全规范。
-
-
-### 2)CORS(允许任意跨域)
-
-为保证浏览器端访问与上传,public bucket 需要配置 CORS,允许跨域请求。
-
-AWS S3 示例:
-
-```json
-[
- {
- "AllowedHeaders": ["*"],
- "AllowedMethods": ["GET", "HEAD"],
- "AllowedOrigins": ["*"],
- "ExposeHeaders": ["ETag", "x-amz-request-id", "x-amz-id-2"],
- "MaxAgeSeconds": 3000
- }
-]
-```
-
-如果你们启用 **浏览器直传(presigned PUT)**,则可能还需要把 `PUT` 加到 `AllowedMethods`。
-
-## Private bucket 提示
-
-- **private bucket** 必须保持私有(禁止 public read)。
-- Teable 会根据功能,通过 **签名 URL** 或后端读取来访问 private 对象。
-- 记录历史冷存储会把压缩后的历史分片写入 private bucket,请让 bucket 备份和保留策略与记录历史要求保持一致。
-- 如需为 private bucket 使用独立域名/endpoint,可配置:
- - `BACKEND_STORAGE_PRIVATE_BUCKET_ENDPOINT`(可选)
-
-## Azure / GCP 说明
-
-Teable 对象存储使用 **S3 API**。Azure Blob Storage 与 Google Cloud Storage **并非 S3-native**。
-
-- 在 **Azure / GCP** 上部署时,只要 Teable 运行环境能访问到某个 S3 endpoint(例如 AWS S3),同样可以直接使用 `BACKEND_STORAGE_PROVIDER=s3`。
-- 或选用 **S3-compatible** 的对象存储:
- - 自建 MinIO(作为 S3 endpoint)
- - 或其他你们选择的托管 S3-compatible 服务
diff --git a/zh/deploy/upgrade.mdx b/zh/deploy/upgrade.mdx
index 7fcac066..e1b56c1f 100644
--- a/zh/deploy/upgrade.mdx
+++ b/zh/deploy/upgrade.mdx
@@ -4,162 +4,111 @@ title: "版本更新"
本文档介绍如何更新您的 Teable 私有化部署版本。
-## 更新频率
+## 发布通道与版本号
-Teable 的更新发布频率较高且不固定,一周内可能会发布多个更新版本。Teable 私有化版本的更新完全由您自主决定,您可以选择每周或每月进行一次升级。只要有新版本发布,您都可以灵活决定是否更新。您可以在 [GitHub Packages](https://github.com/teableio/teable-enterprise/pkgs/container/teable-ee) 查看所有可用版本。
+Teable 应用以**日期型 release tag** 发布,形如
+`release.<时间戳>.<构建号>`(例如 `release.2026-07-14T12-24-39Z.2228`),
+另有两个浮动通道:
-
-在进行任何更新操作之前,强烈建议先备份您的数据。
-
-
-## Docker Compose 更新
-
-如果您使用 Docker Compose 部署 Teable,请按以下步骤更新:
-
-### 备份数据(推荐)
-
-我们建议直接备份整个云主机,或者备份使用到的 PostgreSQL / Redis / 存储卷。
+| Tag | 含义 |
+|---|---|
+| `latest` | **稳定**通道 —— 始终指向最新的稳定版本 |
+| `beta` | 滚动通道 —— 最新构建,先于稳定版 |
+| `release.<时间戳>.<构建号>` | 不可变的具体版本 |
-### 进入部署目录
-
-```bash
-cd teable # 进入您的 teable 部署目录
-```
-
-### 拉取最新镜像
-
-```bash
-docker-compose pull
-```
-
-### 重启服务
-
-```bash
-docker-compose up -d
-```
-
-系统会自动使用最新的镜像重新创建容器。您的数据保存在 Docker 卷中,不会丢失。
-
-### 验证更新
-
-```bash
-# 查看容器状态
-docker-compose ps
-
-# 查看日志确认启动正常
-docker-compose logs -f teable
-```
+发布频率较高(常常一周多个版本),何时升级由您自主决定。
+全部版本可在 [GitHub Packages](https://github.com/teableio/teable/pkgs/container/teable) 查看。
-访问您的 Teable 实例,确认服务正常运行。
-
-## 更新到指定版本
-
-如果您希望更新到特定版本而不是最新版本,可以修改 `docker-compose.yaml` 中的镜像标签:
-
-```yaml
-services:
- teable:
- image: registry.cn-shenzhen.aliyuncs.com/teable/teable:0.5.0-alpha-1.x.x-build.xxx # 指定版本号
-```
-
-然后执行:
-
-```bash
-docker-compose pull
-docker-compose up -d
-```
-
-
-您可以在 [GitHub Releases](https://github.com/teableio/teable-enterprise/pkgs/container/teable-ee) 页面查看所有可用版本。
-
+
+在进行任何更新操作之前,强烈建议先备份您的数据。
+
-## Kubernetes 更新
+## 日常更新:跟着更新日志走
-如果您使用 Kubernetes 部署 Teable,请按以下步骤更新:
+新功能与修复都发布在[更新日志](/zh/changelog)里,而 Teable 的每个 release tag
+自带构建日期 —— 所以「我有没有这个功能」就是一次日期比较。想用上日志里提到的
+某项更新,把 Teable 镜像升到该条目日期之后(含当日)的任一版本即可:
-### 手动更新镜像
+- **Docker 部署**直接跟 `latest` 通道就行:
-如果您使用自定义的 Kubernetes 配置,可以直接更新 Deployment 中的镜像版本:
+ ```bash
+ cd teable # 您的部署目录
+ docker compose pull
+ docker compose up -d
+ ```
-```bash
-kubectl set image deployment/teable teable=registry.cn-shenzhen.aliyuncs.com/teable/teable:0.5.0-alpha-1.x.x-build.xxx -n teable
-```
+ 容器基于新镜像重建;数据存储在 Docker 卷(或外部数据库)中,不受影响。
-### 验证更新
+- **Kubernetes 部署**不要跑浮动 tag:保持 Teable 镜像钉版,**每次更新时主动
+ 上调钉定的版本号**。部署仓库自带的 `pin-image.sh` 可解析 `latest` 当前
+ 对应的具体版本。
-```bash
-# 查看 Pod 状态
-kubectl get pods -n teable
+## 最佳方式:整个平台一起升
-# 查看滚动更新状态
-kubectl rollout status deployment/teable -n teable
+全功能部署有两条版本线 —— Teable 应用与平台本身(见[架构](/zh/deploy/architecture))。
+最可靠的节奏是把两条线绑在一起,以
+[`VERSIONS.md`](https://github.com/teableio/teable-deployment/blob/main/VERSIONS.md)
+为升级清单,每轮:
-# 查看日志
-kubectl logs -f deployment/teable -n teable
-```
+1. 把运行平面升到**最新平台版本**(`v<年>.<月>.<序号>`):每个 git tag 都是
+ 全部运行面组件的已验证快照,对应的
+ [`CHANGELOG.md`](https://github.com/teableio/teable-deployment/blob/main/CHANGELOG.md)
+ 条目写明变了什么、你需要做什么(多数版本可热切换)。操作时从 checkout 到
+ 该 tag 的仓库副本进行;
+2. 把 Teable 应用钉到 **`latest` 当前对应的具体版本号**(`pin-image.sh`
+ 可解析)—— 用钉定的已验证组合替代浮动通道;
+3. 跑自带的 **doctor** —— 检查健康状态,并把实际运行的组合与平台版本清单
+ 比对(兼容 / 需升级 Teable 应用 / 未知组合)。
## 数据库迁移
-Teable 在启动时会自动执行数据库迁移,无需手动干预。如果您在更新后遇到问题,可以查看日志确认迁移是否成功:
+Teable 启动时自动执行数据库迁移,无需人工干预。如升级后出现异常,先查日志:
```bash
-# Docker Compose
-docker-compose logs teable | grep -i migration
-
-# Kubernetes
-kubectl logs deployment/teable -n teable | grep -i migration
+docker compose logs teable | grep -i migration
```
-## 回滚版本
-
-如果更新后遇到问题,您可以回滚到之前的版本。
+## 回滚
-### Docker Compose 回滚
+如果升级后遇到问题:
-1. 修改 `docker-compose.yaml` 中的镜像标签为之前的版本
-2. 执行 `docker-compose up -d`
+1. 将 `docker-compose.yaml` 中的镜像 tag 改回上一个版本号
+ (这正是钉版优于 `latest` 的原因:上一个版本是白纸黑字记着的);
+2. `docker compose up -d`
-### Kubernetes 回滚
-
-```bash
-# 查看历史版本
-kubectl rollout history deployment/teable -n teable
-
-# 回滚到上一个版本
-kubectl rollout undo deployment/teable -n teable
-
-# 回滚到指定版本
-kubectl rollout undo deployment/teable -n teable --to-revision=
-```
+
+若某次升级执行过数据库结构迁移,直接回滚可能不安全 —— 此时应从升级前的备份恢复。
+这也是上文强烈建议备份的主要原因。
+
## 常见问题
-
-不会。您的数据存储在 Docker 卷或外部数据库中,更新容器不会影响数据。但仍建议在更新前进行备份。
+
+不会。您的数据存储在 Docker 卷或外部数据库中,更新容器不会影响数据。但仍建议在更新前备份。
-
-不会。您的实例 ID 在应用更新过程中保持不变,它是您自托管安装的永久标识符。
+
+不会。应用更新期间 Instance ID 保持不变,它是您私有化安装的永久标识。
-
-通常情况下,拉取新镜像需要几分钟(取决于网络速度),容器重启只需要几秒钟。整个过程通常在 5-10 分钟内完成。
+
+通常拉取新镜像需要几分钟(取决于网速),容器重启只需几秒。整个过程一般在 5-10 分钟内完成。
-
-使用 `docker-compose up -d` 或 Kubernetes 滚动更新时,会有短暂的服务中断(通常几秒到几十秒)。如果需要零停机更新,建议使用 Kubernetes 并配置适当的滚动更新策略。
+
+使用 `docker compose up -d` 会有短暂的服务中断(通常几秒到几十秒)。
-
-您可以通过以下方式查看当前版本:
-- 在 Teable 界面左下角查看版本号
-- 使用管理员账号进入管理面板查看
-- 执行 `docker inspect teable-teable-1 --format='{{.Config.Image}}'` 查看镜像版本
+
+您可以通过以下方式查看当前版本:
+- 查看 Teable 界面左下角的版本号
+- 使用管理员账号访问管理面板
+- 运行 `docker inspect <容器名> --format='{{.Config.Image}}'` 查看镜像版本。若您运行的是 `latest` 通道,全功能部署自带 `pin-image.sh` 工具可解析 `latest` 当前对应的具体版本。
-
-1. 首先查看容器日志排查问题:`docker-compose logs teable`
-2. 如果是数据库迁移问题,尝试从备份恢复数据
-3. 如果问题持续,可以回滚到之前的版本
-4. 联系支持团队 support@teable.ai
+
+1. 先查看容器日志排查:`docker compose logs teable`
+2. 如果是数据库迁移问题,尝试从备份恢复
+3. 问题持续存在时,回滚到上一版本
+4. 联系支持:support@teable.ai