> ## Documentation Index
> Fetch the complete documentation index at: https://docs.asktable.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Self-hosting (Docker)

> Deploy the full AskTable stack on your own server with Docker Compose so data never leaves your network. Includes the complete docker-compose, access, and upgrade steps.

AskTable can run fully self-hosted: every component runs as a Docker container in your own environment, and data never leaves your network. This page covers the all-in-one Docker Compose deployment.

## Prerequisites

**Hardware** (minimum): 4-core CPU, 16 GB RAM, 100 GB disk, x86.

**Software**: a Linux server + [Docker](https://docs.docker.com/engine/install/) + [Docker Compose](https://docs.docker.com/compose/install/) **v2.23.1+** (deployment uses the `configs.content` inline feature).

**Network**: the host needs outbound HTTPS (443) to:

| Address                               | Purpose                                                |
| ------------------------------------- | ------------------------------------------------------ |
| `registry.cn-shanghai.aliyuncs.com`   | Pull images                                            |
| `dockerauth.cn-hangzhou.aliyuncs.com` | Image authentication                                   |
| `aiproxy.asktable.com`                | AI model service (when using AskTable's hosted models) |
| `lf.asktable.com`                     | AI call tracing                                        |

<Note>
  Fully offline: preload the images into your network and choose **Custom** in [Configuring LLMs](/en/deploy/models) to use an in-network model — then no internet access is needed.
</Note>

## docker-compose.yaml

Create a directory and save the following as `docker-compose.yaml`. Each service's role is in the inline comments; backing services talk to each other over the Compose internal network and only `asktable` exposes a host port. For servers outside mainland China, switch the images to the Docker Hub versions in the comments (`datamini/...`).

```yaml docker-compose.yaml theme={null}
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
      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
    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 a production deployment, change the values marked **\[change me]**: `DATABASE_PASSWORD` (keep it consistent with `POSTGRES_PASSWORD`).
</Warning>

## Start and initialize

<Steps>
  <Step title="Start">
    From the directory containing `docker-compose.yaml`:

    ```bash theme={null}
    docker compose up -d
    ```

    The first start initializes the databases automatically (including the separate Workbook database).
  </Step>

  <Step title="Open">
    Open `http://<your-server>:8000/` in a browser.
  </Step>

  <Step title="Initialize">
    Follow the wizard to create an admin account and configure an LLM (model group), then start using AskTable.
  </Step>
</Steps>

## Access URLs

| Entry         | URL                                 |
| ------------- | ----------------------------------- |
| Console UI    | `http://<server>:8000/`             |
| API reference | `http://<server>:8000/api/v1/redoc` |
| MCP server    | `http://<server>:8000/mcp/`         |

## Configure an LLM

AskTable is not tied to a specific model — you configure one before you can ask questions. The first-run wizard walks you through it. See [Configuring LLMs](/en/deploy/models).

## Enable Workbook

Workbook is the built-in writable dataset, stored in a separate `asktable_workbook` database that is hard-isolated from the main one. The compose above already sets `WORKBOOK_PG_DSN` and inlines the create-database SQL:

* **Fresh deployment**: the database is created automatically on first start — nothing to do.
* **Upgrading an existing deployment**: the data volume is already initialized and the init script no longer runs, so create the database once manually:

  ```bash theme={null}
  docker compose exec asktable-pg psql -U asktable -d asktable -c "CREATE DATABASE asktable_workbook;"
  docker compose up -d
  ```

## Upgrading

```bash theme={null}
docker compose pull
docker compose down
docker compose up -d
```

<Note>
  **Upgrading from an older version** (remove Qdrant, switch to the pgvector image, handle the collation-version warning, rebuild embeddings) — see [Migration](/en/deploy/migration).
</Note>

## Uninstalling

```bash theme={null}
docker compose down
rm -rf asktable_data postgres_data redis_data
```

<Warning>
  Removing the data volumes erases all data permanently. Back up first.
</Warning>

## Next steps

* [Configuring LLMs](/en/deploy/models) — connect your own or a hosted LLM
* [AI Search (Value Index)](/en/deploy/ai-search) — match abbreviations to full stored values (optional, needs aisearch)
* [Advanced configuration](/en/deploy/advanced) — subpath deployment, white-labeling
* [Commercial licensing](/en/deploy/license) — trial limits and the enterprise license
* [Connecting Data](/en/concepts/data/connect) — bring your data in
