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
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 Architecture
Recommended setup: single domain + host Nginx reverse proxy
- Public URL:
https://app.example.com - Host Nginx: listens on
80/443 - Docker
frontend: binds to127.0.0.1:8888 - Docker
backend: binds to127.0.0.1:5000 - Docker
postgres: binds to127.0.0.1:5432
Benefits:
- Only
80/443are 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:
- Create an
Arecord - Host:
app - Value: your server public IP
- 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 NginxBACKEND_PORT=127.0.0.1:5000: avoid exposing API directlyDB_PORT=127.0.0.1:5432: avoid exposing PostgreSQL directlyIMAGE_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:8888127.0.0.1:5000127.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/*tobackend:5000inside 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:
- the frontend must point API requests to
api.example.com - backend cross-origin handling must be correct
- this is better suited for deployments where you control frontend source/customization
Host Nginx can expose:
app.example.com->127.0.0.1:8888api.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 metadataregistry-1.docker.ioDocker 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:
54325000
Publicly expose only:
80443