Skip to content

Ручная установка

Ручная установка — альтернатива мастеру: вы запускаете опубликованный образ бэкенда njoy14/copula-api:latest с собственным docker-compose.yml. Доступ к репозиторию, клонирование и сборка из исходников не требуются — всё запускается из публичных образов. Используйте этот путь, когда нужен полный контроль над compose-стеком.

Предварительные условия: сервер, соответствующий требованиям (с установленным Docker), и лицензионный токен.

WARNING

В стеке по умолчанию нет ни TLS, ни reverse proxy. Поставьте перед бэкендом собственный reverse proxy — см. Reverse proxy и TLS.

Шаги

  1. Установите Docker согласно требованиям и получите лицензионный токен в кабинете.

  2. Создайте каталог установки (например, /root/copula) и перейдите в него. Подкаталоги data, workspace и ssh будут созданы автоматически при первом запуске через volume'ы compose:

    bash
    mkdir -p /root/copula && cd /root/copula
  3. Создайте docker-compose.yml со следующим содержимым:

    yaml
    version: '3.9'
    
    services:
      copula-postgres:
        container_name: copula-postgres
        image: postgres:16-alpine
        restart: unless-stopped
        networks:
          - copula-network
        environment:
          POSTGRES_USER: ${POSTGRES_USER}
          POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
          POSTGRES_DB: ${POSTGRES_DB}
        volumes:
          - ./data:/var/lib/postgresql/data
        healthcheck:
          test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
          interval: 10s
          timeout: 5s
          retries: 5
    
      copula-migrate:
        container_name: copula-migrate
        image: njoy14/copula-api:latest
        entrypoint: ["/usr/local/bin/migrate"]
        networks:
          - copula-network
        env_file:
          - .env
        command:
          - "-path=/migrations"
          - "-database"
          - "postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@copula-postgres:5432/${POSTGRES_DB}?sslmode=disable"
          - "up"
        restart: "no"
        depends_on:
          copula-postgres:
            condition: service_healthy
    
      copula-back:
        container_name: copula-back
        image: njoy14/copula-api:latest
        restart: unless-stopped
        user: "root"
        networks:
          - copula-network
        volumes:
          - ./workspace:/workspace
          - ./ssh:/root/.ssh
          - ./.env:/config/.env:ro
          - /var/run/docker.sock:/var/run/docker.sock
        ports:
          - "8901:${BACKEND_PORT}"
        env_file:
          - .env
        depends_on:
          copula-postgres:
            condition: service_healthy
          copula-migrate:
            condition: service_completed_successfully
    
      copula-cocoindex:
        container_name: copula-cocoindex
        image: ${COCOINDEX_CODE_IMAGE:-cocoindex/cocoindex-code:full}
        restart: unless-stopped
        volumes:
          - ./workspace:/workspace
          - cocoindex-data:/var/cocoindex
        stdin_open: true
        tty: true
        command: ccc mcp
        healthcheck:
          test: ["CMD-SHELL", "ccc doctor || exit 1"]
          interval: 10s
          timeout: 5s
          retries: 3
          start_period: 30s
    
      # Опциональный TLS-терминатор. Раскомментируйте ТОЛЬКО если у этого
      # хоста есть публичный домен, DNS которого уже указывает на него,
      # и порты 80/443 свободны. Иначе оставьте блок закомментированным
      # и следуйте странице «Reverse proxy и TLS».
      # copula-caddy:
      #   container_name: copula-caddy
      #   image: caddy:2.11.4-alpine
      #   restart: unless-stopped
      #   networks:
      #     - copula-network
      #   ports:
      #     - "80:80"
      #     - "443:443"
      #   volumes:
      #     - ./Caddyfile:/etc/caddy/Caddyfile:ro
      #     - ./caddy-data:/data
      #   depends_on:
      #     - copula-back
    
    volumes:
      cocoindex-data:
    
    networks:
      copula-network:
  4. Создайте .env со следующим содержимым и заполните обязательные значения:

    bash
    # === Бэкенд ===
    BACKEND_PORT=8080
    LOG_LEVEL=info
    CORS_ALLOWED_ORIGINS=*
    PUBLIC_BASE_URL=https://copula.example.com
    
    # === Безопасность (все обязательны) ===
    # ровно 128 hex-символов — генерация: openssl rand -hex 64
    JWT_SECRET=
    # ровно 32 символа — генерация: openssl rand -hex 16
    ENCRYPTION_KEY=
    # лицензионный токен из кабинета https://app.copul4.com
    LICENSE_TOKEN=
    CABINET_URL=https://api.copul4.com
    
    # === PostgreSQL (соответствует сервису copula-postgres) ===
    POSTGRES_HOST=copula-postgres
    POSTGRES_PORT=5432
    POSTGRES_USER=agent
    POSTGRES_PASSWORD=
    POSTGRES_DB=agentdb
    
    # === Начальная учётная запись администратора ===
    ADMIN_USER=admin
    ADMIN_PASS=
    
    # === Модель (по умолчанию: LLM-роутер кабинета; учётные данные — лицензионный токен) ===
    MODEL_PROVIDER=copula
    MODEL_BASE_URL=
    MODEL_NAME=copula-base
    # MODEL_API_KEY=            # не нужен для provider=copula
    # SMART_MODEL_* / BASIC_MODEL_* — опциональные переопределения по профилям, см. env-reference
    
    # === Рантайм агентов ===
    AGENT_WORKSPACE=/workspace
    AGENT_CONTEXT_TOKEN_LIMIT=120000
    MAX_REPO_WORKERS=20
    
    # === Хранилище ===
    SESSION_STORAGE_TYPE=database
    SESSION_FILE_PATH=./sessions
    FILE_STORAGE_PATH=./uploads
    MAX_FILE_SIZE_MB=200
    
    # === Интеграции ===
    SP_DISTRIBUTOR_URL=https://get.copul4.com
    COCOINDEX_CODE_IMAGE=cocoindex/cocoindex-code:full

    Обязательные значения для заполнения:

    • JWT_SECRET — ровно 128 hex-символов; сгенерируйте командой openssl rand -hex 64
    • ENCRYPTION_KEY — ровно 32 символа; сгенерируйте командой openssl rand -hex 16
    • POSTGRES_PASSWORD — надёжный пароль для встроенного PostgreSQL
    • LICENSE_TOKEN — токен из кабинета
    • ADMIN_USER / ADMIN_PASS — начальные учётные данные администратора

    См. полный справочник переменных окружения по каждой переменной.

  5. Скачайте образы и запустите стек:

    bash
    docker compose pull
    docker compose up -d
  6. Проверьте, что миграции применились и бэкенд запущен:

    bash
    docker logs copula-migrate
    docker logs copula-back

