Как и любого уважающего себя молодого человека меня нередко преследуют мысли об открытии своего собственного технологического стартапа, ну или хотя бы магазина рыболовных приспособлений у метро. Но каждый раз все разбивается о суровые реалии нашего мира. Любое дело подразумевает наличие команды, учет товаров, обслуживание клиентов и многое другое.
А как обслужить клиента и удобно хранить информацию о нем? Для этого существует CRM — система управления отношениями с клиентами, которая помогает бизнесу собирать, хранить и использовать данные о клиентах, автоматизировать продажи и улучшать обслуживание.
Многие существующие на рынке CRM-решения выставляют огромный ценник и, на фоне не всегда высокой маржинальности реализуемой услуги или товара, многие идеи теряют свою актуальность в силу существенных издержек, ведь нередко поддержание работоспособности подобных программных решений занимает значимую часть общих расходов компании. Однако нет большей неудачи, чем перестать пытаться. В гонке за сокращением расходов существующей только в моем воображении компании, был найден следующий выход.

Конечно, кроме шуток, нужно отдавать себе отчет в том, что найти мощную, бесплатную и отказоустойчивую систему — утопия, но для организации работы на первых этапах, прежде чем усиливаться и переезжать на более мощные серверы, можно попробовать пойти по пути наименьшего сопротивления. Поэтому поступаем следующим образом: создадим бесплатную виртуальную машину и Objective storage с помощью Evolution free tier. Конфигурация следующая:

