# yaml-language-server: $schema=https://schema.zeabur.app/template.json
apiVersion: zeabur.com/v1
kind: Template
metadata:
    name: Firecrawl
spec:
    description: Self-hosted Firecrawl API plus firecrawl-ui playground — pinned to the v2.11.162 Compose contract.
    coverImage: https://opengraph.githubassets.com/1/firecrawl/firecrawl
    icon: https://avatars.githubusercontent.com/firecrawl
    variables:
        - key: PUBLIC_DOMAIN
          type: DOMAIN
          name: API Domain
          description: Domain for the Firecrawl API endpoint.
        - key: UI_DOMAIN
          type: DOMAIN
          name: UI Domain
          description: Domain for the Firecrawl UI playground (scrape, crawl, extract, map, search).
        - key: OPENAI_API_KEY
          type: STRING
          name: OpenAI API Key (Optional)
          description: Optional. OpenAI-compatible API key for LLM-backed formats (extract, summary, /v2/extract). Leave blank to deploy without LLM features.
        - key: OPENAI_BASE_URL
          type: STRING
          name: OpenAI Base URL (Optional)
          description: Optional. OpenAI-compatible base URL, e.g. https://api.openai.com/v1. Leave blank to use the provider default.
    tags:
        - Tool
        - AI
        - Crawler
        - Web
    readme: |-
        # Firecrawl

        [Firecrawl](https://github.com/firecrawl/firecrawl) is an open-source web crawler and scraper API. This template follows the official [self-hosting guide](https://docs.firecrawl.dev/contributing/self-host) (release `v2.11.162`): PostgreSQL queue, no database authentication, no FoundationDB, no queue-admin UI unless you keep the generated `BULL_AUTH_KEY`.

        The stack:

        - **ui** — [firecrawl-ui](https://github.com/obeone/firecrawl-ui) playground (scrape, crawl, extract, map, search)
        - **api** — `harness.js --start-docker` (API server plus worker, extract-worker, and NUQ queue workers in one container)
        - **playwright** — Chromium microservice for JS-rendered pages
        - **redis** — cache and rate-limit store (no password, matching upstream Compose)
        - **rabbitmq** — NUQ task broker
        - **postgres** — `nuq-postgres` (Postgres 17 + pg_cron + NUQ schema). Database name is `postgres` because pg_cron is compiled against that database.

        ## Resource recommendation

        Upstream Compose sizes the API at 4 vCPU / 8 GB RAM and Playwright at 2 vCPU / 4 GB RAM. Deploy on a Pro plan or a dedicated server.

        ## Configuration

        The API domain and UI domain are required. Authentication is off (`USE_DB_AUTHENTICATION=false`); requests do not need an API key. Do not expose this baseline to untrusted networks without a reverse-proxy ACL or auth layer.

        Optional LLM features (JSON extract, summary, `/v2/extract`): set `OPENAI_API_KEY` and optionally `OPENAI_BASE_URL` at deploy time. Any OpenAI-compatible provider works (OpenAI, OpenRouter, xAI, Ollama, Zeabur AI Hub). Leave both blank to skip LLM. You can still change `MODEL_NAME` on the api env tab after deploy.

        `BULL_AUTH_KEY` is auto-generated. Find it on the api service env tab.

        ## Quick test

        After the API is up, run a real scrape (this is the functional smoke test, not the readiness heartbeat):

        ```bash
        curl --fail-with-body --max-time 75 \
          -X POST https://<your-domain>/v2/scrape \
          -H 'Content-Type: application/json' \
          -d '{"url":"https://example.com","formats":["markdown"],"timeout":60000}'
        ```

        A successful body looks like `{"success":true,"data":{"markdown":"...","metadata":{"statusCode":200}}}`.

        ## Self-hosted feature support

        | Need | This template |
        | --- | --- |
        | Core scrape, crawl, map, search | Included (Fetch + Playwright) |
        | LLM extract / summary | Add an OpenAI-compatible key as above |
        | Fire-engine anti-bot, screenshots, page actions | Not included; those paths need Fire-engine / Cloud |
        | Agent, Browser, interact, product/audio/video formats | Use [Firecrawl Cloud](https://firecrawl.dev) or extra external services |

        ## Playground UI

        Open the **UI domain** after deploy. Nginx on the UI service proxies `/v2`, `/v1`, and `/v0` to the API, so the playground talks same-origin and does not need CORS. If the API URL is empty, open Settings (gear) and paste the UI URL (or the API URL). Config is stored in the browser (`localStorage`).

        Operators can also open Bull Board at:

        `https://<api-domain>/admin/<BULL_AUTH_KEY>/queues`

        ## Versioning

        Upstream GHCR images only publish `:latest`. This template pins each Firecrawl image by digest (pulled 2026-09-02) so deploys stay reproducible. Redis and RabbitMQ use upstream tags.

        ## Reference

        - Self-host docs: https://docs.firecrawl.dev/contributing/self-host
        - GitHub: https://github.com/firecrawl/firecrawl
        - Open Source vs Cloud: https://docs.firecrawl.dev/contributing/open-source-or-cloud
        - Playground UI: https://github.com/obeone/firecrawl-ui
        - License: AGPL-3.0 (Firecrawl); MIT (firecrawl-ui)
    services:
        - name: postgres
          icon: https://cdn.zeabur.com/marketplace/postgresql.svg
          template: PREBUILT
          spec:
            id: postgres
            source:
                image: ghcr.io/firecrawl/nuq-postgres@sha256:aed86f62858f29bd971abddcdeb301c12888098d2cf5d33c1ba42b053bc460f6
            ports:
                - id: database
                  port: 5432
                  type: TCP
            volumes:
                - id: data
                  dir: /var/lib/postgresql/data
            instructions:
                - title: Connection String
                  content: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${PORT_FORWARDED_HOSTNAME}:${DATABASE_PORT_FORWARDED_PORT}/${POSTGRES_DB}
                - title: PostgreSQL Connect Command
                  content: psql "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${PORT_FORWARDED_HOSTNAME}:${DATABASE_PORT_FORWARDED_PORT}/${POSTGRES_DB}"
                - title: PostgreSQL username
                  content: ${POSTGRES_USER}
                - title: PostgreSQL password
                  content: ${POSTGRES_PASSWORD}
                - title: PostgreSQL database
                  content: ${POSTGRES_DB}
                - title: PostgreSQL host
                  content: ${PORT_FORWARDED_HOSTNAME}
                - title: PostgreSQL port
                  content: ${DATABASE_PORT_FORWARDED_PORT}
            env:
                POSTGRES_CONNECTION_STRING:
                    default: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
                    expose: true
                POSTGRES_DB:
                    default: postgres
                    expose: true
                POSTGRES_HOST:
                    default: ${CONTAINER_HOSTNAME}
                    expose: true
                POSTGRES_PASSWORD:
                    default: ${PASSWORD}
                    expose: true
                POSTGRES_PORT:
                    default: ${DATABASE_PORT}
                    expose: true
                POSTGRES_USER:
                    default: postgres
                    expose: true
            healthCheck:
                type: TCP
                port: database
        - name: redis
          icon: https://raw.githubusercontent.com/zeabur/service-icons/main/marketplace/redis.svg
          template: PREBUILT
          spec:
            id: redis
            source:
                image: redis:7-alpine
                command:
                    - redis-server
                    - --bind
                    - 0.0.0.0
            ports:
                - id: database
                  port: 6379
                  type: TCP
            volumes:
                - id: data
                  dir: /data
            instructions:
                - title: Command to connect to your Redis
                  content: redis-cli -h ${PORT_FORWARDED_HOSTNAME} -p ${DATABASE_PORT_FORWARDED_PORT}
                - title: Redis Connection String
                  content: redis://${PORT_FORWARDED_HOSTNAME}:${DATABASE_PORT_FORWARDED_PORT}
                - title: Redis host
                  content: ${PORT_FORWARDED_HOSTNAME}
                - title: Redis port
                  content: ${DATABASE_PORT_FORWARDED_PORT}
            env:
                REDIS_HOST:
                    default: ${CONTAINER_HOSTNAME}
                    expose: true
                REDIS_PORT:
                    default: ${DATABASE_PORT}
                    expose: true
                REDIS_URL:
                    default: redis://${REDIS_HOST}:${REDIS_PORT}
                    expose: true
            healthCheck:
                type: TCP
                port: database
        - name: rabbitmq
          icon: https://raw.githubusercontent.com/zeabur/service-icons/main/marketplace/rabbitmq.svg
          template: PREBUILT
          spec:
            id: rabbitmq
            source:
                image: rabbitmq:3-management
            ports:
                - id: amqp
                  port: 5672
                  type: TCP
            volumes:
                - id: data
                  dir: /var/lib/rabbitmq
            instructions:
                - title: AMQP URL
                  content: amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@${PORT_FORWARDED_HOSTNAME}:${AMQP_PORT_FORWARDED_PORT}
                - title: RabbitMQ username
                  content: ${RABBITMQ_DEFAULT_USER}
                - title: RabbitMQ password
                  content: ${RABBITMQ_DEFAULT_PASS}
            env:
                NUQ_RABBITMQ_URL:
                    default: amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@${RABBITMQ_HOST}:${RABBITMQ_PORT}
                    expose: true
                RABBITMQ_DEFAULT_PASS:
                    default: ${PASSWORD}
                    expose: true
                RABBITMQ_DEFAULT_USER:
                    default: firecrawl
                    expose: true
                RABBITMQ_HOST:
                    default: ${CONTAINER_HOSTNAME}
                    expose: true
                RABBITMQ_PORT:
                    default: ${AMQP_PORT}
                    expose: true
            healthCheck:
                type: TCP
                port: amqp
        - name: playwright
          icon: https://raw.githubusercontent.com/github/explore/60cd2530141f67f07a947fa2d310c482e287e387/topics/playwright/playwright.png
          template: PREBUILT
          spec:
            id: playwright
            source:
                image: ghcr.io/firecrawl/playwright-service@sha256:468009bae00911d40d7120d58489a1d529362c22c45585cb9076094fe61b0025
            ports:
                - id: web
                  port: 3000
                  type: TCP
            env:
                BLOCK_MEDIA:
                    default: "false"
                MAX_CONCURRENT_PAGES:
                    default: "10"
                PLAYWRIGHT_HOST:
                    default: ${CONTAINER_HOSTNAME}
                    expose: true
                PLAYWRIGHT_MICROSERVICE_URL:
                    default: http://${PLAYWRIGHT_HOST}:${PLAYWRIGHT_PORT}/scrape
                    expose: true
                PLAYWRIGHT_PORT:
                    default: ${WEB_PORT}
                    expose: true
                PORT:
                    default: "3000"
            healthCheck:
                type: TCP
                port: web
        - name: api
          icon: https://avatars.githubusercontent.com/firecrawl
          template: PREBUILT
          spec:
            id: api
            source:
                image: ghcr.io/firecrawl/firecrawl@sha256:58138b58a1db575c2dc97bd4253e72361df8013ae232f9e93a0d12303a8b2b40
                command:
                    - node
                    - dist/src/harness.js
                    - --start-docker
            ports:
                - id: web
                  port: 3002
                  type: HTTP
            instructions:
                - title: Firecrawl API URL
                  content: ${ZEABUR_WEB_URL}
                - title: Bull Queue Dashboard
                  content: ${ZEABUR_WEB_URL}/admin/${BULL_AUTH_KEY}/queues
                - title: Quick scrape (curl)
                  content: |-
                    curl --fail-with-body --max-time 75 \
                      -X POST ${ZEABUR_WEB_URL}/v2/scrape \
                      -H 'Content-Type: application/json' \
                      -d '{"url":"https://example.com","formats":["markdown"],"timeout":60000}'
            env:
                BROWSER_POOL_SIZE:
                    default: "5"
                BULL_AUTH_KEY:
                    default: ${PASSWORD}
                CRAWL_CONCURRENT_REQUESTS:
                    default: "10"
                ENV:
                    default: local
                FIRECRAWL_API_HOST:
                    default: ${CONTAINER_HOSTNAME}
                    expose: true
                FIRECRAWL_API_PORT:
                    default: ${WEB_PORT}
                    expose: true
                FIRECRAWL_API_URL:
                    default: ${ZEABUR_WEB_URL}
                    expose: true
                HARNESS_STARTUP_TIMEOUT_MS:
                    default: "120000"
                HOST:
                    default: 0.0.0.0
                LOGGING_LEVEL:
                    default: INFO
                MAX_CONCURRENT_JOBS:
                    default: "5"
                NUM_WORKERS_PER_QUEUE:
                    default: "8"
                NUQ_RABBITMQ_URL:
                    default: ${NUQ_RABBITMQ_URL}
                OPENAI_API_KEY:
                    default: ${OPENAI_API_KEY}
                OPENAI_BASE_URL:
                    default: ${OPENAI_BASE_URL}
                PLAYWRIGHT_MICROSERVICE_URL:
                    default: ${PLAYWRIGHT_MICROSERVICE_URL}
                PORT:
                    default: ${WEB_PORT}
                POSTGRES_DB:
                    default: ${POSTGRES_DB}
                POSTGRES_HOST:
                    default: ${POSTGRES_HOST}
                POSTGRES_PASSWORD:
                    default: ${POSTGRES_PASSWORD}
                POSTGRES_PORT:
                    default: ${POSTGRES_PORT}
                POSTGRES_USER:
                    default: ${POSTGRES_USER}
                REDIS_RATE_LIMIT_URL:
                    default: ${REDIS_URL}
                REDIS_URL:
                    default: ${REDIS_URL}
                USE_DB_AUTHENTICATION:
                    default: "false"
            healthCheck:
                type: TCP
                port: web
          domainKey: PUBLIC_DOMAIN
        - name: ui
          icon: https://avatars.githubusercontent.com/obeone
          template: PREBUILT
          spec:
            id: ui
            source:
                image: ghcr.io/obeone/firecrawl-ui@sha256:01f1227de6f69904da552a00ab28eb3ccd98647b73da157c64d51ad9f9d0febd
            ports:
                - id: web
                  port: 8080
                  type: HTTP
            instructions:
                - title: Firecrawl UI
                  content: ${ZEABUR_WEB_URL}
                - title: Firecrawl API URL
                  content: ${FIRECRAWL_API_URL}
            env:
                FIRECRAWL_API_HOST:
                    default: ${FIRECRAWL_API_HOST}
                FIRECRAWL_API_PORT:
                    default: ${FIRECRAWL_API_PORT}
                FIRECRAWL_API_URL:
                    default: ${FIRECRAWL_API_URL}
            init:
                - id: inject-api-url
                  image: null
                  command:
                    - /bin/sh
                    - -c
                    - sed -i 's#</head>#<script>if(!localStorage.getItem("firecrawl_base_url")){localStorage.setItem("firecrawl_base_url","${ZEABUR_WEB_URL}");}</script></head>#' /usr/share/nginx/html/index.html || true
                  volumes: null
            configs:
                - path: /etc/nginx/conf.d/default.conf
                  template: |-
                    server {
                        listen 8080;
                        server_name localhost;
                        root /usr/share/nginx/html;
                        index index.html;
                        error_page 404 /index.html;

                        location /v2/ {
                            proxy_pass http://${FIRECRAWL_API_HOST}:${FIRECRAWL_API_PORT}/v2/;
                            proxy_http_version 1.1;
                            proxy_read_timeout 120s;
                            proxy_connect_timeout 10s;
                        }
                        location /v1/ {
                            proxy_pass http://${FIRECRAWL_API_HOST}:${FIRECRAWL_API_PORT}/v1/;
                            proxy_http_version 1.1;
                            proxy_read_timeout 120s;
                            proxy_connect_timeout 10s;
                        }
                        location /v0/ {
                            proxy_pass http://${FIRECRAWL_API_HOST}:${FIRECRAWL_API_PORT}/v0/;
                            proxy_http_version 1.1;
                            proxy_read_timeout 120s;
                            proxy_connect_timeout 10s;
                        }
                    }
                  permission: null
                  envsubst: true
            healthCheck:
                type: TCP
                port: web
          domainKey: UI_DOMAIN
localization:
    zh-CN:
        description: 自托管 Firecrawl API + firecrawl-ui 控制台，对齐官方 v2.11.162 Compose 契约。
        variables:
            - key: PUBLIC_DOMAIN
              type: DOMAIN
              name: API 域名
              description: Firecrawl API 要绑定的域名。
            - key: UI_DOMAIN
              type: DOMAIN
              name: UI 域名
              description: Firecrawl UI 控制台域名（scrape / crawl / extract / map / search）。
            - key: OPENAI_API_KEY
              type: STRING
              name: OpenAI API Key（可选）
              description: 可选。OpenAI 兼容 API key，用于 extract、summary、/v2/extract。留空则不启用 LLM。
            - key: OPENAI_BASE_URL
              type: STRING
              name: OpenAI Base URL（可选）
              description: 可选。OpenAI 兼容接口地址，例如 https://api.openai.com/v1。留空则使用供应商默认地址。
        readme: |-
            # Firecrawl

            [Firecrawl](https://github.com/firecrawl/firecrawl) 是开源网页爬取 API。本模板按官方 [自托管指南](https://docs.firecrawl.dev/contributing/self-host)（`v2.11.162`）部署：PostgreSQL 队列、关闭数据库认证、不启用 FoundationDB。

            包含服务：

            - **ui** — [firecrawl-ui](https://github.com/obeone/firecrawl-ui) 控制台（scrape / crawl / extract / map / search）
            - **api** — `harness.js --start-docker`（同一容器内跑 API、worker、extract-worker 和 NUQ 队列 worker）
            - **playwright** — 处理 JS 渲染页的 Chromium 微服务
            - **redis** — 缓存与限流（无密码，与上游 Compose 一致）
            - **rabbitmq** — NUQ 任务队列
            - **postgres** — `nuq-postgres`（Postgres 17 + pg_cron + NUQ schema）。数据库名必须是 `postgres`，因为 pg_cron 写死了该库名。

            ## 资源建议

            上游 Compose 建议 API 至少 4 vCPU / 8 GB RAM，Playwright 至少 2 vCPU / 4 GB RAM。请用 Pro 套餐或独立服务器。

            ## 配置

            需要填写 API 域名和 UI 域名。认证默认关闭（`USE_DB_AUTHENTICATION=false`），请求不需要 API key。不要把这套未鉴权基线直接暴露到不可信网络。

            可选 LLM 能力：部署时填写 `OPENAI_API_KEY`，以及可选的 `OPENAI_BASE_URL`。任意 OpenAI 兼容供应商均可（OpenAI、OpenRouter、xAI、Ollama、Zeabur AI Hub）。两者都留空则跳过 LLM。部署后仍可在 api 的 env 里改 `MODEL_NAME`。

            `BULL_AUTH_KEY` 会自动生成，可在 api 服务 env 中查看。

            ## 快速测试

            ```bash
            curl --fail-with-body --max-time 75 \
              -X POST https://<your-domain>/v2/scrape \
              -H 'Content-Type: application/json' \
              -d '{"url":"https://example.com","formats":["markdown"],"timeout":60000}'
            ```

            成功响应形如 `{"success":true,"data":{"markdown":"...","metadata":{"statusCode":200}}}`。

            ## 自托管能力范围

            | 需求 | 本模板 |
            | --- | --- |
            | scrape / crawl / map / search | 已包含（Fetch + Playwright） |
            | LLM extract / summary | 按上面配置 OpenAI 兼容 key |
            | Fire-engine 反爬、截图、page actions | 不包含，需要 Fire-engine / Cloud |
            | Agent、Browser、interact、product/audio/video | 使用 [Firecrawl Cloud](https://firecrawl.dev) 或额外外部服务 |

            ## 控制台

            部署完成后打开 **UI 域名**。UI 服务的 Nginx 会把 `/v2`、`/v1`、`/v0` 反代到 API，控制台走同源请求，不依赖 CORS。若 API URL 为空，打开设置（齿轮）粘贴 UI 域名（或 API 域名）。配置保存在浏览器 `localStorage`。

            运维队列面板：

            `https://<api-domain>/admin/<BULL_AUTH_KEY>/queues`

            ## 版本

            上游 GHCR 只有 `:latest`。本模板按 digest 锁定 Firecrawl 镜像（拉取日期 2026-09-02）。

            ## 参考

            - 自托管文档: https://docs.firecrawl.dev/contributing/self-host
            - GitHub: https://github.com/firecrawl/firecrawl
            - 开源 vs Cloud: https://docs.firecrawl.dev/contributing/open-source-or-cloud
            - 控制台 UI: https://github.com/obeone/firecrawl-ui
            - License: AGPL-3.0（Firecrawl）；MIT（firecrawl-ui）
    zh-TW:
        description: 自架 Firecrawl API + firecrawl-ui 控制台，對齊官方 v2.11.162 Compose 契約。
        variables:
            - key: PUBLIC_DOMAIN
              type: DOMAIN
              name: API 網域
              description: Firecrawl API 要綁定的網域。
            - key: UI_DOMAIN
              type: DOMAIN
              name: UI 網域
              description: Firecrawl UI 控制台網域（scrape / crawl / extract / map / search）。
            - key: OPENAI_API_KEY
              type: STRING
              name: OpenAI API Key（選填）
              description: 選填。OpenAI 相容 API key，用於 extract、summary、/v2/extract。留空則不啟用 LLM。
            - key: OPENAI_BASE_URL
              type: STRING
              name: OpenAI Base URL（選填）
              description: 選填。OpenAI 相容接口地址，例如 https://api.openai.com/v1。留空則使用供應商預設地址。
        readme: |-
            # Firecrawl

            [Firecrawl](https://github.com/firecrawl/firecrawl) 是開源網頁爬取 API。本模板依官方 [自架指南](https://docs.firecrawl.dev/contributing/self-host)（`v2.11.162`）部署：PostgreSQL 佇列、關閉資料庫認證、不啟用 FoundationDB。

            包含服務：

            - **ui** — [firecrawl-ui](https://github.com/obeone/firecrawl-ui) 控制台（scrape / crawl / extract / map / search）
            - **api** — `harness.js --start-docker`（同一容器內跑 API、worker、extract-worker 與 NUQ 佇列 worker）
            - **playwright** — 處理 JS 渲染頁的 Chromium 微服務
            - **redis** — 快取與限流（無密碼，與上游 Compose 一致）
            - **rabbitmq** — NUQ 任務佇列
            - **postgres** — `nuq-postgres`（Postgres 17 + pg_cron + NUQ schema）。資料庫名稱必須是 `postgres`，因為 pg_cron 寫死了該庫名。

            ## 資源建議

            上游 Compose 建議 API 至少 4 vCPU / 8 GB RAM，Playwright 至少 2 vCPU / 4 GB RAM。請使用 Pro 方案或獨立伺服器。

            ## 設定

            需要填寫 API 網域和 UI 網域。認證預設關閉（`USE_DB_AUTHENTICATION=false`），請求不需要 API key。不要把這套未鑑權基線直接暴露到不可信網路。

            可選 LLM 能力：部署時填寫 `OPENAI_API_KEY`，以及可選的 `OPENAI_BASE_URL`。任意 OpenAI 相容供應商均可（OpenAI、OpenRouter、xAI、Ollama、Zeabur AI Hub）。兩者都留空則略過 LLM。部署後仍可在 api 的 env 改 `MODEL_NAME`。

            `BULL_AUTH_KEY` 會自動產生，可在 api 服務 env 查看。

            ## 快速測試

            ```bash
            curl --fail-with-body --max-time 75 \
              -X POST https://<your-domain>/v2/scrape \
              -H 'Content-Type: application/json' \
              -d '{"url":"https://example.com","formats":["markdown"],"timeout":60000}'
            ```

            成功回應形如 `{"success":true,"data":{"markdown":"...","metadata":{"statusCode":200}}}`。

            ## 自架能力範圍

            | 需求 | 本模板 |
            | --- | --- |
            | scrape / crawl / map / search | 已包含（Fetch + Playwright） |
            | LLM extract / summary | 依上面設定 OpenAI 相容 key |
            | Fire-engine 反爬、截圖、page actions | 不包含，需要 Fire-engine / Cloud |
            | Agent、Browser、interact、product/audio/video | 使用 [Firecrawl Cloud](https://firecrawl.dev) 或額外外部服務 |

            ## 控制台

            部署完成後打開 **UI 網域**。UI 服務的 Nginx 會把 `/v2`、`/v1`、`/v0` 反向代理到 API，控制台走同源請求，不依賴 CORS。若 API URL 為空，打開設定（齒輪）貼上 UI 網域（或 API 網域）。設定存在瀏覽器 `localStorage`。

            維運佇列面板：

            `https://<api-domain>/admin/<BULL_AUTH_KEY>/queues`

            ## 版本

            上游 GHCR 只有 `:latest`。本模板以 digest 鎖定 Firecrawl 映像（拉取日期 2026-09-02）。

            ## 參考

            - 自架文件: https://docs.firecrawl.dev/contributing/self-host
            - GitHub: https://github.com/firecrawl/firecrawl
            - 開源 vs Cloud: https://docs.firecrawl.dev/contributing/open-source-or-cloud
            - 控制台 UI: https://github.com/obeone/firecrawl-ui
            - License: AGPL-3.0（Firecrawl）；MIT（firecrawl-ui）
