Ручная установка
Ручная установка — альтернатива мастеру: вы запускаете опубликованный образ бэкенда njoy14/copula-api:latest с собственным docker-compose.yml. Доступ к репозиторию, клонирование и сборка из исходников не требуются — всё запускается из публичных образов. Используйте этот путь, когда нужен полный контроль над compose-стеком.
Предварительные условия: сервер, соответствующий требованиям (с установленным Docker), и лицензионный токен.
WARNING
В стеке по умолчанию нет ни TLS, ни reverse proxy. Поставьте перед бэкендом собственный reverse proxy — см. Reverse proxy и TLS.
Шаги
Установите Docker согласно требованиям и получите лицензионный токен в кабинете.
Создайте каталог установки (например,
/root/copula) и перейдите в него. Подкаталогиdata,workspaceиsshбудут созданы автоматически при первом запуске через volume'ы compose:bashmkdir -p /root/copula && cd /root/copulaСоздайте
docker-compose.ymlсо следующим содержимым:yamlversion: '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:Создайте
.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 64ENCRYPTION_KEY— ровно 32 символа; сгенерируйте командойopenssl rand -hex 16POSTGRES_PASSWORD— надёжный пароль для встроенного PostgreSQLLICENSE_TOKEN— токен из кабинетаADMIN_USER/ADMIN_PASS— начальные учётные данные администратора
См. полный справочник переменных окружения по каждой переменной.
Скачайте образы и запустите стек:
bashdocker compose pull docker compose up -dПроверьте, что миграции применились и бэкенд запущен:
bashdocker logs copula-migrate docker logs copula-back
Что входит в стек
| Сервис | Роль |
|---|---|
copula-postgres | PostgreSQL (postgres:16-alpine); только внутренний, без порта хоста |
copula-migrate | Init-задача из 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:
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.