Настройка и развёртывание серверов криптобиржи: техническое руководство по запуску
DevOps Развёртывание Сервер

Настройка и развёртывание серверов криптобиржи: техническое руководство по запуску

C
Codono Team
| · Updated March 10, 2026 | 15 min read

Содержание

Это руководство предназначено для системных администраторов, DevOps-инженеров и CTO, которые уже приняли бизнес-решение о запуске биржи и теперь нуждаются в плане развёртывания. Если вы ещё оцениваете бизнес-сторону вопроса — лицензирование, расходы, модели монетизации — сначала прочитайте бизнес-план криптобиржи или полное руководство для старта.

Здесь мы разберём каждый технический шаг: от подготовки «голого» сервера до production-готовой биржи, обрабатывающей реальные сделки и реальные деньги.

Перед началом работы

Убедитесь, что у вас есть:

  • Лицензионная копия биржевого ПО Codono с полным доступом к исходному коду
  • Root-доступ по SSH к вашему серверу (или серверам)
  • Зарегистрированный домен с управлением DNS
  • SSL-сертификаты (или план использовать Let’s Encrypt)
  • Учётные данные для выбранного KYC-провайдера (SumSub или аналогичного)

Инструкции ниже предполагают Ubuntu 22.04 LTS. Codono также поддерживает CentOS/RHEL и Debian, но названия пакетов могут отличаться.

Обзор серверной архитектуры

Production-криптобиржа — это не один сервер. Как минимум, планируйте такую топологию:

СерверРольМинимальные характеристики
Сервер приложенийNginx + PHP-FPM + код приложения8 vCPU, 32 ГБ ОЗУ, 200 ГБ NVMe
Сервер базы данныхMySQL 8.0 primary16 vCPU, 64 ГБ ОЗУ, 500 ГБ NVMe RAID-10
Сервер кэша/очередейRedis 7.x4 vCPU, 16 ГБ ОЗУ
WebSocket-серверЛенты данных в реальном времени4 vCPU, 8 ГБ ОЗУ
Сервер(ы) кошельковДемоны блокчейнов (bitcoind, geth и т. д.)8 vCPU, 32 ГБ ОЗУ, 1 ТБ+ SSD на каждую сеть

Для биржи малого и среднего размера (до 5 000 одновременных пользователей) можно объединить приложение + WebSocket на одном сервере, а кэш + очереди — на другом. Никогда не совмещайте базу данных или демоны кошельков с чем-либо ещё.

Рекомендуемые провайдеры: Hetzner (лучшее соотношение цена/производительность в ЕС), OVH, AWS EC2 (если нужна мультирегиональность), DigitalOcean. Избегайте виртуального хостинга.

Шаг 1: Подготовка и защита серверов

Начните с чистой установки Ubuntu 22.04 LTS на каждом сервере.

Первичная защита:

# Update packages
apt update && apt upgrade -y

# Create a non-root deploy user
adduser deploy
usermod -aG sudo deploy

# Disable root SSH login
sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd

# Configure UFW firewall
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp    # SSH
ufw allow 80/tcp    # HTTP
ufw allow 443/tcp   # HTTPS
ufw enable

На серверах кошельков также ограничьте RPC-порты так, чтобы они принимали соединения только с внутреннего IP сервера приложений:

ufw allow from 10.0.0.2 to any port 8332  # Bitcoin RPC
ufw allow from 10.0.0.2 to any port 8545  # Ethereum RPC

Установите fail2ban для защиты от брутфорса:

apt install fail2ban -y
systemctl enable fail2ban

Настройте автоматическую установку обновлений безопасности:

apt install unattended-upgrades -y
dpkg-reconfigure --priority=low unattended-upgrades

Шаг 2: Установка веб-стека

На сервере приложений установите Nginx, PHP 8.2 и необходимые расширения:

# Nginx
apt install nginx -y

# PHP 8.2 + extensions required by Codono
apt install php8.2-fpm php8.2-mysql php8.2-redis php8.2-curl \
  php8.2-gd php8.2-mbstring php8.2-xml php8.2-zip php8.2-bcmath \
  php8.2-intl php8.2-soap php8.2-gmp -y

Разверните исходный код Codono:

mkdir -p /var/www/exchange
# Upload source code via rsync or git clone
rsync -avz ./codono-source/ deploy@app-server:/var/www/exchange/
chown -R www-data:www-data /var/www/exchange
chmod -R 755 /var/www/exchange
chmod -R 775 /var/www/exchange/runtime  # Writable cache dir

Шаг 3: Настройка Nginx как обратного прокси

