Merge pull request #40 from d0lwl0b/main

docs: modernize Docker Compose documentation to V2 syntax
This commit is contained in:
tinkle-community
2025-10-30 14:24:52 +08:00
committed by GitHub
16 changed files with 400 additions and 347 deletions

13
.env.example Normal file
View File

@@ -0,0 +1,13 @@
# NOFX Environment Variables Template
# Copy this file to .env and modify the values as needed
# Ports Configuration
# Backend API server port (internal: 8080, external: configurable)
NOFX_BACKEND_PORT=8080
# Frontend web interface port (Nginx listens on port 80 internally)
NOFX_FRONTEND_PORT=3000
# Timezone Setting
# System timezone for container time synchronization
NOFX_TIMEZONE=Asia/Shanghai

1
.gitignore vendored
View File

@@ -21,6 +21,7 @@ Thumbs.db
*.log *.log
*.tmp *.tmp
*.bak *.bak
*.backup
# 环境变量 # 环境变量
.env .env

View File

@@ -15,22 +15,33 @@ Before you begin, ensure your system has:
Download and install [Docker Desktop](https://www.docker.com/products/docker-desktop/) Download and install [Docker Desktop](https://www.docker.com/products/docker-desktop/)
#### Linux (Ubuntu/Debian) #### Linux (Ubuntu/Debian)
> #### Docker Compose Version Notes
>
> **New User Recommendation:**
> - **Use Docker Desktop**: Automatically includes latest Docker Compose, no separate installation needed
> - Simple installation, one-click setup, provides GUI management
> - Supports macOS, Windows, and some Linux distributions
>
> **Upgrading User Note:**
> - **Deprecating standalone docker-compose**: No longer recommended to download the independent Docker Compose binary
> - **Use built-in version**: Docker 20.10+ includes `docker compose` command (with space)
> - If still using old `docker-compose`, please upgrade to new syntax
*Recommended: Use Docker Desktop (if available) or Docker CE with built-in Compose*
```bash ```bash
# Install Docker # Install Docker (includes compose)
curl -fsSL https://get.docker.com -o get-docker.sh curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh sudo sh get-docker.sh
# Install Docker Compose # Add user to docker group
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# Add current user to docker group
sudo usermod -aG docker $USER sudo usermod -aG docker $USER
newgrp docker newgrp docker
# Verify installation # Verify installation (new command)
docker --version docker --version
docker-compose --version docker compose --version # Docker 24+ includes this, no separate installation needed
``` ```
## 🚀 Quick Start (3 Steps) ## 🚀 Quick Start (3 Steps)
@@ -69,10 +80,10 @@ nano config.json # or use any other editor
```bash ```bash
# Build and start all services (first run) # Build and start all services (first run)
docker-compose up -d --build docker compose up -d --build
# Subsequent starts (without rebuilding) # Subsequent starts (without rebuilding)
docker-compose up -d docker compose up -d
``` ```
**Startup options:** **Startup options:**
@@ -91,49 +102,49 @@ Once deployed, open your browser and visit:
### View Running Status ### View Running Status
```bash ```bash
# View all container status # View all container status
docker-compose ps docker compose ps
# View service health status # View service health status
docker-compose ps --format json | jq docker compose ps --format json | jq
``` ```
### View Logs ### View Logs
```bash ```bash
# View all service logs # View all service logs
docker-compose logs -f docker compose logs -f
# View backend logs only # View backend logs only
docker-compose logs -f backend docker compose logs -f backend
# View frontend logs only # View frontend logs only
docker-compose logs -f frontend docker compose logs -f frontend
# View last 100 lines # View last 100 lines
docker-compose logs --tail=100 docker compose logs --tail=100
``` ```
### Stop Services ### Stop Services
```bash ```bash
# Stop all services (keep data) # Stop all services (keep data)
docker-compose stop docker compose stop
# Stop and remove containers (keep data) # Stop and remove containers (keep data)
docker-compose down docker compose down
# Stop and remove containers and volumes (clear all data) # Stop and remove containers and volumes (clear all data)
docker-compose down -v docker compose down -v
``` ```
### Restart Services ### Restart Services
```bash ```bash
# Restart all services # Restart all services
docker-compose restart docker compose restart
# Restart backend only # Restart backend only
docker-compose restart backend docker compose restart backend
# Restart frontend only # Restart frontend only
docker-compose restart frontend docker compose restart frontend
``` ```
### Update Services ### Update Services
@@ -142,7 +153,7 @@ docker-compose restart frontend
git pull git pull
# Rebuild and restart # Rebuild and restart
docker-compose up -d --build docker compose up -d --build
``` ```
## 🔧 Advanced Configuration ## 🔧 Advanced Configuration
@@ -226,14 +237,14 @@ tar -xzf backup_20241029.tar.gz
```bash ```bash
# View detailed error messages # View detailed error messages
docker-compose logs backend docker compose logs backend
docker-compose logs frontend docker compose logs frontend
# Check container status # Check container status
docker-compose ps -a docker compose ps -a
# Rebuild (clear cache) # Rebuild (clear cache)
docker-compose build --no-cache docker compose build --no-cache
``` ```
### Port Already in Use ### Port Already in Use
@@ -273,10 +284,10 @@ curl http://localhost:3000/health
```bash ```bash
# Check network connectivity # Check network connectivity
docker-compose exec frontend ping backend docker compose exec frontend ping backend
# Check if backend service is running # Check if backend service is running
docker-compose exec frontend wget -O- http://backend:8080/health docker compose exec frontend wget -O- http://backend:8080/health
``` ```
### Clean Docker Resources ### Clean Docker Resources
@@ -321,8 +332,8 @@ docker system prune -a --volumes
4. **Regularly update images** 4. **Regularly update images**
```bash ```bash
docker-compose pull docker compose pull
docker-compose up -d docker compose up -d
``` ```
## 🌐 Production Deployment ## 🌐 Production Deployment
@@ -391,7 +402,7 @@ logging:
max-file: "3" max-file: "3"
# View log statistics # View log statistics
docker-compose logs --timestamps | wc -l docker compose logs --timestamps | wc -l
``` ```
### Monitoring Tool Integration ### Monitoring Tool Integration
@@ -424,28 +435,28 @@ services:
```bash ```bash
# Start # Start
docker-compose up -d --build # Build and start docker compose up -d --build # Build and start
docker-compose up -d # Start (without rebuilding) docker compose up -d # Start (without rebuilding)
# Stop # Stop
docker-compose stop # Stop services docker compose stop # Stop services
docker-compose down # Stop and remove containers docker compose down # Stop and remove containers
docker-compose down -v # Stop and remove containers and data docker compose down -v # Stop and remove containers and data
# View # View
docker-compose ps # View status docker compose ps # View status
docker-compose logs -f # View logs docker compose logs -f # View logs
docker-compose top # View processes docker compose top # View processes
# Restart # Restart
docker-compose restart # Restart all services docker compose restart # Restart all services
docker-compose restart backend # Restart backend docker compose restart backend # Restart backend
# Update # Update
git pull && docker-compose up -d --build git pull && docker compose up -d --build
# Clean # Clean
docker-compose down -v # Clear all data docker compose down -v # Clear all data
docker system prune -a # Clean Docker resources docker system prune -a # Clean Docker resources
``` ```

View File

@@ -11,26 +11,42 @@
### 安装 Docker ### 安装 Docker
> #### 提示Docker Compose 版本说明
>
> **新用户建议**
> - **推荐使用 Docker Desktop**:自动包含最新 Docker Compose无需单独安装
> - 安装简单,一键搞定,提供图形界面管理
> - 支持 macOS、Windows、部分 Linux 发行版
>
> **旧用户提醒**
> - **弃用独立 docker-compose**:不再推荐下载独立的 Docker Compose 二进制文件
> - **使用内置版**Docker 20.10+ 自带 `docker compose` 命令(注意是空格)
> - 如果还在使用旧的 `docker-compose`,请升级到新语法
#### macOS / Windows #### macOS / Windows
下载并安装 [Docker Desktop](https://www.docker.com/products/docker-desktop/) 下载并安装 [Docker Desktop](https://www.docker.com/products/docker-desktop/)
#### Linux (Ubuntu/Debian) **安装后验证:**
```bash ```bash
# 安装 Docker docker --version
docker compose --version # 注意:使用空格,不再是连字符
```
#### Linux (Ubuntu/Debian)
**推荐方式:使用 Docker Desktop如果可用或 Docker CE**
```bash
# 安装 Docker (自动包含 compose)
curl -fsSL https://get.docker.com -o get-docker.sh curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh sudo sh get-docker.sh
# 安装 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# 将当前用户加入 docker 组 # 将当前用户加入 docker 组
sudo usermod -aG docker $USER sudo usermod -aG docker $USER
newgrp docker newgrp docker
# 验证安装 # 验证安装(新命令)
docker --version docker --version
docker-compose --version docker compose --version # Docker 24+ 自带,无需单独安装
``` ```
## 🚀 快速开始3步完成部署 ## 🚀 快速开始3步完成部署
@@ -69,10 +85,10 @@ nano config.json # 或使用其他编辑器
```bash ```bash
# 构建并启动所有服务(首次运行) # 构建并启动所有服务(首次运行)
docker-compose up -d --build docker compose up -d --build
# 后续启动(不重新构建) # 后续启动(不重新构建)
docker-compose up -d docker compose up -d
``` ```
**启动过程说明:** **启动过程说明:**
@@ -91,49 +107,49 @@ docker-compose up -d
### 查看运行状态 ### 查看运行状态
```bash ```bash
# 查看所有容器状态 # 查看所有容器状态
docker-compose ps docker compose ps
# 查看服务健康状态 # 查看服务健康状态
docker-compose ps --format json | jq docker compose ps --format json | jq
``` ```
### 查看日志 ### 查看日志
```bash ```bash
# 查看所有服务日志 # 查看所有服务日志
docker-compose logs -f docker compose logs -f
# 只查看后端日志 # 只查看后端日志
docker-compose logs -f backend docker compose logs -f backend
# 只查看前端日志 # 只查看前端日志
docker-compose logs -f frontend docker compose logs -f frontend
# 查看最近 100 行日志 # 查看最近 100 行日志
docker-compose logs --tail=100 docker compose logs --tail=100
``` ```
### 停止服务 ### 停止服务
```bash ```bash
# 停止所有服务(保留数据) # 停止所有服务(保留数据)
docker-compose stop docker compose stop
# 停止并删除容器(保留数据) # 停止并删除容器(保留数据)
docker-compose down docker compose down
# 停止并删除容器和卷(清除所有数据) # 停止并删除容器和卷(清除所有数据)
docker-compose down -v docker compose down -v
``` ```
### 重启服务 ### 重启服务
```bash ```bash
# 重启所有服务 # 重启所有服务
docker-compose restart docker compose restart
# 只重启后端 # 只重启后端
docker-compose restart backend docker compose restart backend
# 只重启前端 # 只重启前端
docker-compose restart frontend docker compose restart frontend
``` ```
### 更新服务 ### 更新服务
@@ -142,7 +158,7 @@ docker-compose restart frontend
git pull git pull
# 重新构建并重启 # 重新构建并重启
docker-compose up -d --build docker compose up -d --build
``` ```
## 🔧 高级配置 ## 🔧 高级配置
@@ -226,14 +242,14 @@ tar -xzf backup_20241029.tar.gz
```bash ```bash
# 查看详细错误信息 # 查看详细错误信息
docker-compose logs backend docker compose logs backend
docker-compose logs frontend docker compose logs frontend
# 检查容器状态 # 检查容器状态
docker-compose ps -a docker compose ps -a
# 重新构建(清除缓存) # 重新构建(清除缓存)
docker-compose build --no-cache docker compose build --no-cache
``` ```
### 端口被占用 ### 端口被占用
@@ -273,10 +289,10 @@ curl http://localhost:3000/health
```bash ```bash
# 检查网络连接 # 检查网络连接
docker-compose exec frontend ping backend docker compose exec frontend ping backend
# 检查后端服务是否正常 # 检查后端服务是否正常
docker-compose exec frontend wget -O- http://backend:8080/health docker compose exec frontend wget -O- http://backend:8080/health
``` ```
### 清理 Docker 资源 ### 清理 Docker 资源
@@ -321,8 +337,8 @@ docker system prune -a --volumes
4. **定期更新镜像** 4. **定期更新镜像**
```bash ```bash
docker-compose pull docker compose pull
docker-compose up -d docker compose up -d
``` ```
## 🌐 生产环境部署 ## 🌐 生产环境部署
@@ -391,7 +407,7 @@ logging:
max-file: "3" max-file: "3"
# 查看日志统计 # 查看日志统计
docker-compose logs --timestamps | wc -l docker compose logs --timestamps | wc -l
``` ```
### 监控工具集成 ### 监控工具集成
@@ -424,28 +440,28 @@ services:
```bash ```bash
# 启动 # 启动
docker-compose up -d --build # 构建并启动 docker compose up -d --build # 构建并启动
docker-compose up -d # 启动(不重新构建) docker compose up -d # 启动(不重新构建)
# 停止 # 停止
docker-compose stop # 停止服务 docker compose stop # 停止服务
docker-compose down # 停止并删除容器 docker compose down # 停止并删除容器
docker-compose down -v # 停止并删除容器和数据 docker compose down -v # 停止并删除容器和数据
# 查看 # 查看
docker-compose ps # 查看状态 docker compose ps # 查看状态
docker-compose logs -f # 查看日志 docker compose logs -f # 查看日志
docker-compose top # 查看进程 docker compose top # 查看进程
# 重启 # 重启
docker-compose restart # 重启所有服务 docker compose restart # 重启所有服务
docker-compose restart backend # 重启后端 docker compose restart backend # 重启后端
# 更新 # 更新
git pull && docker-compose up -d --build git pull && docker compose up -d --build
# 清理 # 清理
docker-compose down -v # 清除所有数据 docker compose down -v # 清除所有数据
docker system prune -a # 清理 Docker 资源 docker system prune -a # 清理 Docker 资源
``` ```

View File

@@ -1,123 +0,0 @@
# Multi-stage build for NOFX AI Trading System
FROM golang:1.25-alpine AS backend-builder
# Install build dependencies including TA-Lib
RUN apk update && \
apk add --no-cache \
git \
make \
gcc \
g++ \
musl-dev \
wget \
tar \
autoconf \
automake
# Install TA-Lib
RUN wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz && \
tar -xzf ta-lib-0.4.0-src.tar.gz && \
cd ta-lib && \
if [ "$(uname -m)" = "aarch64" ]; then \
CONFIG_GUESS=$(find /usr/share -name config.guess | head -1) && \
CONFIG_SUB=$(find /usr/share -name config.sub | head -1) && \
cp "$CONFIG_GUESS" config.guess && \
cp "$CONFIG_SUB" config.sub && \
chmod +x config.guess config.sub; \
fi && \
./configure --prefix=/usr && \
make && \
make install && \
cd .. && \
rm -rf ta-lib ta-lib-0.4.0-src.tar.gz
# Set working directory
WORKDIR /app
# Copy go mod files
COPY go.mod go.sum ./
# Download dependencies
RUN go mod download
# Copy backend source code
COPY . .
# Build the application
RUN CGO_ENABLED=1 GOOS=linux go build -trimpath -ldflags="-s -w" -o nofx .
# Frontend build stage
FROM node:18-alpine AS frontend-builder
WORKDIR /app/web
# Copy package files
COPY web/package*.json ./
# Install dependencies
RUN npm ci
# Copy frontend source
COPY web/ ./
# Build frontend
RUN npm run build
# Final stage
FROM alpine:latest
# Update package index and install runtime dependencies
RUN apk update && \
apk add --no-cache \
ca-certificates \
tzdata \
wget \
tar \
make \
gcc \
g++ \
musl-dev \
autoconf \
automake
# Install TA-Lib runtime
RUN wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz && \
tar -xzf ta-lib-0.4.0-src.tar.gz && \
cd ta-lib && \
if [ "$(uname -m)" = "aarch64" ]; then \
CONFIG_GUESS=$(find /usr/share -name config.guess | head -1) && \
CONFIG_SUB=$(find /usr/share -name config.sub | head -1) && \
cp "$CONFIG_GUESS" config.guess && \
cp "$CONFIG_SUB" config.sub && \
chmod +x config.guess config.sub; \
fi && \
./configure --prefix=/usr && \
make && \
make install && \
cd .. && \
rm -rf ta-lib ta-lib-0.4.0-src.tar.gz
# Set timezone to UTC
ENV TZ=UTC
WORKDIR /app
# Copy backend binary from builder
COPY --from=backend-builder /app/nofx .
# Copy frontend build from builder
COPY --from=frontend-builder /app/web/dist ./web/dist
# Create directories for logs and data
RUN mkdir -p /app/decision_logs
# Expose ports
# 8080 for backend API
EXPOSE 8080
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
# Run the application
CMD ["./nofx"]

View File

@@ -260,8 +260,14 @@ nano config.json # or use any editor
chmod +x start.sh chmod +x start.sh
./start.sh start --build ./start.sh start --build
# Option 2: Use docker-compose directly > #### Docker Compose Version Notes
docker-compose up -d --build >
> **This project uses Docker Compose V2 syntax (with spaces)**
>
> If you have the older standalone `docker-compose` installed, please upgrade to Docker Desktop or Docker 20.10+
# Option 2: Use docker compose directly
docker compose up -d --build
``` ```
#### Step 3: Access Dashboard #### Step 3: Access Dashboard

View File

@@ -196,8 +196,10 @@ nano config.json # или используйте любой редактор
chmod +x start.sh chmod +x start.sh
./start.sh start --build ./start.sh start --build
# Вариант 2: Используйте docker-compose напрямую # Вариант 2: Используйте docker compose напрямую
docker-compose up -d --build # Этот проект использует синтаксис Docker Compose V2 (с пробелами)
# Если у вас установлена старая версия `docker-compose`, обновитесь до Docker Desktop или Docker 20.10+
docker compose up -d --build
``` ```
#### Шаг 3: Доступ к панели #### Шаг 3: Доступ к панели

View File

@@ -196,8 +196,10 @@ nano config.json # або використайте будь-який редак
chmod +x start.sh chmod +x start.sh
./start.sh start --build ./start.sh start --build
# Варіант 2: Використайте docker-compose безпосередньо # Варіант 2: Використайте docker compose безпосередньо
docker-compose up -d --build # Цей проект використовує синтаксис Docker Compose V2 (з пробілами)
# Якщо у вас встановлена стара версія `docker-compose`, оновіть до Docker Desktop або Docker 20.10+
docker compose up -d --build
``` ```
#### Крок 3: Доступ до панелі #### Крок 3: Доступ до панелі

View File

@@ -260,8 +260,10 @@ nano config.json # 或使用其他编辑器
chmod +x start.sh chmod +x start.sh
./start.sh start --build ./start.sh start --build
# 方式2直接使用docker-compose
docker-compose up -d --build # 方式2直接使用docker compose
# 如果您还在使用旧的独立 `docker-compose`,请升级到 Docker Desktop 或 Docker 20.10+
docker compose up -d --build
``` ```
#### 步骤3访问控制台 #### 步骤3访问控制台

View File

@@ -1,22 +1,21 @@
version: '3.8' version: '3.8'
services: services:
# NOFX Trading Backend # Backend service (API and core logic)
nofx: nofx:
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: ./docker/Dockerfile.backend
container_name: nofx-trading container_name: nofx-trading
restart: unless-stopped restart: unless-stopped
ports: ports:
- "8080:8080" - "${NOFX_BACKEND_PORT:-8080}:8080"
volumes: volumes:
- ./config.json:/app/config.json:ro - ./config.json:/app/config.json:ro
- ./decision_logs:/app/decision_logs - ./decision_logs:/app/decision_logs
- /etc/localtime:/etc/localtime:ro # 同步主机时间 - /etc/localtime:/etc/localtime:ro # Sync host time
- frontend-dist:/app/web/dist-shared:rw # 共享前端文件
environment: environment:
- TZ=Asia/Shanghai # 使用中国时区 - TZ=${NOFX_TIMEZONE:-Asia/Shanghai} # Set timezone
networks: networks:
- nofx-network - nofx-network
healthcheck: healthcheck:
@@ -25,25 +24,26 @@ services:
timeout: 10s timeout: 10s
retries: 3 retries: 3
start_period: 60s start_period: 60s
command: sh -c "cp -r /app/web/dist/* /app/web/dist-shared/ 2>/dev/null || true && exec ./nofx"
# Frontend (Nginx) # Frontend service (static serving and proxy)
nofx-frontend: nofx-frontend:
image: nginx:alpine build:
context: .
dockerfile: ./docker/Dockerfile.frontend
container_name: nofx-frontend container_name: nofx-frontend
restart: unless-stopped restart: unless-stopped
ports: ports:
- "3000:80" - "${NOFX_FRONTEND_PORT:-3000}:80"
volumes:
- frontend-dist:/usr/share/nginx/html:ro
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
networks: networks:
- nofx-network - nofx-network
depends_on: depends_on:
- nofx - nofx
healthcheck:
volumes: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost/health"]
frontend-dist: interval: 30s
timeout: 10s
retries: 3
start_period: 5s
networks: networks:
nofx-network: nofx-network:

68
docker/Dockerfile.backend Normal file
View File

@@ -0,0 +1,68 @@
# docker/backend/Dockerfile
# ═══════════════════════════════════════════════════════════════
# NOFX Backend Dockerfile (Go + TA-Lib)
# Multi-stage build with shared TA-Lib compilation stage
# Versions extracted as ARGs for maintainability
# ═══════════════════════════════════════════════════════════════
ARG GO_VERSION=1.25-alpine
ARG ALPINE_VERSION=latest
ARG TA_LIB_VERSION=0.4.0
# ──────────────────────────────────────────────────────────────
# TA-Lib Build Stage (shared across builds)
# ──────────────────────────────────────────────────────────────
FROM alpine:${ALPINE_VERSION} AS ta-lib-builder
ARG TA_LIB_VERSION
RUN apk update && apk add --no-cache \
wget tar make gcc g++ musl-dev autoconf automake
RUN wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-${TA_LIB_VERSION}-src.tar.gz && \
tar -xzf ta-lib-${TA_LIB_VERSION}-src.tar.gz && \
cd ta-lib && \
if [ "$(uname -m)" = "aarch64" ]; then \
CONFIG_GUESS=$(find /usr/share -name config.guess | head -1) && \
CONFIG_SUB=$(find /usr/share -name config.sub | head -1) && \
cp "$CONFIG_GUESS" config.guess && \
cp "$CONFIG_SUB" config.sub && \
chmod +x config.guess config.sub; \
fi && \
./configure --prefix=/usr/local && \
make && make install && \
cd .. && rm -rf ta-lib ta-lib-${TA_LIB_VERSION}-src.tar.gz
# ──────────────────────────────────────────────────────────────
# Backend Build Stage (Go Application)
# ──────────────────────────────────────────────────────────────
FROM golang:${GO_VERSION} AS backend-builder
RUN apk update && apk add --no-cache git make gcc g++ musl-dev
COPY --from=ta-lib-builder /usr/local /usr/local
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=1 GOOS=linux go build -trimpath -ldflags="-s -w" -o nofx .
# ──────────────────────────────────────────────────────────────
# Runtime Stage (Minimal Executable Environment)
# ──────────────────────────────────────────────────────────────
FROM alpine:${ALPINE_VERSION}
RUN apk update && apk add --no-cache ca-certificates tzdata
COPY --from=ta-lib-builder /usr/local /usr/local
WORKDIR /app
COPY --from=backend-builder /app/nofx .
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
CMD ["./nofx"]

View File

@@ -0,0 +1,36 @@
# docker/frontend/Dockerfile
# ═══════════════════════════════════════════════════════════════
# NOFX Frontend Dockerfile (Node Build → Nginx Runtime)
# Versions extracted as ARGs for consistency
# ═══════════════════════════════════════════════════════════════
ARG NODE_VERSION=20-alpine
ARG NGINX_VERSION=alpine
# ──────────────────────────────────────────────────────────────
# Build Stage (Node)
# ──────────────────────────────────────────────────────────────
FROM node:${NODE_VERSION} AS builder
WORKDIR /build
COPY web/package*.json ./
RUN npm ci
COPY web/ ./
RUN npm run build
# ──────────────────────────────────────────────────────────────
# Runtime Stage (Nginx)
# ──────────────────────────────────────────────────────────────
FROM nginx:${NGINX_VERSION}
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /build/dist /usr/share/nginx/html
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost/health || exit 1
CMD ["nginx", "-g", "daemon off;"]

View File

@@ -1,3 +1,6 @@
# nginx.conf - Extracted Nginx configuration for NOFX Frontend
# This configuration merges enhancements from provided variants: improved gzip, static asset caching, adjusted API proxy (preserving /api/ path), extended timeouts, and a static health response for frontend independence.
server { server {
listen 80; listen 80;
server_name localhost; server_name localhost;
@@ -6,13 +9,13 @@ server {
root /usr/share/nginx/html; root /usr/share/nginx/html;
index index.html; index index.html;
# Gzip compression # Gzip compression (enhanced)
gzip on; gzip on;
gzip_vary on; gzip_vary on;
gzip_min_length 1024; gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript application/json; gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript application/json;
# Frontend routes (SPA) # Frontend routes (SPA) with static asset caching
location / { location / {
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
@@ -23,9 +26,9 @@ server {
} }
} }
# Proxy API requests to backend # Proxy API requests to backend (preserves /api/ path, with timeouts)
location /api/ { location /api/ {
proxy_pass http://nofx-trading:8080; proxy_pass http://nofx:8080/api/;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade'; proxy_set_header Connection 'upgrade';
@@ -41,9 +44,10 @@ server {
proxy_read_timeout 300s; proxy_read_timeout 300s;
} }
# Health check endpoint # Health check endpoint (static response for frontend health, independent of backend)
location /health { location /health {
return 200 "OK\n"; return 200 "OK\n";
add_header Content-Type text/plain; add_header Content-Type text/plain;
access_log off;
} }
} }

148
start.sh
View File

@@ -1,18 +1,24 @@
#!/bin/bash #!/bin/bash
# ═══════════════════════════════════════════════════════════════
# NOFX AI Trading System - Docker Quick Start Script # NOFX AI Trading System - Docker Quick Start Script
# 使用方法: ./start.sh [command] # Usage: ./start.sh [command]
# ═══════════════════════════════════════════════════════════════
set -e set -e
# 颜色定义 # ------------------------------------------------------------------------
# Color Definitions
# ------------------------------------------------------------------------
RED='\033[0;31m' RED='\033[0;31m'
GREEN='\033[0;32m' GREEN='\033[0;32m'
YELLOW='\033[1;33m' YELLOW='\033[1;33m'
BLUE='\033[0;34m' BLUE='\033[0;34m'
NC='\033[0m' # No Color NC='\033[0m' # No Color
# 打印带颜色的消息 # ------------------------------------------------------------------------
# Utility Functions: Colored Output
# ------------------------------------------------------------------------
print_info() { print_info() {
echo -e "${BLUE}[INFO]${NC} $1" echo -e "${BLUE}[INFO]${NC} $1"
} }
@@ -29,22 +35,51 @@ print_error() {
echo -e "${RED}[ERROR]${NC} $1" echo -e "${RED}[ERROR]${NC} $1"
} }
# 检查 Docker 是否安装 # ------------------------------------------------------------------------
# Detection: Docker Compose Command (Backward Compatible)
# ------------------------------------------------------------------------
detect_compose_cmd() {
if command -v docker compose &> /dev/null; then
COMPOSE_CMD="docker compose"
elif command -v docker-compose &> /dev/null; then
COMPOSE_CMD="docker-compose"
else
print_error "Docker Compose 未安装!请先安装 Docker Compose"
exit 1
fi
print_info "使用 Docker Compose 命令: $COMPOSE_CMD"
}
# ------------------------------------------------------------------------
# Validation: Docker Installation
# ------------------------------------------------------------------------
check_docker() { check_docker() {
if ! command -v docker &> /dev/null; then if ! command -v docker &> /dev/null; then
print_error "Docker 未安装!请先安装 Docker: https://docs.docker.com/get-docker/" print_error "Docker 未安装!请先安装 Docker: https://docs.docker.com/get-docker/"
exit 1 exit 1
fi fi
if ! command -v docker-compose &> /dev/null; then detect_compose_cmd
print_error "Docker Compose 未安装!请先安装 Docker Compose"
exit 1
fi
print_success "Docker 和 Docker Compose 已安装" print_success "Docker 和 Docker Compose 已安装"
} }
# 检查配置文件 # ------------------------------------------------------------------------
# Validation: Environment File (.env)
# ------------------------------------------------------------------------
check_env() {
if [ ! -f ".env" ]; then
print_warning ".env 不存在,从模板复制..."
cp .env.example .env
print_info "请编辑 .env 填入你的环境变量配置"
print_info "运行: nano .env 或使用其他编辑器"
exit 1
fi
print_success "环境变量文件存在"
}
# ------------------------------------------------------------------------
# Validation: Configuration File (config.json)
# ------------------------------------------------------------------------
check_config() { check_config() {
if [ ! -f "config.json" ]; then if [ ! -f "config.json" ]; then
print_warning "config.json 不存在,从模板复制..." print_warning "config.json 不存在,从模板复制..."
@@ -56,15 +91,53 @@ check_config() {
print_success "配置文件存在" print_success "配置文件存在"
} }
# 启动服务 # ------------------------------------------------------------------------
# Build: Frontend (Node.js Based)
# ------------------------------------------------------------------------
# build_frontend() {
# print_info "检查前端构建环境..."
# if ! command -v node &> /dev/null; then
# print_error "Node.js 未安装!请先安装 Node.js"
# exit 1
# fi
# if ! command -v npm &> /dev/null; then
# print_error "npm 未安装!请先安装 npm"
# exit 1
# fi
# print_info "正在构建前端..."
# cd web
# print_info "安装 Node.js 依赖..."
# npm install
# print_info "构建前端应用..."
# npm run build
# cd ..
# print_success "前端构建完成"
# }
# ------------------------------------------------------------------------
# Service Management: Start
# ------------------------------------------------------------------------
start() { start() {
print_info "正在启动 NOFX AI Trading System..." print_info "正在启动 NOFX AI Trading System..."
# Auto-build frontend if missing or forced
# if [ ! -d "web/dist" ] || [ "$1" == "--build" ]; then
# build_frontend
# fi
# Rebuild images if flag set
if [ "$1" == "--build" ]; then if [ "$1" == "--build" ]; then
print_info "重新构建镜像..." print_info "重新构建镜像..."
docker-compose up -d --build $COMPOSE_CMD up -d --build
else else
docker-compose up -d print_info "启动容器..."
$COMPOSE_CMD up -d
fi fi
print_success "服务已启动!" print_success "服务已启动!"
@@ -75,60 +148,74 @@ start() {
print_info "停止服务: ./start.sh stop" print_info "停止服务: ./start.sh stop"
} }
# 停止服务 # ------------------------------------------------------------------------
# Service Management: Stop
# ------------------------------------------------------------------------
stop() { stop() {
print_info "正在停止服务..." print_info "正在停止服务..."
docker-compose stop $COMPOSE_CMD stop
print_success "服务已停止" print_success "服务已停止"
} }
# 重启服务 # ------------------------------------------------------------------------
# Service Management: Restart
# ------------------------------------------------------------------------
restart() { restart() {
print_info "正在重启服务..." print_info "正在重启服务..."
docker-compose restart $COMPOSE_CMD restart
print_success "服务已重启" print_success "服务已重启"
} }
# 查看日志 # ------------------------------------------------------------------------
# Monitoring: Logs
# ------------------------------------------------------------------------
logs() { logs() {
if [ -z "$2" ]; then if [ -z "$2" ]; then
docker-compose logs -f $COMPOSE_CMD logs -f
else else
docker-compose logs -f "$2" $COMPOSE_CMD logs -f "$2"
fi fi
} }
# 查看状态 # ------------------------------------------------------------------------
# Monitoring: Status
# ------------------------------------------------------------------------
status() { status() {
print_info "服务状态:" print_info "服务状态:"
docker-compose ps $COMPOSE_CMD ps
echo "" echo ""
print_info "健康检查:" print_info "健康检查:"
curl -s http://localhost:8080/health | jq '.' || echo "后端未响应" curl -s http://localhost:8080/health | jq '.' || echo "后端未响应"
} }
# 清理 # ------------------------------------------------------------------------
# Maintenance: Clean (Destructive)
# ------------------------------------------------------------------------
clean() { clean() {
print_warning "这将删除所有容器和数据!" print_warning "这将删除所有容器和数据!"
read -p "确认删除?(yes/no): " confirm read -p "确认删除?(yes/no): " confirm
if [ "$confirm" == "yes" ]; then if [ "$confirm" == "yes" ]; then
print_info "正在清理..." print_info "正在清理..."
docker-compose down -v $COMPOSE_CMD down -v
print_success "清理完成" print_success "清理完成"
else else
print_info "已取消" print_info "已取消"
fi fi
} }
# 更新 # ------------------------------------------------------------------------
# Maintenance: Update
# ------------------------------------------------------------------------
update() { update() {
print_info "正在更新..." print_info "正在更新..."
git pull git pull
docker-compose up -d --build $COMPOSE_CMD up -d --build
print_success "更新完成" print_success "更新完成"
} }
# 显示帮助 # ------------------------------------------------------------------------
# Help: Usage Information
# ------------------------------------------------------------------------
show_help() { show_help() {
echo "NOFX AI Trading System - Docker 管理脚本" echo "NOFX AI Trading System - Docker 管理脚本"
echo "" echo ""
@@ -150,12 +237,15 @@ show_help() {
echo " ./start.sh status # 查看状态" echo " ./start.sh status # 查看状态"
} }
# 主函数 # ------------------------------------------------------------------------
# Main: Command Dispatcher
# ------------------------------------------------------------------------
main() { main() {
check_docker check_docker
case "${1:-start}" in case "${1:-start}" in
start) start)
check_env
check_config check_config
start "$2" start "$2"
;; ;;
@@ -188,5 +278,5 @@ main() {
esac esac
} }
# 运行主函数 # Execute Main
main "$@" main "$@"

View File

@@ -1,8 +1,5 @@
# Dependencies # Dependencies
node_modules/ node_modules/
package-lock.json
yarn.lock
pnpm-lock.yaml
# Build output (will be regenerated) # Build output (will be regenerated)
dist/ dist/

View File

@@ -1,72 +0,0 @@
# 构建阶段
FROM node:20-alpine AS builder
# 设置工作目录
WORKDIR /app
# 复制 package 文件
COPY package*.json ./
# 安装依赖
RUN npm ci --only=production=false
# 复制源代码
COPY . .
# 构建应用
RUN npm run build
# 运行阶段
FROM nginx:alpine
# 复制自定义 nginx 配置
COPY <<EOF /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
# 启用 gzip 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_min_length 1000;
# SPA 路由支持
location / {
try_files \$uri \$uri/ /index.html;
}
# API 代理到后端
location /api/ {
proxy_pass http://backend:8080/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;
}
# 健康检查端点
location /health {
proxy_pass http://backend:8080/health;
access_log off;
}
}
EOF
# 从构建阶段复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html
# 暴露端口
EXPOSE 80
# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost/health || exit 1
# 启动 nginx
CMD ["nginx", "-g", "daemon off;"]