Skip to content

Latest commit

 

History

History
450 lines (306 loc) · 8.11 KB

File metadata and controls

450 lines (306 loc) · 8.11 KB

QuantDinger Cloud Server Deployment Guide

This guide covers production-style deployment on a cloud server with Docker Compose, domain setup, HTTPS, reverse proxy, and frontend/backend separation options.

Recommended Architecture

Recommended setup: single domain + host Nginx reverse proxy

  • Public URL: https://app.example.com
  • Host Nginx: listens on 80/443
  • Docker frontend: binds to 127.0.0.1:8888
  • Docker backend: binds to 127.0.0.1:5000
  • Docker postgres: binds to 127.0.0.1:5432

Benefits:

  • Only 80/443 are exposed publicly
  • Frontend and API stay on the same origin
  • Backend and database are not directly exposed to the internet

1. Prepare the Server

Recommended:

  • Ubuntu 22.04 / Debian 12
  • 2 vCPU / 4 GB RAM or higher
  • Security group ports open: 22, 80, 443
  • A domain such as app.example.com

DNS steps:

  1. Create an A record
  2. Host: app
  3. Value: your server public IP
  4. Wait for DNS propagation

Verify:

ping app.example.com

2. Install Docker and Docker Compose

Ubuntu / Debian example:

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker
docker --version
docker compose version

If Docker Hub is slow or blocked in your network, you can switch image source later with IMAGE_PREFIX in the project-root .env.

3. Clone the Project

git clone https://github.com/brokermr810/QuantDinger.git
cd QuantDinger

4. Configure backend_api_python/.env

Copy the template:

cp backend_api_python/env.example backend_api_python/.env

Generate and write SECRET_KEY:

./scripts/generate-secret-key.sh

At minimum, review these values:

ADMIN_USER=quantdinger
ADMIN_PASSWORD=your_strong_password
SECRET_KEY=your_generated_secret

If you want AI features, add at least one provider key, for example:

OPENROUTER_API_KEY=your_key

5. Configure the Project-Root .env

The project-root .env is used by Docker Compose for ports and image source selection.

Copy the template:

cp .env.example .env

Recommended production values:

FRONTEND_PORT=127.0.0.1:8888
BACKEND_PORT=127.0.0.1:5000
DB_PORT=127.0.0.1:5432
IMAGE_PREFIX=

Explanation:

  • FRONTEND_PORT=127.0.0.1:8888: only accessible locally, exposed through host Nginx
  • BACKEND_PORT=127.0.0.1:5000: avoid exposing API directly
  • DB_PORT=127.0.0.1:5432: avoid exposing PostgreSQL directly
  • IMAGE_PREFIX=: empty means official Docker Hub

If image pulls fail, try:

IMAGE_PREFIX=docker.m.daocloud.io/library/

or:

IMAGE_PREFIX=docker.xuanyuan.me/library/

6. Start the Containers

docker-compose up -d --build
docker-compose ps

Logs:

docker-compose logs -f backend
docker-compose logs -f frontend

At this point, services usually listen on:

  • 127.0.0.1:8888
  • 127.0.0.1:5000
  • 127.0.0.1:5432

7. Install and Configure Nginx

Install:

sudo apt update
sudo apt install -y nginx

Recommended site config /etc/nginx/sites-available/quantdinger.conf:

server {
    listen 80;
    server_name app.example.com;

    client_max_body_size 20m;

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

Enable it:

sudo ln -s /etc/nginx/sites-available/quantdinger.conf /etc/nginx/sites-enabled/quantdinger.conf
sudo nginx -t
sudo systemctl reload nginx

If using UFW:

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable

8. Enable HTTPS with Let's Encrypt

Install Certbot:

sudo apt install -y certbot python3-certbot-nginx

Request the certificate:

sudo certbot --nginx -d app.example.com

Test renewal:

sudo certbot renew --dry-run

Then open:

https://app.example.com

9. Recommended Production Mode: Single Domain

This is the recommended mode for the open-source edition.

Why:

  • The open-source frontend is shipped as prebuilt frontend/dist
  • The frontend container already proxies /api/* to backend:5000 inside Docker
  • Only one public domain and one TLS configuration are needed

Topology:

Browser
  -> https://app.example.com
  -> Host Nginx :443
  -> 127.0.0.1:8888 (frontend container)
  -> /api/* then proxied by frontend container to backend:5000

10. Advanced Option: Frontend / Backend Separation

If you want:

  • frontend: app.example.com
  • API: api.example.com

you can use a dual-domain setup, but note:

  1. the frontend must point API requests to api.example.com
  2. backend cross-origin handling must be correct
  3. this is better suited for deployments where you control frontend source/customization

Host Nginx can expose:

  • app.example.com -> 127.0.0.1:8888
  • api.example.com -> 127.0.0.1:5000

Example api.example.com config:

server {
    listen 80;
    server_name api.example.com;

    client_max_body_size 20m;

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

If you only want logical separation without cross-origin complexity, keep:

  • https://app.example.com/
  • https://app.example.com/api/

11. Common Operations

Check status:

docker-compose ps

View logs:

docker-compose logs -f backend
docker-compose logs -f frontend
docker-compose logs -f postgres

Update:

git pull
docker-compose up -d --build

Restart:

docker-compose restart backend
docker-compose restart frontend

Stop:

docker-compose down

12. Troubleshooting

1. Image pull failures

Symptoms:

  • failed to resolve source metadata
  • registry-1.docker.io
  • Docker Desktop has no HTTPS proxy

Fix:

IMAGE_PREFIX=docker.m.daocloud.io/library/

Then rerun:

docker-compose up -d --build

2. Backend logs show exec /usr/local/bin/docker-entrypoint.sh: no such file or directory

Fix:

docker-compose build --no-cache backend
docker-compose up -d backend

3. Frontend logs show host not found in upstream "backend"

This usually means backend failed first.

Fix:

docker-compose ps
docker-compose logs backend --tail=100
docker-compose restart frontend

4. Frontend build fails with COPY frontend/dist ... not found

This usually means .dockerignore excluded frontend/dist, while the current open-source frontend image copies that prebuilt directory directly.

Check:

cat .dockerignore
ls frontend/dist

Make sure .dockerignore does NOT contain:

frontend/dist

5. Saving settings fails with Read-only file system: '/app/.env'

This means backend_api_python/.env is mounted read-only into the container.

In docker-compose.yml, avoid:

- ./backend_api_python/.env:/app/.env:ro

Use a writable mount instead:

- ./backend_api_python/.env:/app/.env

Then run:

docker-compose up -d backend

6. Proxy works on host but not inside Docker

If your proxy listens on host 127.0.0.1:10808, do not use 127.0.0.1 inside the container, because that points to the container itself.

For Docker deployments, use:

PROXY_URL=socks5h://host.docker.internal:10808

7. Exchange logs show symbol not found

If proxy/network access is already working but some symbols still fail, for example:

Symbol 'MATIC/USDT' not found on okx

this is usually a market-symbol mapping / token-rename issue on the exchange side, not a general network failure.

8. Nginx 502 / 504

Check:

docker-compose ps
curl http://127.0.0.1:8888/health
curl http://127.0.0.1:5000/api/health
sudo nginx -t

9. PostgreSQL should not be public

Recommended:

DB_PORT=127.0.0.1:5432

Do not expose:

  • 5432
  • 5000

Publicly expose only:

  • 80
  • 443