Для тестов и запуска первого проекта этого хватит с головой. А дальше всегда можно переместить программную инфраструктуру на более мощное железо и увеличить объем ресурсов. Ниже подробная инструкция о том, как и что делать.
Шаг 1. Разверните ресурсы в облаке
Создайте группу безопасности с названием crm-service и добавьте в нее правила.
Правило входящего трафика:
Протокол: TCP.
Порт: 443.
Тип источника: IP-адрес.
Источник: «ваш ip/32»
Правило входящего трафика:
Протокол: TCP.
Порт: 80.
Тип источника: IP‑адрес.
Источник: 0.0.0.0/0.
Правило исходящего трафика:
Протокол: Любой.
Тип адресата: IP‑адрес.
Адресат: 0.0.0.0/0.
Обращаю ваше внимание, в группах безопасности не указывайте 0.0.0.0/0, иначе весь интернет будет ломиться на ваши порты, воспользуйтесь сервисом и укажите личный ip‑адрес. Также рекомендую сразу настраивать личный домен.
На странице Сети → Группы безопасности убедитесь, что отображается группа безопасности crm-service со статусом Создана.
Создайте бесплатную виртуальную машину со следующими параметрами:
Название: crm-service.
Образ: публичный образ Ubuntu 22.04.
Подключить публичный IP: оставьте опцию включенной.
Тип IP: оставьте прямой IP-адрес.
Группы безопасности: SSH-access_ru.AZ-1 и crm-service.
Логин: crm.
Метод аутентификации: Публичный ключ и Пароль.
Публичный ключ: укажите ключ, созданный ранее.
Пароль: задайте пароль.
Имя хоста: crm-service.
На странице Инфраструктура → Виртуальные машины убедитесь, что отображается виртуальная машина crm-service со статусом Запущена.
Создайте бакет в Object Storage со следующими параметрами
Название: crm-service.
Максимальный размер: 15 ГБ.
Класс хранения по умолчанию: Стандартный.
Перейдите в раздел Object Storage API. Сохраните значения ID тенанта и Регион.
Создайте сервисный аккаунт со следующими параметрами:
Название: crm-service.
Описание: Аккаунт Object Storage.
Проект: Пользователь сервисов.
Evolution Object Storage Роли: s3e.viewer, s3e.editor.
Сгенерируйте ключи доступа для сервисного аккаунта. Сохраните Secret ID и Secret Key.
Шаг 2. Настройте окружение на виртуальной машине
Подключитесь к виртуальной машине crm-service через серийную консоль или по SSH.
Обновите систему и установите необходимые зависимости:
sudo apt update && sudo apt upgrade -y &&\ sudo apt install -y curl apt-transport-https\ ca-certificates\ software-properties-common\ gnupg2\ lsb-release
Установите Docker:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update sudo apt install docker-ce docker-ce-cli containerd.io -y
Дайте текущему пользователю права на запуск Docker:
sudo usermod -aG docker $USER newgrp docker
Установите Docker Compose:
sudo apt-get install docker-compose-plugin -y
Проверьте, что Docker и Docker Compose установлены корректно:
docker --version docker compose version
Установите сервер nginx:
sudo apt install nginx -y sudo systemctl start nginx sudo systemctl enable nginx
Установите Let’s Encrypt и плагин для nginx:
sudo apt install certbot python3-certbot-nginx -y
Шаг 3. Настройте nginx и HTTPS
Настройте межсетевой экран:
sudo ufw allow OpenSSH sudo ufw allow 'Nginx Full' sudo ufw enable
Создайте конфигурационный файл:
sudo nano /etc/nginx/sites-available/crm.conf
Вставьте конфигурацию, заменив <IP-ADDRESS> на IP-адрес вашей виртуальной машины:
server { listen 80; server_name crm.<IP-ADDRESS>.nip.io www.crm.<IP-ADDRESS>.nip.io; # Proxy all other requests to Twenty CRM location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; proxy_read_timeout 300; proxy_connect_timeout 300; proxy_send_timeout 300; } }
Примените конфигурацию и перезапустите nginx:
sudo ln -sf /etc/nginx/sites-available/crm.conf /etc/nginx/sites-enabled/crm.conf sudo rm -f /etc/nginx/sites-enabled/default sudo nginx -t sudo systemctl reload nginx
Проверьте, что nginx работает:
sudo systemctl status nginx
Cервис nginx должен быть в статусе active (running).
Перейдите по адресу http://crm.<IP-ADDRESS>.nip.io. Откроется страница с текстом «502 Bad Gateway».
Запустите команду для выпуска SSL-сертификата:
sudo certbot --nginx -d crm.<IP-ADDRESS>.nip.io --redirect --agree-tos -m <EMAIL>
Где:
<IP-ADDRESS> — IP-адрес вашей виртуальной машины.
<EMAIL> — email для регистрации сертификата.
После выпуска сертификата перейдите по адресу https://crm.<IP-ADDRESS>.nip.io. Откроется страница с текстом «502 Bad Gateway». В свойствах сайта браузер отметит соединение как безопасное.
Шаг 4. Разверните серверное приложение Twenty CRM с помощью Docker Compose
Создайте структуру проекта:
mkdir ~/twenty-crm cd ~/twenty-crm
Сгенерируйте уникальный ключ и сохраните его, он понадобится в дальнейшем:
openssl rand -base64 32
Сгенерируйте пароль для базы данных и сохраните его, он понадобится в дальнейшем:
openssl rand -base64 15
Создайте файл docker-compose.yml:
nano docker-compose.yml
Вставьте код:
Длинный код
name: twenty services: server: image: twentycrm/twenty:${TAG:-latest} volumes: - server-local-data:/app/packages/twenty-server/.local-storage ports: - "3000:3000" environment: NODE_PORT: 3000 PG_DATABASE_URL: postgres://${PG_DATABASE_USER:-postgres}:${PG_DATABASE_PASSWORD:-postgres}@${PG_DATABASE_HOST:-db}:${PG_DATABASE_PORT:-5432}/default SERVER_URL: ${SERVER_URL} REDIS_URL: ${REDIS_URL:-redis://redis:6379} DISABLE_DB_MIGRATIONS: ${DISABLE_DB_MIGRATIONS} DISABLE_CRON_JOBS_REGISTRATION: ${DISABLE_CRON_JOBS_REGISTRATION} STORAGE_TYPE: ${STORAGE_TYPE} STORAGE_S3_REGION: ${STORAGE_S3_REGION} STORAGE_S3_NAME: ${STORAGE_S3_NAME} STORAGE_S3_ENDPOINT: ${STORAGE_S3_ENDPOINT} STORAGE_S3_ACCESS_KEY_ID: ${STORAGE_S3_ACCESS_KEY_ID} STORAGE_S3_SECRET_ACCESS_KEY: ${STORAGE_S3_SECRET_ACCESS_KEY} APP_SECRET: ${APP_SECRET:-replace_me_with_a_random_string} # MESSAGING_PROVIDER_GMAIL_ENABLED: ${MESSAGING_PROVIDER_GMAIL_ENABLED} # CALENDAR_PROVIDER_GOOGLE_ENABLED: ${CALENDAR_PROVIDER_GOOGLE_ENABLED} # AUTH_GOOGLE_CLIENT_ID: ${AUTH_GOOGLE_CLIENT_ID} # AUTH_GOOGLE_CLIENT_SECRET: ${AUTH_GOOGLE_CLIENT_SECRET} # AUTH_GOOGLE_CALLBACK_URL: ${AUTH_GOOGLE_CALLBACK_URL} # AUTH_GOOGLE_APIS_CALLBACK_URL: ${AUTH_GOOGLE_APIS_CALLBACK_URL} # CALENDAR_PROVIDER_MICROSOFT_ENABLED: ${CALENDAR_PROVIDER_MICROSOFT_ENABLED} # MESSAGING_PROVIDER_MICROSOFT_ENABLED: ${MESSAGING_PROVIDER_MICROSOFT_ENABLED} # AUTH_MICROSOFT_ENABLED: ${AUTH_MICROSOFT_ENABLED} # AUTH_MICROSOFT_CLIENT_ID: ${AUTH_MICROSOFT_CLIENT_ID} # AUTH_MICROSOFT_CLIENT_SECRET: ${AUTH_MICROSOFT_CLIENT_SECRET} # AUTH_MICROSOFT_CALLBACK_URL: ${AUTH_MICROSOFT_CALLBACK_URL} # AUTH_MICROSOFT_APIS_CALLBACK_URL: ${AUTH_MICROSOFT_APIS_CALLBACK_URL} # EMAIL_FROM_ADDRESS: ${EMAIL_FROM_ADDRESS:-contact@yourdomain.com} # EMAIL_FROM_NAME: ${EMAIL_FROM_NAME:-"John from YourDomain"} # EMAIL_SYSTEM_ADDRESS: ${EMAIL_SYSTEM_ADDRESS:-system@yourdomain.com} # EMAIL_DRIVER: ${EMAIL_DRIVER:-smtp} # EMAIL_SMTP_HOST: ${EMAIL_SMTP_HOST:-smtp.gmail.com} # EMAIL_SMTP_PORT: ${EMAIL_SMTP_PORT:-465} # EMAIL_SMTP_USER: ${EMAIL_SMTP_USER:-} # EMAIL_SMTP_PASSWORD: ${EMAIL_SMTP_PASSWORD:-} depends_on: db: condition: service_healthy healthcheck: test: curl --fail http://localhost:3000/healthz interval: 5s timeout: 5s retries: 20 restart: always worker: image: twentycrm/twenty:${TAG:-latest} volumes: - server-local-data:/app/packages/twenty-server/.local-storage command: ["yarn", "worker:prod"] environment: PG_DATABASE_URL: postgres://${PG_DATABASE_USER:-postgres}:${PG_DATABASE_PASSWORD:-postgres}@${PG_DATABASE_HOST:-db}:${PG_DATABASE_PORT:-5432}/default SERVER_URL: ${SERVER_URL} REDIS_URL: ${REDIS_URL:-redis://redis:6379} DISABLE_DB_MIGRATIONS: "true" DISABLE_CRON_JOBS_REGISTRATION: "true" STORAGE_TYPE: ${STORAGE_TYPE} STORAGE_S3_REGION: ${STORAGE_S3_REGION} STORAGE_S3_NAME: ${STORAGE_S3_NAME} STORAGE_S3_ENDPOINT: ${STORAGE_S3_ENDPOINT} STORAGE_S3_ACCESS_KEY_ID: ${STORAGE_S3_ACCESS_KEY_ID} STORAGE_S3_SECRET_ACCESS_KEY: ${STORAGE_S3_SECRET_ACCESS_KEY} APP_SECRET: ${APP_SECRET:-replace_me_with_a_random_string} # MESSAGING_PROVIDER_GMAIL_ENABLED: ${MESSAGING_PROVIDER_GMAIL_ENABLED} # CALENDAR_PROVIDER_GOOGLE_ENABLED: ${CALENDAR_PROVIDER_GOOGLE_ENABLED} # AUTH_GOOGLE_CLIENT_ID: ${AUTH_GOOGLE_CLIENT_ID} # AUTH_GOOGLE_CLIENT_SECRET: ${AUTH_GOOGLE_CLIENT_SECRET} # AUTH_GOOGLE_CALLBACK_URL: ${AUTH_GOOGLE_CALLBACK_URL} # AUTH_GOOGLE_APIS_CALLBACK_URL: ${AUTH_GOOGLE_APIS_CALLBACK_URL} # CALENDAR_PROVIDER_MICROSOFT_ENABLED: ${CALENDAR_PROVIDER_MICROSOFT_ENABLED} # MESSAGING_PROVIDER_MICROSOFT_ENABLED: ${MESSAGING_PROVIDER_MICROSOFT_ENABLED} # AUTH_MICROSOFT_ENABLED: ${AUTH_MICROSOFT_ENABLED} # AUTH_MICROSOFT_CLIENT_ID: ${AUTH_MICROSOFT_CLIENT_ID} # AUTH_MICROSOFT_CLIENT_SECRET: ${AUTH_MICROSOFT_CLIENT_SECRET} # AUTH_MICROSOFT_CALLBACK_URL: ${AUTH_MICROSOFT_CALLBACK_URL} # AUTH_MICROSOFT_APIS_CALLBACK_URL: ${AUTH_MICROSOFT_APIS_CALLBACK_URL} # EMAIL_FROM_ADDRESS: ${EMAIL_FROM_ADDRESS:-contact@yourdomain.com} # EMAIL_FROM_NAME: ${EMAIL_FROM_NAME:-"John from YourDomain"} # EMAIL_SYSTEM_ADDRESS: ${EMAIL_SYSTEM_ADDRESS:-system@yourdomain.com} # EMAIL_DRIVER: ${EMAIL_DRIVER:-smtp} # EMAIL_SMTP_HOST: ${EMAIL_SMTP_HOST:-smtp.gmail.com} # EMAIL_SMTP_PORT: ${EMAIL_SMTP_PORT:-465} # EMAIL_SMTP_USER: ${EMAIL_SMTP_USER:-} # EMAIL_SMTP_PASSWORD: ${EMAIL_SMTP_PASSWORD:-} depends_on: db: condition: service_healthy server: condition: service_healthy restart: always db: image: postgres:16 volumes: - db-data:/var/lib/postgresql/data environment: POSTGRES_USER: ${PG_DATABASE_USER:-postgres} POSTGRES_PASSWORD: ${PG_DATABASE_PASSWORD:-postgres} healthcheck: test: pg_isready -U ${PG_DATABASE_USER:-postgres} -h localhost -d postgres interval: 5s timeout: 5s retries: 10 restart: always redis: image: redis restart: always command: [ "redis-server", "--maxmemory-policy", "noeviction" ] volumes: db-data: server-local-data:
Файл docker-compose.yml содержит закомментированные секции для включения интеграций с Google, Microsoft и email. Для настройки этих интеграций, раскомментируйте необходимые параметры и добавьте значения в файл .env. Подробнее — в документации Twenty CRM.
Создайте файл .env:
nano .env
Вставьте код в файл:
TAG=<TAG> PG_DATABASE_USER=postgres PG_DATABASE_PASSWORD=<PG_DATABASE_PASSWORD> PG_DATABASE_HOST=db PG_DATABASE_PORT=5432 REDIS_URL=redis://redis:6379 SERVER_URL=https://crm.<IP-ADDRESS>.nip.io # Use openssl rand -base64 32 for each secret APP_SECRET=<APP_SECRET> STORAGE_TYPE=s3 STORAGE_S3_NAME=<OBJECT-STORAGE-NAME> STORAGE_S3_REGION=<REGION> STORAGE_S3_ENDPOINT=https://s3.cloud.ru STORAGE_S3_ACCESS_KEY_ID=<TENANT_ID>:<SECRET_KEY_ID> STORAGE_S3_SECRET_ACCESS_KEY=<SECRET_KEY> STORAGE_S3_FORCE_PATH_STYLE=true
Где:
<TAG> — тeг docker-образа Twenty CRM. Для этой лабораторной работы используйте значение v1.3.0. Другие теги могут требовать иной конфигурации. Актуальный список тегов доступен на странице docker-образа Twenty CRM.
<APP_SECRET> — уникальный ключ, сгенерированный ранее.
<PG_DATABASE_PASSWORD> — пароль от базы данных, сгенерированный ранее.
<IP-ADDRESS> — IP-адрес вашей виртуальной машины.
<OBJECT-STORAGE-NAME> — название бакета Object Storage.
<TENANT_ID> — ID тенанта сервиса Object Storage.
<REGION> — регион Object Storage.
<SECRET_KEY_ID>, <SECRET_KEY> — ID ключа и секретный ключ доступа к Object Storage.
<BUCKET_NAME> — название бакета Object Storage.
Запустите сервис:
docker compose up -d
Проверьте, что сервисы запущены:
docker compose ps
На компьютере в браузере откройте страницу https://crm.<IP-ADDRESS>.nip.io. Отобразится страница настройки Twenty CRM.
После того, как вы реализовали все этапы инструкции, проходим регистрацию.
1. Создаем рабочее пространство:

2.Создаем личный профиль:

3. Приглашаем коллег:

4. Попадаем в CRM и начинаем осваивать функционал:

Дальше все зависит от конкретных целей и задач пользователя. Система крайне гибкая и поддерживает интеграции с большим количеством разнообразных сервисов. Если что, подробности еще можно посмотреть в инструкции.
Например, я использую раздел Tasks, чтобы трекать свои дневные задачи:

Можно настроить связанность задач, канбан-доску, можно приложить файлы к задаче, назначить ответственных и настроить прочий полезный базовый минимум. Что простому обывателю поможет уйти от платных приложений по тайм-менеджменту в более функциональную и бесплатную сторону, а предпринимателям — предоставит кучу инструментов для организации полного цикла работы с клиентом и внутренней командой.
Поля гибко настраиваются, что помогает вести базу контактов контрагентов и удобно хранить основную информацию о них:

Сервис Notes позволяет вести и хранить накапливаемую информацию в удобном формате:

Opportunities — воронка, по совместительству отличная штука для того чтобы трекать свой прогресс по разнообразным жизненным задачам, если вы как и я решите использовать данную систему в личных целях:

Workflows — для настройки всякого рода автоматизации. Этот раздел заслуживает отдельной статьи, надеюсь найдутся энтузиасты, которые раскроют весь потенциал этого инструмента.

Профиль и рабочее пространство настраивается максимально юзерфрендли, но при этом гибко:

Теперь у вас есть необходимый задел для дальнейшего изучения функциональности и настройки собственной или корпоративной CRM-системы. Желаю успехов)

