在 Linux Ubuntu 操作系统安装 nofx 量化开源项目

tinkle-community/nofx, AI-powered Binance futures trading bot with DeepSeek/Qwen, featuring multi-AI competition, Sharpe ratio self-evolution, and real-time dashboard

一、开发环境

1、环境准备

环境要求:

  • Go 1.21+
  • Node.js 18+
  • TA-Lib 库(技术指标计算)

Ubuntu/Debian:

sudo apt-get install libta-lib0-dev

安装Ta-lib库

# 1、先安装编译环境和常用工具:
sudo apt update
sudo apt install -y build-essential wget python3-dev

# 下载并编译安装 TA-Lib C 库
cd /usr/local/src
sudo wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz
sudo tar -xzf ta-lib-0.4.0-src.tar.gz
cd ta-lib
sudo ./configure --prefix=/usr/local
sudo make
sudo make install

# 配置系统动态库路径, 执行以下命令,让系统能找到 TA-Lib 动态库:
echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/ta-lib.conf
sudo ldconfig

# 如果是Python环境,执行以下命令,这里是Go环境,就不执行了
#pip install ta-lib

# 验证安装环境
(base) ubuntu@AwesomeStrategy-Freqtrade:/usr/local/include$ ls /usr/local/lib | grep ta_lib
libta_lib.a
libta_lib.la
libta_lib.so
libta_lib.so.0
libta_lib.so.0.0.0
(base) ubuntu@AwesomeStrategy-Freqtrade:/usr/local/include$ 

2、克隆项目

cd /home/ubuntu/Code/
git clone https://github.com/tinkle-community/nofx.git
cd /home/ubuntu/Code/nofx

3、安装依赖

cd /home/ubuntu/Code/nofx
go mod download

前端:

cd web
npm install
cd ..

4、系统配置

步骤1:复制并重命名示例配置文件

cp config.json.example config.json

二、使用Docker 方式进行部署

1、Docker部署

Docker 部署比较简单,请参考官方文档,这里使用脚本快速部署:
快速开始:

cd /home/ubuntu/Code/nofx-dev/nofx
cp config.json.example config.json
sudo ./start.sh start --build

启动的服务:

ubuntu@dev:~/Code/nofx-dev/nofx$ sudo docker ps
CONTAINER ID   IMAGE                           COMMAND                  CREATED        STATUS                    PORTS                                         NAMES
b82b84b1369a   nofx-nofx-frontend              "/docker-entrypoint.…"   10 hours ago   Up 10 hours (healthy)     0.0.0.0:9070->80/tcp, [::]:9070->80/tcp       nofx-frontend
901798c1a28c   nofx-nofx                       "./nofx"                 10 hours ago   Up 10 hours (unhealthy)   0.0.0.0:9080->9080/tcp, [::]:9080->9080/tcp   nofx-trading

配置SSL 代理

由于网站配置部分做了严格的SSL 加密,所以,需要配置SSL证书访问,否则配置模型会报错:

下边在宿主机单独跑 Nginx,负责 SSL 和 80/443 的外部访问,然后反代到 Docker 内部前端和后端服务,不修改 nofx-frontend 容器自带的 Nginx。下面我给出完整方案,包括 docker-compose、宿主机 Nginx 配置、SSL 获取流程、端口规划

整体架构规划:

外网用户
     |
  HTTPS/HTTP(443/80)
     |
宿主机 Nginx (80/443 + SSL)
     |---> /api/ 反代 -> nofx backend:9080
     |---> /      反代 -> nofx-frontend:80
Docker 网络 (nofx-network)
     |-- nofx-frontend:80
     |-- nofx:9080

端口规划建议:

  • 前端容器仍用 80:80 或内部端口 9070:80 映射到宿主机 9070(避免宿主机 Nginx 冲突)
  • 后端容器 9080 保持不变
  • 宿主机 Nginx 监听 80/443,反代到容器的 9070/9080

②、先启动 NGINX 服务:
编辑 /etc/nginx/sites-available/tradingbit.ai

注释掉所有 SSL 相关配置(listen 443 ssl;、ssl_certificate、ssl_certificate_key 等行)

保留 HTTP 重定向或者简单前端反代即可,例如:

server {
    listen 80;
    server_name tradingbit.ai www.tradingbit.ai;

    location / {
        proxy_pass http://127.0.0.1:9070;
        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;
    }

    location /api/ {
        proxy_pass http://127.0.0.1:9080/api/;
        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;
    }
}