Создайте основную конфигурацию сайта:

# /etc/nginx/sites-available/exchange.conf

upstream php-fpm {
    server unix:/run/php/php8.2-fpm.sock;
}

upstream websocket {
    server 127.0.0.1:9502;
}

server {
    listen 443 ssl http2;
    server_name exchange.example.com;

    root /var/www/exchange/public;
    index index.php;

    # SSL (see Step 9)
    ssl_certificate /etc/letsencrypt/live/exchange.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/exchange.example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;

    # Gzip
    gzip on;
    gzip_types text/plain application/json application/javascript text/css;
    gzip_min_length 1000;

    # Rate limiting zone (defined in nginx.conf)
    limit_req zone=api burst=20 nodelay;

    # Main application
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass php-fpm;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_read_timeout 30s;
    }

    # WebSocket proxy
    location /ws {
        proxy_pass http://websocket;
        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_read_timeout 86400s;
    }

    # Block sensitive paths
    location ~ /\.(git|env|htaccess) {
        deny all;
    }

    location ~ /(runtime|application|vendor) {
        deny all;
    }

    # Static asset caching
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
}

server {
    listen 80;
    server_name exchange.example.com;
    return 301 https://$host$request_uri;
}

Добавьте зону ограничения частоты запросов в /etc/nginx/nginx.conf внутри блока http:

limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

Включите конфигурацию и проверьте её:

ln -s /etc/nginx/sites-available/exchange.conf /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

Шаг 4: Настройка PHP-FPM

Отредактируйте /etc/php/8.2/fpm/pool.d/www.conf под production-нагрузки:

; Process management
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 1000

; Timeouts
request_terminate_timeout = 30s

; Logging
slowlog = /var/log/php-fpm-slow.log
request_slowlog_timeout = 5s

Отредактируйте /etc/php/8.2/fpm/php.ini под специфику биржи:

memory_limit = 256M
max_execution_time = 30
upload_max_filesize = 10M
post_max_size = 12M
opcache.enable = 1
opcache.memory_consumption = 256
opcache.max_accelerated_files = 20000
opcache.validate_timestamps = 0   ; Set to 1 during development
session.gc_maxlifetime = 7200

Перезапустите PHP-FPM:

systemctl restart php8.2-fpm

Ключевой момент: установка opcache.validate_timestamps = 0 в production означает, что после каждого деплоя кода нужно выполнять systemctl restart php8.2-fpm. Это даёт значительный прирост производительности, потому что PHP не выполняет проверку stat файлов при каждом запросе.

Шаг 5: Установка и настройка базы данных MySQL

На сервере базы данных установите MySQL 8.0:

apt install mysql-server-8.0 -y
mysql_secure_installation

Создайте базу данных биржи и пользователя:

CREATE DATABASE exchange_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'exchange_user'@'10.0.0.%' IDENTIFIED BY 'strong_random_password';
GRANT ALL PRIVILEGES ON exchange_db.* TO 'exchange_user'@'10.0.0.%';
FLUSH PRIVILEGES;

Отредактируйте /etc/mysql/mysql.conf.d/mysqld.cnf под нагрузки биржи:

[mysqld]
# InnoDB tuning (assuming 64 GB RAM server)
innodb_buffer_pool_size = 40G
innodb_buffer_pool_instances = 8
innodb_log_file_size = 2G
innodb_flush_log_at_trx_commit = 1
innodb_flush_method = O_DIRECT
innodb_io_capacity = 2000
innodb_io_capacity_max = 4000

# Connection handling
max_connections = 500
thread_cache_size = 50
table_open_cache = 4000

# Query cache (disabled in MySQL 8, use Redis instead)
# query_cache_type = 0

# Slow query logging
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1

# Network
bind-address = 10.0.0.3    # Internal IP only
max_allowed_packet = 64M

# Binary logging for replication
log_bin = mysql-bin
server-id = 1
binlog_expire_logs_seconds = 604800

Импортируйте схему базы данных Codono:

mysql -u exchange_user -p exchange_db < /var/www/exchange/database/schema.sql

Совет по производительности: innodb_buffer_pool_size должен составлять 60-70% от общего объёма ОЗУ сервера. Это самый важный параметр настройки MySQL для биржи, поскольку таблицы стакана, балансов и истории сделок интенсивно используются на чтение и запись.

Шаг 6: Настройка кэша и очередей Redis

На сервере кэша установите Redis 7:

apt install redis-server -y

Отредактируйте /etc/redis/redis.conf:

