在 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 运行环境及相关实战
为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)