# Private deployment (Docker)

Deploy AskTable on your own server, initialize it, and verify access.

部署说明 · 模块: deploy · 管理人员 · 部署形态：私有部署 · 已确认产品版本：资料未说明 · 来源：现有文档

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](https://docs.docker.com/engine/install/) + [Docker Compose](https://docs.docker.com/compose/install/) **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**

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`:

```bash
docker compose up -d
```

On 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.

```yaml docker-compose.yaml download="docker-compose.yaml" downloadLabel="Download"
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;
```

**Warning**

Before production deployment, change the default secrets marked **\[change me]**: the passwords in `DATABASE_PASSWORD`, `POSTGRES_PASSWORD`, and `WORKBOOK_PG_DSN` must match.

**Offline deployment**

Use this when the target server cannot connect to the public internet. The offline package contains the images and Compose configuration needed to run AskTable, but **does not include Docker installers or model weights**. Install Docker / Compose on the internal server in advance and prepare an internal model service accessible from the AskTable container.

**Confirm the target server architecture**

Run on the internal server:

```bash
docker info --format '{{.Architecture}}'
docker compose version
```

For `x86_64` or `amd64`, choose the AMD64 package; for `aarch64` or `arm64`, choose ARM64. The installation script also supports the `docker-compose` command, which likewise requires version **2.23.1 or later**.

**Download the offline package and installation script outside the network**

On a computer with internet access, download **one offline package matching the target server architecture** and the installation script:

| File                                               | Download                                                                                                                                          |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| Linux AMD64 offline package                        | [asktable-offline-linux-amd64.tar.gz](https://datamini-release.oss-cn-shanghai.aliyuncs.com/asktable/offline/asktable-offline-linux-amd64.tar.gz) |
| Linux ARM64 offline package                        | [asktable-offline-linux-arm64.tar.gz](https://datamini-release.oss-cn-shanghai.aliyuncs.com/asktable/offline/asktable-offline-linux-arm64.tar.gz) |
| Installation script (shared by both architectures) | [install-asktable.sh](https://datamini-release.oss-cn-shanghai.aliyuncs.com/asktable/offline/install-asktable.sh)                                 |

The script validates the archive. Download the script and package from the same release together; do not rename them or extract them manually.

**Copy them to the internal server**

Place the archive and `install-asktable.sh` in **the same writable directory** on the server, such as `/opt/asktable-offline`. This directory stores installation files and is separate from the deployment directory `/opt/asktable`.

Installation extracts images beside the package, then imports them into Docker. Leave extraction space on the disk holding the installation files and image space on the disk holding Docker's data directory, plus space for business data growth.

The commands below use `sudo`: the account needs permission to manage Docker and write to both the installation-file and deployment directories. For first installation, the deployment directory must be empty or absent; for an existing deployment, read “Upgrade” below first.

**Preview the deployment plan**

Enter the installation-file directory and check the archive, architecture, and deployment configuration:

```bash
cd /opt/asktable-offline
sudo sh install-asktable.sh --dir /opt/asktable --dry-run
```

Confirm the reported deployment directory, project, offline package version, and image plan match expectations. `--dry-run` does not import images, change deployment configuration, or start services. If validation fails, obtain the script and archive from the same release again.

**Install and start**

Once the preview passes, run in the same directory:

```bash
sudo sh install-asktable.sh --dir /opt/asktable
```

The script imports local images, writes the packaged Compose configuration on first installation, and starts services with `--pull never --no-build`. Installation does not need to pull public images.

After the installation command completes, continue with initialization and access verification below to confirm that pages and model calls work.

## 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.

1. **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.
2. **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](https://docs.asktable.com/en/admin/models) for details.
3. **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.

**Note**

To let your team ask questions in Feishu or Slack, add a separate gateway container; see [Deploy the message gateway](https://docs.asktable.com/en/deploy/feishu-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:

1. 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:

   ```bash
   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.

2. Confirm that `WORKBOOK_PG_DSN` in the `asktable` service's `environment` points to this separate database. The following shows the format; replace the username, password, address, and database name with actual values:

   ```text
   postgresql://<username>:<password>@<database-host>:5432/<Workbook-database-name>
   ```

   With this page's Compose example, the database host is `asktable-pg` on the container network, not `localhost`. The password must match the actual database account. Explicitly setting `WORKBOOK_PG_DSN` to an empty string disables Workbook.

3. After changing configuration, run `docker compose up -d asktable` so 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](https://docs.asktable.com/en/deploy/operations) 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](https://docs.asktable.com/en/deploy/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](https://docs.asktable.com/en/deploy/operations)  |
| Workbook operations fail                | The page reports Workbook as unavailable, or `docker compose logs asktable` shows `Workbook PG connection failed` | Follow [Enable Workbook](https://docs.asktable.com/en/deploy/docker#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](https://docs.asktable.com/en/deploy/migration).

**Online deployment**: Run in the deployment directory:

```bash
docker compose pull
docker compose down
docker compose up -d
```

The 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

```bash
docker compose down
rm -rf asktable_data postgres_data redis_data
```

**Warning**

Deleting data volumes clears all data and is irreversible. Back up first.

## Alibaba Cloud Compute Nest deployment

Instances purchased through [Alibaba Cloud Marketplace](https://market.aliyun.com/detail/cmgj00073069.html) 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](https://docs.asktable.com/en/admin/license).

## Next steps

- [Deployment authentication configuration](https://docs.asktable.com/en/deploy/authentication) — Environment variables for login methods, SMTP, and SMS
- [Operations and capacity planning](https://docs.asktable.com/en/deploy/operations) — Database connection pools and background concurrency
- [Configure models](https://docs.asktable.com/en/admin/models) — Connect your own or hosted models
- [Version upgrades and migration](https://docs.asktable.com/en/deploy/migration) — Upgrades, rollback, and manual steps across versions
- [Deploy AI Search (value indexing)](https://docs.asktable.com/en/deploy/ai-search) — Match abbreviations to full values
- [Deploy the message gateway](https://docs.asktable.com/en/deploy/feishu-gateway) — Let the team ask questions in Feishu direct messages and groups
- [Advanced configuration](https://docs.asktable.com/en/deploy/advanced) — Subpath deployment and white labeling
- [Connect data sources](https://docs.asktable.com/en/data/connect) — Connect your data