bind 10.0.0.4              # Internal IP
maxmemory 8gb
maxmemory-policy allkeys-lru
save 900 1                  # RDB snapshots
save 300 10
appendonly yes              # AOF for durability

Codono использует Redis для:

  • Хранения сессий — быстрее, чем сессии в MySQL, и поддерживает горизонтальное масштабирование серверов приложений
  • Слоя кэширования — цены монет, данные тикеров, конфигурации торговых пар
  • Бэкенда очередей — обработка выводов, отправка писем, колбэки KYC
  • Pub/Sub — обновления стакана и сделок в реальном времени, передаваемые WebSocket-серверу

Проверьте связь с сервера приложений:

redis-cli -h 10.0.0.4 ping
# Should return: PONG

Шаг 7: Развёртывание демонов кошельков

Это самая сложная часть. Каждому поддерживаемому блокчейну нужен собственный демон, запущенный на сервере кошельков.

Bitcoin (bitcoind)

# Install
wget https://bitcoincore.org/bin/bitcoin-core-27.0/bitcoin-27.0-x86_64-linux-gnu.tar.gz
tar xzf bitcoin-27.0-x86_64-linux-gnu.tar.gz
cp bitcoin-27.0/bin/* /usr/local/bin/

Настройте /home/bitcoin/.bitcoin/bitcoin.conf:

server=1
rpcuser=exchange_btc
rpcpassword=strong_random_rpc_password
rpcallowip=10.0.0.2/32
rpcbind=10.0.0.5
txindex=1
maxconnections=50
dbcache=4096

Ethereum (geth)

apt install -y software-properties-common
add-apt-repository -y ppa:ethereum/ethereum
apt install geth -y

Запуск в виде systemd-сервиса:

geth --http --http.addr 10.0.0.5 --http.port 8545 \
  --http.api eth,net,web3,personal \
  --http.corsdomain "*" \
  --http.vhosts "10.0.0.5" \
  --syncmode snap \
  --datadir /data/ethereum \
  --maxpeers 50

Другие сети

Повторите эту схему для каждого поддерживаемого блокчейна. Codono поддерживает более 50 сетей — конфигурации для конкретных демонов смотрите в документации по интеграции блокчейнов. Популярные сети для запуска:

  • BNB Chain (нода BSC или RPC-эндпоинт)
  • Tron (полная нода java-tron)
  • Solana (solana-validator или RPC-эндпоинт)
  • Polygon (bor + heimdall или RPC-эндпоинт)

Разделение горячего и холодного кошельков: настройте кошельковую систему биржи так, чтобы в горячем кошельке оставалось только 5-10% от общего объёма депозитов. Остальное перемещается на адреса холодного хранения, защищённые мультиподписью. Админ-панель Codono предоставляет пороговые оповещения и инструменты ручного пополнения горячего кошелька из холодного.

Шаг 8: Настройка WebSocket-сервера

Ленты цен в реальном времени, обновления стакана и уведомления о сделках требуют WebSocket-соединений. Codono включает WebSocket-сервер на базе Swoole.

Установите Swoole:

pecl install swoole
echo "extension=swoole.so" > /etc/php/8.2/cli/conf.d/20-swoole.ini

Запустите WebSocket-сервер:

cd /var/www/exchange
php artisan websocket:serve --host=0.0.0.0 --port=9502

Создайте systemd-сервис для автоматического перезапуска:

# /etc/systemd/system/exchange-ws.service
[Unit]
Description=Exchange WebSocket Server
After=network.target redis.service

[Service]
User=www-data
WorkingDirectory=/var/www/exchange
ExecStart=/usr/bin/php artisan websocket:serve --host=0.0.0.0 --port=9502
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Включите и запустите:

systemctl enable exchange-ws
systemctl start exchange-ws

WebSocket-сервер подписывается на каналы Redis pub/sub. Когда исполняется сделка или меняется стакан, матчинговый движок публикует обновление в Redis, а WebSocket-сервер рассылает его всем подключённым клиентам за миллисекунды.

Шаг 9: Настройка SSL/TLS и домена

Используйте Let’s Encrypt для бесплатных сертификатов с автопродлением:

apt install certbot python3-certbot-nginx -y
certbot --nginx -d exchange.example.com -d www.exchange.example.com

Проверьте автопродление:

certbot renew --dry-run

DNS-записи для настройки:

ЗаписьТипЗначение
exchange.example.comAПубличный IP сервера приложений
www.exchange.example.comCNAMEexchange.example.com
api.exchange.example.comAПубличный IP сервера приложений (если используется отдельный поддомен API)

Заголовки безопасности — добавьте в server-блок Nginx:

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

Шаг 10: Задачи cron и фоновые воркеры

Codono требует несколько запланированных задач. Добавьте их в crontab пользователя www-data:

crontab -u www-data -e
# Process pending withdrawals (every 2 minutes)
*/2 * * * * php /var/www/exchange/artisan queue:withdrawal

