Files
DinQuant/docs/CLOUD_DEPLOYMENT_EN.md
Dinger 05f07ee544 refactor deployment config and exchange integrations
Simplify runtime configuration and remove legacy database and settings surface so new installs are easier to operate.
Refresh deployment assets, docs, and order execution behavior to keep the packaged app aligned with the current backend.

Made-with: Cursor
2026-03-21 18:32:04 +08:00

8.1 KiB

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 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

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