测试 Nginx 配置并重启

sudo nginx -t
sudo systemctl restart nginx

确保 HTTP 正常访问:

curl http://127.0.0.1

使用 Certbot 生成证书

sudo certbot --nginx -d tradingbit.ai -d www.tradingbit.ai

实际执行输出:

# 1、先启动本地的NGINX 服务(默认80端口,443 的先不用配置,自动生成的时候会添加)
# 2、然后再生成域名的SSL 证书;(如果未启动 NGINX ,则下边的命令会执行报错)
(base) ubuntu@dev:/etc/nginx/sites-available$ sudo certbot --nginx -d tradingbit.ai -d www.tradingbit.ai
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for tradingbit.ai and www.tradingbit.ai

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/tradingbit.ai/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/tradingbit.ai/privkey.pem
This certificate expires on 2026-02-13.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

Deploying certificate
Successfully deployed certificate for tradingbit.ai to /etc/nginx/sites-enabled/default
Successfully deployed certificate for www.tradingbit.ai to /etc/nginx/sites-enabled/default
Congratulations! You have successfully enabled HTTPS on https://tradingbit.ai and https://www.tradingbit.ai

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(base) ubuntu@AwesomeStrategy-Freqtrade:/etc/nginx/sites-available$ 

操作流程:
1. Certbot 会自动检测 Nginx 配置。
2. 自动修改 Nginx 配置,将 listen 443 ssl 添加到 server block。
3. 自动生成 SSL 证书:
    * 证书路径 /etc/letsencrypt/live/tradingbit.ai/fullchain.pem
    * 私钥 /etc/letsencrypt/live/tradingbit.ai/privkey.pem
4. 自动重启 Nginx。
如果出现报错 cannot load certificate "/etc/letsencrypt/live/tradingbit.ai/fullchain.pem",说明证书生成失败,常见原因:
* 80 端口未开放或被占用
* 域名未解析到本机公网 IP
* 防火墙阻挡端口 80

重新加载 Nginx

sudo nginx -t
sudo systemctl reload nginx

查看端口占用:

sudo lsof -i :80
sudo lsof -i :9070

如果生成没什么问题,就可以正常访问 https://demo.ai 了,当然前期是要在域名服务网站开启 @ A 的域名服务器映射(如 demo.ai 40.23.32.25 );

上边会新生成 NGINX 配置文件,在 etc/nginx/sites-enabled/default ,然后修改 NGINX 配置文件:

# 宿主机 NGINX 转发:
# sudo cat /etc/nginx/sites-enabled/default

# 修改 NGINX 配置
sudo vim /etc/nginx/sites-enabled/default

nnginx default 配置文件:

(base) ubuntu@AwesomeStrategy-Freqtrade:/var/log/nginx$ sudo cat /etc/nginx/sites-enabled/default
[sudo] password for ubuntu: 
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

# Default server configuration
#
#server {
#       listen 80 default_server;
#       listen [::]:80 default_server;
        #
        # SSL configuration
        #
        # listen 443 ssl default_server;
        # listen [::]:443 ssl default_server;
        #
        # Note: You should disable gzip for SSL traffic.
        # See: https://bugs.debian.org/773332
        #
        # Read up on ssl_ciphers to ensure a secure configuration.
        # See: https://bugs.debian.org/765782
        #
        # Self signed certs generated by the ssl-cert package
        # Don't use them in a production server!
        #
        # include snippets/snakeoil.conf;

#       root /var/www/html;

        # Add index.php to the list if you are using PHP
#       index index.html index.htm index.nginx-debian.html;

#       server_name _;

#       location / {
#               # First attempt to serve request as file, then
#               # as directory, then fall back to displaying a 404.
#               try_files $uri $uri/ =404;
#       }
        #
        # pass PHP scripts to FastCGI server
        #
        #location ~ \.php$ {
        #       include snippets/fastcgi-php.conf;
        #
        #       # With php-fpm (or other unix sockets):
        #       fastcgi_pass unix:/run/php/php7.4-fpm.sock;
        #       # With php-cgi (or other tcp sockets):
        #       fastcgi_pass 127.0.0.1:9000;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #       deny all;
        #}
#}

# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
#       listen 80;
#       listen [::]:80;
#
#       server_name example.com;
#
#       root /var/www/example.com;
#       index index.html;
#
#       location / {
#               try_files $uri $uri/ =404;
#       }
#}