# Update coin prices from market data (every minute)
* * * * * php /var/www/exchange/artisan market:prices

# Process deposit confirmations (every minute)
* * * * * php /var/www/exchange/artisan wallet:deposits

# Clean expired orders (every 5 minutes)
*/5 * * * * php /var/www/exchange/artisan orders:cleanup

# Generate daily reports (daily at midnight UTC)
0 0 * * * php /var/www/exchange/artisan reports:daily

# Database backup (daily at 3 AM UTC)
0 3 * * * /usr/local/bin/exchange-backup.sh

# SSL certificate renewal check (twice daily)
0 */12 * * * certbot renew --quiet --post-hook "systemctl reload nginx"

Для воркеров очередей, которые должны работать непрерывно (email-уведомления, колбэки KYC), используйте Supervisor:

apt install supervisor -y
# /etc/supervisor/conf.d/exchange-worker.conf
[program:exchange-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/exchange/artisan queue:work redis --tries=3 --timeout=90
autostart=true
autorestart=true
numprocs=4
user=www-data
redirect_stderr=true
stdout_logfile=/var/log/exchange-worker.log
supervisorctl reread && supervisorctl update

Шаг 11: Мониторинг и оповещения

Production-бирже нужны три уровня мониторинга:

Мониторинг инфраструктуры (Prometheus + Grafana)

Установите node_exporter на каждый сервер. Отслеживайте:

  • Загрузку CPU (оповещение при устойчивом превышении 80%)
  • Использование ОЗУ (оповещение выше 85%)
  • Дисковый I/O и свободное место (оповещение ниже 20%)
  • Пропускную способность сети и потери пакетов

Мониторинг приложения

  • Статус пула PHP-FPM (pm.status_path = /fpm-status)
  • Nginx stub_status для активных соединений
  • Количество медленных запросов MySQL в час
  • Использование памяти Redis и количество ключей
  • Глубину очереди (количество ожидающих задач должно держаться около нуля)

Мониторинг кошельков (критически важен)

  • Баланс горячего кошелька по каждой монете (оповещение при падении ниже порога)
  • Количество ожидающих депозитов (резкий рост указывает на проблемы с синхронизацией демона)
  • Количество ожидающих выводов (резкий рост указывает на сбой обработки)
  • Высота блока демона по сравнению с высотой сети (оповещение при отставании более чем на 10 блоков)

Каналы оповещений: PagerDuty или Opsgenie для критических оповещений (кошельки, падение базы данных), Slack или Telegram для предупреждений (высокая загрузка CPU, медленные запросы). Админ-панель также показывает состояние системы в реальном времени.

Шаг 12: Резервное копирование и аварийное восстановление

Резервное копирование базы данных

#!/bin/bash
# /usr/local/bin/exchange-backup.sh
DATE=$(date +%Y%m%d_%H%M)
BACKUP_DIR=/backup/mysql

mysqldump --single-transaction --routines --triggers \
  -u backup_user -p exchange_db | gzip > $BACKUP_DIR/exchange_$DATE.sql.gz

# Retain 30 days
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete

# Sync to offsite storage
aws s3 sync $BACKUP_DIR s3://exchange-backups/mysql/ --storage-class STANDARD_IA

Резервное копирование кошельков

  • Bitcoin: сохраняйте wallet.dat в зашифрованное внешнее хранилище после генерации каждого нового адреса
  • Ethereum: сохраняйте каталог keystore
  • Seed-фразы холодных кошельков храните в географически разнесённых огнестойких сейфах

Целевые показатели восстановления

КомпонентRPO (потеря данных)RTO (время простоя)
База данных1 час30 минут
Приложение0 (stateless, повторный деплой из исходников)10 минут
Демоны кошельков0 (повторная синхронизация из блокчейна)2-24 часа (зависит от сети)

Настройте репликацию MySQL на резервный сервер для RPO, близкого к нулю. Тестируйте переключение на резерв ежеквартально.

Шаг 13: Нагрузочное тестирование

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

# Install k6
apt install k6 -y

# Test login endpoint
k6 run --vus 100 --duration 60s login-test.js

# Test order placement
k6 run --vus 50 --duration 120s order-test.js

# Test WebSocket connections
k6 run --vus 500 --duration 60s ws-test.js

Базовые целевые показатели для production-биржи:

ЭндпоинтЦелевое значениеПриемлемое
Ответ API (размещение ордера)<100 мс p95<200 мс p99
Задержка WebSocket-сообщений<50 мс<100 мс
Загрузка страницы (торговый интерфейс)<2 с<3 с
Одновременные WebSocket-соединения5 000+2 000+
Ордеров в секунду (матчинговый движок)1 000+500+

Если какой-либо эндпоинт превышает пороговые значения, проведите профилирование с помощью php-fpm-slow.log, лога медленных запросов MySQL или EXPLAIN для «горячих» запросов — прежде чем наращивать железо.

Шаг 14: Чек-лист запуска

Пройдите этот чек-лист перед открытием регистрации:

Инфраструктура:

  • Все серверы защищены (только SSH-ключи, правила файрвола, fail2ban)
  • SSL-сертификаты установлены, автопродление проверено
  • Распространение DNS завершено
  • Защита от DDoS активна (Cloudflare или аналог)
  • Скрипты резервного копирования работают и проверены тестовым восстановлением

Приложение:

  • Конфигурация окружения переведена в production (debug выключен, отображение ошибок выключено)
  • OPcache включён, validate_timestamps выключен
  • Все чувствительные пути заблокированы в Nginx (.git, .env, runtime/)
  • Заголовки безопасности настроены
  • Ограничение частоты запросов активно на API-эндпоинтах
  • CORS настроен только для вашего домена

Кошельки:

  • Все демоны кошельков синхронизированы до актуальной высоты блока
  • Горячий кошелёк пополнен начальными операционными балансами
  • Адреса холодных кошельков сгенерированы, ключи надёжно хранятся офлайн
  • Генерация депозитных адресов протестирована для каждой монеты
  • Поток вывода средств протестирован end-to-end для каждой монеты
  • Настроены пороги и оповещения для горячего кошелька

Торговля:

  • Торговые пары настроены с правильной точностью цен
  • Установлены тарифы комиссий (ставки maker/taker)
  • Матчинговый движок протестирован с симулированными ордерами
  • Глубина стакана отображается корректно
  • WebSocket-ленты транслируют данные в реальном времени

Комплаенс:

  • KYC-провайдер интегрирован и протестирован
  • Настроены уровни верификации
  • Применяются лимиты вывода по уровням
  • Активен AML-мониторинг транзакций

Мониторинг:

  • Все дашборды работают в Grafana
  • Каналы оповещений настроены и протестированы (отправьте тестовое оповещение)
  • Установлено дежурное расписание (on-call)

Эксплуатация после запуска

Первые 30 дней после запуска требуют пристального внимания:

Ежедневные задачи:

  • Проверяйте балансы горячих кошельков по всем сетям
  • Контролируйте очередь ожидающих выводов (должна очищаться за считанные минуты)
  • Отслеживайте логи ошибок на предмет новых паттернов
  • Просматривайте лог медленных запросов для поиска возможностей оптимизации

Еженедельные задачи:

  • Проверяйте целостность резервных копий (тестовое восстановление на staging)
  • Просматривайте логи безопасности (неудачные входы, заблокированные IP)
  • Обновляйте ПО демонов кошельков при выходе новых версий
  • Анализируйте паттерны нагрузки PHP-FPM и Nginx для планирования мощностей

Триггеры масштабирования:

  • PHP-FPM max_children постоянно на пределе → добавьте сервер приложений за балансировщиком нагрузки
  • CPU MySQL устойчиво выше 70% → добавьте реплики на чтение или обновите железо
  • Память Redis выше 80% → увеличьте maxmemory или добавьте узлы кластера
  • WebSocket-сервер выше 3 000 одновременных соединений → добавьте второй WS-узел с Redis pub/sub

Это руководство охватывает техническое развёртывание. О бизнес-стороне — лицензировании, расходах, моделях монетизации и стратегии выхода на рынок — читайте в бизнес-плане криптобиржи. Полный обзор процесса от начала до конца смотрите в статье как запустить криптобиржу.

Готовы к развёртыванию? Запросите живое демо, чтобы протестировать весь стек, ознакомьтесь с ценами на варианты лицензий или свяжитесь с командой для поддержки при развёртывании.

DevOps Развёртывание Сервер Биржа Технические статьи
C

Codono Team

Codono builds enterprise-grade crypto exchange software deployed by 250+ operators across 40+ countries. Our team writes from production experience running spot, derivatives, custody, and compliance at scale.

View all posts by Codono Team →

Build Your Exchange with Codono

Complete crypto exchange software with spot, futures, P2P, and 15+ blockchains.