Deployment and operations
Private deployment (Docker)
Deploy AskTable on your own server, initialize it, and verify access.
Private deployment runs AskTable's main service, PostgreSQL, Redis, and Python sandbox on your own server. Only the main service exposes a host port; other services communicate through the internal Compose network.
Choose online deployment when the server can access image registries. For a fully isolated internal network, choose offline deployment: download the offline package and installation script outside the network, then copy them into the internal network for installation.
Prerequisites
| Item | Requirement |
|---|---|
| Architecture | Linux x86_64 (amd64) or ARM64 (arm64); the offline package must match the target server's Docker architecture |
| Minimum resources | 4 CPU cores, 16 GB RAM, 100 GB disk |
| Operating system | Linux server |
| Docker | Docker Engine + Docker Compose v2.23.1 or later. configs.content in Compose (inline database-creation SQL) was introduced in this version; older versions fail during parsing |
| Model service | Prepare an accessible model service; use an internal model service in a fully isolated network |
| Port | Host port 8000 available (the container listens on 80) |
Steps
Online deployment requires HTTPS (443) access to image registries. Allow model and tracing services according to actual usage:
| Address | Purpose | Symptom if blocked |
|---|---|---|
registry.cn-shanghai.aliyuncs.com | Pull all images | docker compose pull hangs and then times out |
dockerauth.cn-hangzhou.aliyuncs.com | Alibaba Cloud image registry authentication | docker login reports authentication failure and images cannot be pulled |
aiproxy.asktable.com | Model service when using AskTable-hosted compute | “Test model” fails after entering the compute API Key in the wizard |
lf.asktable.com | Call tracing (Langfuse) | Conversations work, but service logs show tracing upload errors |
Save docker-compose.yaml
Create a directory on the server (such as /opt/asktable) and save the content of the “docker-compose.yaml” section below in this tab unchanged as docker-compose.yaml in that directory.
Keep ports and volume paths unchanged: ports determine the access URL, and volume paths determine which host directories store the data.
Start the services
Run in the directory containing docker-compose.yaml:
docker compose up -dOn startup, the asktable container first runs database schema migration (syncdb), then starts the API, nginx, background task processes, and built-in MCP service. The first startup automatically creates the asktable and asktable_workbook databases.
docker-compose.yaml
The four services' roles are described in inline comments. Backend services communicate over the internal Compose network; only asktable exposes a public port.
services:
# Main service: backend API + frontend + built-in MCP (the only service exposed externally)
asktable:
image: registry.cn-shanghai.aliyuncs.com/datamini/asktable-all-in-one:latest # mainland China; elsewhere use datamini/asktable-all-in-one:latest
container_name: asktable
depends_on:
- asktable-pg
- asktable-redis
- asktable-atbox
ports:
- "8000:80"
privileged: true
environment:
TZ: Asia/Shanghai
AT_REGION: global # cn or global; keep static after deployment
DATABASE_HOST: asktable-pg
DATABASE_PORT: 5432
DATABASE_USER: asktable
DATABASE_PASSWORD: asktable # [change me]
DATABASE_DB: asktable
REDIS_URL: redis://asktable-redis:6379
ATBOX_URL: http://asktable-atbox:5300
# Workbook's own database: same instance/role, separate database (PG has no cross-db query -> hard isolation)
WORKBOOK_PG_DSN: postgresql://asktable:asktable@asktable-pg:5432/asktable_workbook
volumes:
- ./asktable_data:/asktable
# PostgreSQL 17 (pgvector): primary database (metadata, config, field vectors)
asktable-pg:
image: pgvector/pgvector:pg17
container_name: asktable-pg
restart: unless-stopped
command: ["postgres", "-c", "max_connections=100"]
environment:
POSTGRES_USER: asktable
POSTGRES_PASSWORD: asktable # [change me] keep consistent with DATABASE_PASSWORD
POSTGRES_DB: asktable
volumes:
- ./postgres_data:/var/lib/postgresql/data
configs:
# Runs once on a fresh deployment with an empty data volume; creates the workbook database
- source: workbook-initdb
target: /docker-entrypoint-initdb.d/01-create-workbook-db.sql
# Redis 7.4: task queue
asktable-redis:
image: registry.cn-shanghai.aliyuncs.com/dminfra/redis:7.4.4
container_name: asktable-redis
restart: unless-stopped
command: redis-server --appendonly yes
volumes:
- ./redis_data:/data
# Python sandbox: isolated execution of untrusted, agent-generated Python.
# Options marked "security" are the sandbox itself — do not remove; "tunable" resource limits can be adjusted.
asktable-atbox:
image: registry.cn-shanghai.aliyuncs.com/datamini/asktable-atbox:latest # mainland China; elsewhere use datamini/asktable-atbox:latest
container_name: asktable-atbox
restart: unless-stopped
environment:
TZ: Asia/Shanghai
ATBOX_MAX_WORKERS: 8 # tunable: concurrent workers
ATBOX_DEFAULT_TIMEOUT: 30s # tunable: default execution timeout
ATBOX_MAX_TIMEOUT: 120s # tunable: max execution timeout
ATBOX_ENABLE_NETWORK: "0" # security: no network inside the sandbox
# security: read-only rootfs + writable scratch (/var/atbox/root/tmp is the chroot workdir); paired, do not remove
read_only: true
tmpfs:
- /var/atbox/root/tmp:rw,noexec,nosuid,nodev,mode=1777,size=512m
- /tmp:rw,noexec,nosuid,nodev,mode=1777,size=64m
# security: drop all capabilities, add back only the minimal set chroot + UID-drop need; do not change
cap_drop:
- ALL
cap_add:
- CHOWN
- DAC_OVERRIDE
- SETUID
- SETGID
- SYS_CHROOT
security_opt:
- no-new-privileges:true # security: block privilege escalation
pids_limit: 128 # tunable: max processes (anti fork-bomb)
mem_limit: 1g # tunable: memory cap
cpus: 1.0 # tunable: CPU cap
configs:
# Inline create-database SQL; requires Docker Compose v2.23.1+ (configs.content support)
workbook-initdb:
content: |
CREATE DATABASE asktable_workbook;Before production deployment, change the default secrets marked [change me]: the passwords in DATABASE_PASSWORD, POSTGRES_PASSWORD, and WORKBOOK_PG_DSN must match.
Complete the initialization wizard
For first-time online and offline installations, open http://<server-address>:8000/. If the database has no users, the /setup initialization wizard opens, with “Create administrator” followed by “Configure models”. Existing deployments retain their access URL and accounts after an upgrade.
- Create the administrator and organization: Enter the organization name, administrator email, password, and password confirmation, following the page's password requirements. The account becomes a system administrator, and a default organization is created.
- Configure models: Connected environments can choose “AskTable official API channel” and enter the compute API Key. In a fully isolated network, choose “Custom channel”, enter the internal model service's Base URL, API Key, and model name, then click “Complete configuration”. See Configure models for details.
- Verify usage: Log in with the administrator account you just created and follow the remaining guidance to create a project. Confirm the console opens and the model test passes, then connect a dataset and complete one question. A successful container startup does not mean models or business functions are ready.
To let your team ask questions in Feishu or Slack, add a separate gateway container; see Deploy the message gateway.
Access URLs
| Entry | URL |
|---|---|
| Console | http://<server>:8000/ |
| API documentation (ReDoc) | http://<server>:8000/api/v1/redoc |
| API documentation (Swagger UI) | http://<server>:8000/api/v1/docs |
| Current version (JSON) | http://<server>:8000/api/v1/version |
| MCP service | http://<server>:8000/mcp/ |
Enable Workbook
Workbook lets you create and edit tables in AskTable, with data stored in a separate PostgreSQL database. WORKBOOK_PG_DSN selects that database and must not point to AskTable's main database.
The complete Compose example on this page already configures WORKBOOK_PG_DSN and creates asktable_workbook when PostgreSQL initializes an empty data volume for the first time. A new deployment does not need another database-creation step. When reusing an existing volume, the initialization SQL does not run again, so updating Compose alone will not create the missing database.
For an existing deployment, check and complete the following:
-
Confirm that a separate Workbook database exists in PostgreSQL. If you use the service name and database account from this page and have not yet created it, run this once from the deployment directory:
docker compose exec asktable-pg psql -U asktable -d asktable -c "CREATE DATABASE asktable_workbook;"For external PostgreSQL or a custom account, ask the database administrator to create a separate database and grant the Workbook connection account access to connect, create schemas and tables, and read and write data.
-
Confirm that
WORKBOOK_PG_DSNin theasktableservice'senvironmentpoints to this separate database. The following shows the format; replace the username, password, address, and database name with actual values:postgresql://<username>:<password>@<database-host>:5432/<Workbook-database-name>With this page's Compose example, the database host is
asktable-pgon the container network, notlocalhost. The password must match the actual database account. Explicitly settingWORKBOOK_PG_DSNto an empty string disables Workbook. -
After changing configuration, run
docker compose up -d asktableso the main service applies it. Sign in, create a Workbook, enter data, and query it to verify availability.
A “configured” status only means the DSN is nonempty; it does not confirm a successful database connection. If Workbook is reported as unavailable, inspect connection errors in docker compose logs asktable and check the database's existence, credentials, and network access. There is no need to delete existing data volumes.
Key constraints
| Item | Value or default | Where to change it |
|---|---|---|
| Public ports | Only asktable exposes 8000:80; asktable-pg, asktable-redis, and asktable-atbox do not map host ports | ports in docker-compose.yaml |
| Database password | Example value: asktable | Passwords in DATABASE_PASSWORD, POSTGRES_PASSWORD, and WORKBOOK_PG_DSN must match in all three places |
| Sandbox authentication | No API Key; only internal network sources are accepted | Therefore, do not add ports to asktable-atbox |
| Sandbox network | ATBOX_ENABLE_NETWORK: "0", disabling network access inside the sandbox | asktable-atbox.environment |
| Sandbox concurrency and timeouts | ATBOX_MAX_WORKERS: 8, ATBOX_DEFAULT_TIMEOUT: 30s, ATBOX_MAX_TIMEOUT: 120s | Same as above |
| Container time zone | The main service and sandbox in the online example and offline package use Asia/Shanghai | Set TZ in the corresponding service's environment |
| Deployment Region | Default: cn, with global also supported; this English Compose example retains global. Private deployment always uses email as the account identifier | AT_REGION; keep it fixed after deployment, as later changes require identity data migration |
| PostgreSQL connection limit | Example: 100; default conservative application peak: 51 | asktable-pg.command; see Operations and capacity planning before scaling |
| Background task processes | 1 | Add AT_WORKER_NUM_PROCS to asktable.environment |
| Data storage locations | ./asktable_data (uploads in filestore/, logs in log/, vector model cache in models/), ./postgres_data, ./redis_data | volumes in docker-compose.yaml |
| Separate Workbook database | asktable_workbook, same instance and role as the main database, but a separate database | WORKBOOK_PG_DSN and inline database-creation SQL |
| Image tag | :latest | Pin a version number for version-based rollback; releases push both {version} and latest |
| Administrator entry | The first user is created by the /setup wizard; later users are controlled through “System settings” → “User registration” | Avatar → “System settings” → “User registration” |
Troubleshooting
| Symptom | How to identify it | Action |
|---|---|---|
| Browser cannot open the page | asktable is not running in docker compose ps | Check initialization logs at the start of docker compose logs asktable |
| Page opens but all API calls return 502 | curl -sS http://127.0.0.1:8000/api/v1/version does not return JSON | The API process inside the container did not start; check docker compose logs asktable |
| Backend cannot connect to the database | Logs show a database authentication failure, and DATABASE_PASSWORD differs from POSTGRES_PASSWORD | Set both to the same value, then recreate the container with docker compose up -d |
docker compose up fails | The error contains port is already allocated | Stop the process occupying 8000, or change ports to "18000:80" and access the new port |
Logs show collation version mismatch | The PostgreSQL image changed while the old postgres_data was reused | Follow Version upgrades and migration: rebuild indexes before refreshing the version number |
Recurring DATABASE_BUSY | Logs show connection wait timeouts or exhausted PostgreSQL connections | Check database headroom and background concurrency first, then follow Operations and capacity planning |
| Workbook operations fail | The page reports Workbook as unavailable, or docker compose logs asktable shows Workbook PG connection failed | Follow Enable Workbook to check the separate database, connection settings, and permissions |
| Cannot pull images | docker compose pull reports a TLS timeout or authentication failure | For online deployment, allow addresses in the corresponding tab's table; for isolated environments, install the offline package |
| Cannot open the wizard | Opening the homepage goes directly to login, with no /setup | The database already has users; log in as an administrator. For a forgotten password, use the recovery flow on the login page |
Upgrade
For either method, back up databases and business data before upgrading and read Version upgrades and migration.
Online deployment: Run in the deployment directory:
docker compose pull
docker compose down
docker compose up -dThe online example uses :latest, so pull retrieves the latest current version. To upgrade to a specific version, replace :latest in image with that version number.
Offline deployment: Download the script and architecture-matched package from the same release again outside the network, then copy them into the internal network. Follow the offline steps above: run --dry-run first, then install without that option. --dir must point to the original deployment directory. The script recognizes existing deployments, updates images according to the plan, and retains existing ports, volumes, and other configuration. There is no need to run docker compose pull.
The recovery record generated by the script restores only this machine's pre-upgrade configuration and local image tags; it does not include database or business data backups. After upgrading, check container logs, the original access URL, and an actual query. Handle database migration and data recovery according to the migration guide.
Removal
docker compose down
rm -rf asktable_data postgres_data redis_dataDeleting data volumes clears all data and is irreversible. Back up first.
Alibaba Cloud Compute Nest deployment
Instances purchased through Alibaba Cloud Marketplace use Compute Nest for automatic deployment. Follow the process in your order and Compute Nest service instance, then open AskTable at the access URL provided by the instance and complete initialization and model configuration. To activate an enterprise license, follow Commercial licensing.
Next steps
- Deployment authentication configuration — Environment variables for login methods, SMTP, and SMS
- Operations and capacity planning — Database connection pools and background concurrency
- Configure models — Connect your own or hosted models
- Version upgrades and migration — Upgrades, rollback, and manual steps across versions
- Deploy AI Search (value indexing) — Match abbreviations to full values
- Deploy the message gateway — Let the team ask questions in Feishu direct messages and groups
- Advanced configuration — Subpath deployment and white labeling
- Connect data sources — Connect your data