server {

        # SSL configuration
        #
        # listen 443 ssl default_server;
        # listen [::]:443 ssl default_server;
        #
        # Note: You should disable gzip for SSL traffic.
        # See: https://bugs.debian.org/773332
        #
        # Read up on ssl_ciphers to ensure a secure configuration.
        # See: https://bugs.debian.org/765782
        #
        # Self signed certs generated by the ssl-cert package
        # Don't use them in a production server!
        #
        # include snippets/snakeoil.conf;

        root /var/www/html;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;
        server_name tradingbit.ai www.tradingbit.ai; # managed by Certbot

        location / {

                access_log /var/log/nginx/frontend_access.log;
                error_log  /var/log/nginx/frontend_error.log warn;
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                #try_files $uri $uri/ =404;
                proxy_pass http://127.0.0.1:9070;  # 前端容器
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_cache_bypass $http_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;
        }

        location /api/ {
          access_log /var/log/nginx/api_access.log;
          error_log  /var/log/nginx/api_error.log warn;

          proxy_pass http://127.0.0.1:9080/api/;  # 后端容器

          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection 'upgrade';
          proxy_set_header Host $host;
          proxy_cache_bypass $http_upgrade;
          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_connect_timeout 300s;
          proxy_send_timeout 300s;
          proxy_read_timeout 300s;

    }

    location /health {
        return 200 "OK\n";
        add_header Content-Type text/plain;
        access_log off;
    }

        # pass PHP scripts to FastCGI server
        #
        #location ~ \.php$ {
        #       include snippets/fastcgi-php.conf;
        #
        #       # With php-fpm (or other unix sockets):
        #       fastcgi_pass unix:/run/php/php7.4-fpm.sock;
        #       # With php-cgi (or other tcp sockets):
        #       fastcgi_pass 127.0.0.1:9000;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #       deny all;
        #}

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/tradingbit.ai/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/tradingbit.ai/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
    if ($host = www.tradingbit.ai) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    if ($host = tradingbit.ai) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

        listen 80 ;
        listen [::]:80 ;
    server_name tradingbit.ai www.tradingbit.ai;
    return 301 https://$host$request_uri;

}
(base) ubuntu@AwesomeStrategy-Freqtrade:/var/log/nginx$ 

配置好之后重启NGINX:

# sudo cat /etc/nginx/sites-enabled/default

# nginx 宿主机
sudo nginx -t

# 重新加载
sudo systemctl reload nginx

# 重启
sudo systemctl restart nginx

ssl证书自动续期

①、证书路径

在 nginx 中读取的证书位置:

/etc/letsencrypt/live/tradingbit.ai/fullchain.pem
/etc/letsencrypt/live/tradingbit.ai/privkey.pem

证书有效期 90 天,Certbot 一般推荐 30 天前自动续期。

②、certbot + nginx reload 脚本

创建脚本:

sudo vim /usr/local/bin/certbot_renew.sh

certbot_renew.sh 文件

#!/bin/bash

# Certbot 自动续期脚本
# 域名: tradingbit.ai

LOG_FILE="/var/log/certbot_renew.log"

echo "==============================" >> $LOG_FILE
echo "Run time: $(date)" >> $LOG_FILE

# 执行续期
certbot renew --quiet >> $LOG_FILE 2>&1

# 判断续期是否成功(检查时间戳是否更新)
if [ $? -eq 0 ]; then
    echo "Certbot renew OK. Reloading nginx..." >> $LOG_FILE
    systemctl reload nginx
else
    echo "Certbot renew FAILED!" >> $LOG_FILE
fi

echo "Done." >> $LOG_FILE
echo "" >> $LOG_FILE

赋予脚本执行权限

sudo chmod +x /usr/local/bin/certbot_renew.sh

使用 cron 定时任务执行:

sudo crontab -e

# 添加定时任务,表示每天凌晨 2 点自动续期。
0 2 * * 0 /usr/local/bin/certbot_renew.sh

手动测试:

sudo /usr/local/bin/certbot_renew.sh

# 查看证书更新日志
cat /var/log/certbot_renew.log

==============================
Run time: Sat Nov 15 10:16:46 PM CST 2025
Certbot renew OK. Reloading nginx...
Done.

相关文章:
NoFxAiOS/nofx开源AI量化交易项目
在 Linux Ubuntu 系统安装 Go 运行环境及相关实战

为者常成,行者常至