Что входит в стек

СервисРоль
copula-postgresPostgreSQL (postgres:16-alpine); только внутренний, без порта хоста
copula-migrateInit-задача из njoy14/copula-api:latest (entrypoint /usr/local/bin/migrate, миграции встроены в образ в /migrations); применяет миграции базы данных до запуска бэкенда
copula-backБэкенд (njoy14/copula-api:latest); порт хоста 8901${BACKEND_PORT}; монтирует workspace, ssh, .env и сокет Docker
copula-cocoindexДемон поиска по коду (cocoindex/cocoindex-code:full)
copula-caddyОпциональный TLS-терминатор (caddy:2.11.4-alpine); по умолчанию закомментирован

При первом запуске entrypoint.sh бэкенда генерирует RSA SSH-ключ в /root/.ssh внутри контейнера (сохраняется в ./ssh на хосте).

INFO

Включение закомментированного блока copula-caddy требует публичного домена, DNS которого уже указывает на этот хост, и свободных портов 80/443. Также рядом с compose-файлом нужен Caddyfile:

text
copula.example.com {
	reverse_proxy copula-back:8080
}

Порт в reverse_proxy должен совпадать с BACKEND_PORT из .env — в Caddyfile нет интерполяции переменных окружения. A-запись домена должна резолвиться до docker compose up, иначе выпуск сертификата завершится ошибкой.

После установки

Бэкенд слушает порт хоста 8901. Поставьте перед ним reverse proxy с TLS (Reverse proxy и TLS), затем добавьте получившийся URL https://<domain> как Space в приложении Copula.