π From Zero to Hero: Deploying the MyZubster Ecosystem on a VPS
How I built a complete decentralized marketplace with Monero payments, Docker, and a full frontendβall on a single VPS.
π± The Vision
MyZubster is an open-source ecosystem for a decentralized marketplace that uses Monero (XMR) as its primary currency to guarantee privacy and security. The architecture consists of three core pillars:
Gateway: Monero payment engine (Node.js + MongoDB)
Marketplace: RESTful API backend (Node.js + SQLite)
Frontend: React/Vite web interface served via Nginx
Additionally, I integrated:
Security Bot: Automated vulnerability scanning with Kali Linux and DeepSeek AI
NFT Template: Rust-based NFT support on Tari (Monero's sidechain)
This post documents my journey deploying the entire system on a VPS, from initial configuration to final validation.
πΊοΈ Roadmap and Priorities
Priority Task Status
π΄ High Deploy Gateway with Docker in production β
Completed
π΄ High Connect Marketplace to Gateway β
Completed
π‘ Medium Deploy Frontend with Nginx β
Completed
π‘ Medium Deploy NFT template on Tari In Progress
π’ Low Centralized documentation Planned
π οΈ Technology Stack
Layer Technology Purpose
Languages JavaScript (Node.js), Python, Rust Backend, automation, blockchain
Databases MongoDB (gateway), SQLite (marketplace) Transactional data, user data
Containerization Docker & Docker Compose Reproducible deployments
Blockchain Monero (mainnet), Tari Private payments, NFT assets
Security Kali Linux, nmap, nikto, DeepSeek (Ollama) Vulnerability scanning, AI analysis
Frontend React + Vite Modern web interface
Web Server Nginx Reverse proxy and static file serving
π§ Step 1: Gateway Configuration
1.1 Dockerfile
I created a multi-stage Dockerfile to containerize the gateway for production:
dockerfile
FROM node:20-slim AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY . .
FROM node:20-slim
RUN groupadd -r myzubster && useradd -r -g myzubster myzubster
WORKDIR /app
COPY --from=builder --chown=myzubster:myzubster /app/node_modules ./node_modules
COPY --from=builder --chown=myzubster:myzubster /app ./
EXPOSE 3000
USER myzubster
CMD ["node", "server.js"]
Key decisions:
Multi-stage build reduces final image size
Non-root user for security
Production-only dependencies
1.2 docker-compose.yml
To orchestrate all services:
yaml
services:
mongodb:
image: mongo:7-jammy
container_name: myzubster-mongodb
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER:-admin}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD:-securepassword}
volumes:
- mongodb_data:/data/db
ports:
- "27018:27017"
networks:
- myzubster-network
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
interval: 30s
timeout: 10s
retries: 5
gateway:
build:
context: .
dockerfile: Dockerfile
container_name: myzubster-gateway
restart: unless-stopped
environment:
- NODE_ENV=${NODE_ENV:-production}
- PORT=${PORT:-3000}
- MONGO_URI=mongodb://${MONGO_USER:-admin}:${MONGO_PASSWORD:-securepassword}@mongodb:27017/myzubster?authSource=admin
- MONERO_RPC_URL=${MONERO_RPC_URL:-http://node.moneroworld.com:18081}
- MONERO_NETWORK=${MONERO_NETWORK:-mainnet}
- JWT_SECRET=${JWT_SECRET}
- API_KEY=${API_KEY}
ports:
- "3001:3000"
depends_on:
mongodb:
condition: service_healthy
networks:
- myzubster-network
volumes:
- ./public:/app/public
- gateway_logs:/app/logs
volumes:
mongodb_data:
driver: local
gateway_logs:
driver: local
networks:
myzubster-network:
driver: bridge
Why port 3001? I mapped internal port 3000 to external port 3001 to avoid conflicts with other services.
1.3 Environment Variables (.env)
Sensitive configuration is stored in a .env file (excluded from Git):
env
NODE_ENV=production
PORT=3000
MONGO_USER=admin
MONGO_PASSWORD=your_secure_password
MONERO_NETWORK=mainnet
MONERO_RPC_URL=http://node.moneroworld.com:18081
MONERO_WALLET_ADDRESS=your_wallet_address
MONERO_WALLET_PASSWORD=your_wallet_password
MONERO_MIN_CONFIRMATIONS=10
JWT_SECRET=your_jwt_secret
API_KEY=your_api_key
1.4 Launch the Gateway
bash
cd ~/MyZubsterGateway
docker compose up -d --build
docker compose ps
curl http://localhost:3001/api/health
{"status":"ok","timestamp":"2026-07-25T..."}
π Step 2: Connecting the Marketplace
The marketplace is a separate Node.js application that connects to the gateway for payment processing and order management.
2.1 Marketplace .env Configuration
env
PORT=4000
NODE_ENV=production
DB_DIALECT=sqlite
DB_STORAGE=./data/marketplace.sqlite
MYZUBSTER_API_URL=http://localhost:3001/api
MYZUBSTER_API_TOKEN=your_api_token
MONERO_NETWORK=mainnet
MONERO_RPC_URL=http://node.moneroworld.com:18081
MONERO_WALLET_ADDRESS=your_wallet_address
MONERO_WALLET_PASSWORD=your_wallet_password
MONERO_MIN_CONFIRMATIONS=10
JWT_SECRET=your_jwt_secret
JWT_EXPIRES_IN=7d
2.2 Launch the Marketplace
bash
cd ~/MyZubster-Marketplace
npm install
node server.js &
2.3 Verify Integration
bash
curl http://localhost:4000/api/health
{"status":"ok","service":"MyZubster-Marketplace","database":"sqlite"}
curl http://localhost:4000/api/gateway/status
{"gateway":{"status":"ok"},"status":"connected"}
Key insight: The marketplace successfully communicates with the gateway via REST API.
π Step 3: Deploying the Frontend
3.1 Build the Frontend
bash
cd ~/myzubster-frontend
npm install
npm run build
3.2 Configure Nginx
nginx
/etc/nginx/sites-available/myzubster-unified
server {
listen 80;
server_name myzubster.com www.myzubster.com;
return 301 https://myzubster.com$request_uri;
}
server {
listen 443 ssl http2;
server_name myzubster.com www.myzubster.com;
root /var/www/myzubster-frontend;
index index.html;
ssl_certificate /etc/letsencrypt/live/myzubster.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myzubster.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://localhost:3001/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;
}
}
3.3 Deploy
bash
sudo cp -r dist/* /var/www/myzubster-frontend/
sudo systemctl reload nginx
3.4 SSL with Let's Encrypt
bash
sudo certbot --nginx -d myzubster.com -d www.myzubster.com
π‘οΈ Step 4: Security Bot Integration
I integrated a security bot that performs automated vulnerability scanning using Kali Linux tools and DeepSeek AI.
4.1 Security Bot Architecture
python
!/usr/bin/env python3
import subprocess
import requests
import json
import logging
logging.basicConfig(filename='/var/log/security_bot.log', level=logging.INFO)
def scan_gateway():
result = subprocess.run(['nmap', '-p', '3001', 'localhost'],
capture_output=True, text=True)
return result.stdout
def ask_deepseek(prompt):
try:
response = requests.post('http://localhost:11434/api/generate',
json={
"model": "deepseek-r1:1.5b",
"prompt": prompt,
"stream": False
},
timeout=30)
return response.json().get('response', '')
except Exception as e:
logging.error(f"DeepSeek error: {e}")
return ""
def block_ip(ip):
subprocess.run(['ufw', 'deny', 'from', ip], check=False)
def main():
scan_results = scan_gateway()
analysis = ask_deepseek(
f"Analyze this nmap scan and list security concerns:\n{scan_results}"
)
logging.info(f"Analysis: {analysis}")
4.2 Automate with Cron
bash
Run every hour
0 * * * * /usr/bin/python3 /root/MyZubsterGateway/security/security_bot.py >> /var/log/security_bot.log 2>&1
β Final Results
After completing the deployment, all services were operational:
Service Endpoint Status
Frontend https://myzubster.com β
HTTP/2 200
Gateway /api/health {"status":"ok"}
Marketplace /api/health {"status":"ok"}
Integration /api/gateway/status "connected"
Database MongoDB + SQLite β
Connected
Security Bot Cron job β
Running hourly
SSL Certificate Let's Encrypt β
Valid
System Overview
text
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MyZubster VPS Infrastructure β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β π FRONTEND (React/Vite) β
β βββ https://myzubster.com β
LIVE (HTTP/2) β
β β
β π NGINX (Reverse Proxy) β
β βββ HTTP β HTTPS reindirizzamento β
β
β βββ /api/ β http://localhost:3001/api/ β
β
β β
β π SSL/TLS (Let's Encrypt) β
β βββ Valido fino a Ottobre 2026 β
β
β β
β βοΈ GATEWAY (Node.js + MongoDB) β
β βββ Porta 3001 (Docker) β
ATTIVO β
β β
β π MARKETPLACE (Node.js + SQLite) β
β βββ Porta 4000 β
ATTIVO β
β β
β π‘οΈ SECURITY BOT (Kali Linux + DeepSeek AI) β
β βββ Nmap β
(scansione porte) β
β βββ Nikto β οΈ (da installare) β
β βββ Sqlmap β
(nessuna vulnerabilitΓ ) β
β βββ Gobuster β
(directory enumerate) β
β β
β π₯ UFW FIREWALL β
β βββ Attivo, solo porte necessarie aperte β
β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Repository & Documentation
All code is available on GitHub:
Gateway: DanielIoni-creator/MyZubsterGateway
Marketplace: DanielIoni-creator/MyZubster-Marketplace
Frontend: DanielIoni-creator/myzubster-frontend
Mobile App: DanielIoni-creator/MyZubster-App
NFT Template: [DanielIoni-creator/tari-nft-template](https://github.com/DanielIoni-creator/t
Top comments (0)