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-ip
server {
listen 80;
server_name 188.213.161.186;
root /var/www/myzubster-frontend;
index index.html;
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 restart nginx
3.4 Verify
bash
curl -I http://188.213.161.186
HTTP/1.1 200 OK
๐ก๏ธ 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
Gateway /api/health {"status":"ok"}
Marketplace /api/health {"status":"ok"}
Integration /api/gateway/status "connected"
Frontend / HTTP 200 OK
Database MongoDB + SQLite โ
Connected
Security Bot Cron job โ
Running hourly
System Overview
text
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ MyZubster VPS Infrastructure โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโ โ
โ โ Frontend โ โ Gateway โ โ Marketplace โ โ Security โ โ
โ โ (Nginx) โโโโถ (Port 3001) โโโโค (Port 4000) โ โ Bot โ โ
โ โ Port 80 โ โ - MongoDB โ โ - SQLite โ โ (Cron) โ โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโ โ
โ โ โ โ โ
โ โผ โผ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ Monero Public Node (node.moneroworld.com) โโ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ 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
๐ก Lessons Learned
Docker simplifies deployment โ Containerizing the gateway made the process reproducible, scalable, and easier to manage.
Environment variables are critical โ Separating configuration from code is essential for security and flexibility.
Monero payment monitoring requires a reliable node โ Using node.moneroworld.com as a public node worked well for testing; consider self-hosting for production.
Integration is seamless โ The REST API communication between gateway and marketplace works without issues.
Nginx is a powerful ally โ Serving static files and proxying API requests with a single configuration is clean and efficient.
Security is a long-term investment โ The Security Bot with DeepSeek AI reduces response time to potential threats.
Wallet recovery is straightforward โ Having the seed phrase saved securely (on a physical USB stick) made wallet recovery quick and painless.
๐ฎ Next Steps
Add HTTPS with Certbot for secure connections
Deploy the Mobile App to Google Play Store
Integrate NFC payments for physical interactions
Implement DAO Governance for community decisions
Complete Security Audit with third-party tools
Add more NFT functionality for real-world asset tokenization
๐ค Contribute
If you're interested in blockchain, privacy-first payments, or decentralized markets, contribute to the repositories on GitHub or open an issue to discuss new features.
Key areas for contribution:
Frontend: Improve the admin dashboard
Testing: Add webhook integration tests
Documentation: Write tutorials for new users
Security: Conduct penetration testing
๐ Connect with Me
Follow the development of MyZubster and connect on social media:
Blog: DEV.to - Daniel Ioni
X (Twitter): @myzubster
LinkedIn: Daniel Ioni
GitHub: DanielIoni-creator
๐ Quick Reference: All Commands Used
bash
Deploy Gateway
cd ~/MyZubsterGateway
docker compose up -d --build
docker compose ps
Deploy Marketplace
cd ~/MyZubster-Marketplace
npm install
node server.js &
Deploy Frontend
cd ~/myzubster-frontend
npm install
npm run build
sudo cp -r dist/* /var/www/myzubster-frontend/
sudo systemctl restart nginx
Verify Integration
curl http://localhost:4000/api/gateway/status
Access Frontend
Built with โค๏ธ for Monero, Tari, and the open-source community. ๐ฑ
Top comments (0)