- Updated branding from "SolaceScanScout" to "Solace" across various files including deployment scripts, API responses, and documentation. - Changed default base URL for Playwright tests and updated security headers to reflect the new branding. - Enhanced README and API documentation to include new authentication endpoints and product access details. This refactor aligns the project branding and improves clarity in the API documentation.
25 KiB
25 KiB
Complete Deployment Guide - LXC + Nginx + Cloudflare
This guide provides step-by-step instructions for deploying the ChainID 138 Explorer Platform using LXC containers, Nginx reverse proxy, Cloudflare DNS, SSL, and Cloudflare Tunnel.
Table of Contents
- Prerequisites
- LXC Container Setup
- Application Installation
- Database Setup
- Nginx Configuration
- Cloudflare DNS Configuration
- SSL Certificate Setup
- Cloudflare Tunnel Setup
- Security Hardening
- Monitoring & Maintenance
Prerequisites
Required Tools
- ✅ Proxmox VE with LXC support
- ✅ Cloudflare account with domain
- ✅ SSH access to Proxmox host
- ✅ Cloudflare API token (with DNS edit permissions)
Domain Requirements
- ✅ Domain registered with Cloudflare
- ✅ DNS managed by Cloudflare
System Requirements
- LXC Container: Ubuntu 22.04 LTS (recommended)
- Resources:
- CPU: 4+ cores
- RAM: 8GB minimum (16GB recommended)
- Storage: 100GB+ SSD
- Network: Public IP or Cloudflare Tunnel
Task List Overview
Phase 1: LXC Container Setup
- Create LXC container
- Configure container resources
- Set up networking
- Install base packages
- Configure firewall
Phase 2: Application Installation
- Install Go 1.21+
- Install Node.js 20+
- Install Docker & Docker Compose
- Clone repository
- Install dependencies
- Build applications
Phase 3: Database Setup
- Install PostgreSQL with TimescaleDB
- Create database and user
- Run migrations
- Configure backups
Phase 4: Infrastructure Services
- Deploy Elasticsearch/OpenSearch
- Deploy Redis
- Configure message queue (optional)
Phase 5: Application Services
- Configure environment variables
- Set up systemd services
- Start indexer service
- Start API service
- Start frontend service
Phase 6: Nginx Reverse Proxy
- Install Nginx
- Configure SSL certificates
- Set up reverse proxy config
- Configure rate limiting
- Set up caching
- Enable security headers
Phase 7: Cloudflare Configuration
- Set up Cloudflare DNS records
- Configure Cloudflare Tunnel
- Set up SSL/TLS mode
- Configure WAF rules
- Set up DDoS protection
- Configure caching rules
Phase 8: Security Hardening
- Configure firewall rules
- Set up fail2ban
- Configure automatic updates
- Set up log rotation
- Configure backup strategy
Phase 9: Monitoring
- Set up health checks
- Configure log aggregation
- Set up alerting
- Configure uptime monitoring
Phase 1: LXC Container Setup
Task 1.1: Create LXC Container
# On Proxmox host
pct create 100 \
local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst \
--hostname explorer-prod \
--memory 16384 \
--cores 4 \
--swap 4096 \
--storage local-lvm \
--rootfs local-lvm:100 \
--net0 name=eth0,bridge=vmbr0,ip=dhcp \
--unprivileged 0 \
--features nesting=1
Parameters:
- Container ID: 100 (change as needed)
- Template: Ubuntu 22.04
- Memory: 16GB
- CPU Cores: 4
- Storage: 100GB on local-lvm
- Network: DHCP on vmbr0
- Features: Enable nesting for Docker
Task 1.2: Start Container
pct start 100
pct enter 100
Task 1.3: Initial Container Configuration
# Update system
apt update && apt upgrade -y
# Install essential packages
apt install -y curl wget git vim net-tools ufw fail2ban \
unattended-upgrades apt-transport-https ca-certificates \
gnupg lsb-release
# Set timezone
timedatectl set-timezone UTC
# Configure hostname
hostnamectl set-hostname explorer-prod
Task 1.4: Create Deployment User
# Create deployment user
adduser explorer
usermod -aG sudo explorer
usermod -aG docker explorer
# Configure SSH (disable root login)
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
systemctl restart sshd
Phase 2: Application Installation
Task 2.1: Install Go 1.21+
# Download Go
cd /tmp
wget https://go.dev/dl/go1.21.6.linux-amd64.tar.gz
# Install Go
rm -rf /usr/local/go
tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz
# Add to PATH
echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc
# Verify
go version
Task 2.2: Install Node.js 20+
# Install Node.js via NodeSource
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt install -y nodejs
# Verify
node --version
npm --version
Task 2.3: Install Docker & Docker Compose
# Add Docker GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Add Docker repository
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Start Docker
systemctl enable docker
systemctl start docker
# Verify
docker --version
docker compose version
Task 2.4: Clone Repository
# Switch to deployment user
su - explorer
# Clone repository
cd /home/explorer
git clone <repository-url> explorer-monorepo
cd explorer-monorepo
Task 2.5: Install Dependencies
# Backend dependencies
cd backend
go mod download
# Frontend dependencies
cd ../frontend
npm ci --production
Task 2.6: Build Applications
# Build backend
cd /home/explorer/explorer-monorepo/backend
go build -o /usr/local/bin/explorer-indexer ./indexer/main.go
go build -o /usr/local/bin/explorer-api ./api/rest/main.go
go build -o /usr/local/bin/explorer-gateway ./api/gateway/main.go
go build -o /usr/local/bin/explorer-search ./api/search/main.go
# Build frontend
cd /home/explorer/explorer-monorepo/frontend
npm run build
Phase 3: Database Setup
Task 3.1: Install PostgreSQL with TimescaleDB
# Add PostgreSQL repository
sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
apt update
# Install PostgreSQL 16
apt install -y postgresql-16 postgresql-contrib-16
# Add TimescaleDB repository
echo "deb https://packagecloud.io/timescale/timescaledb/ubuntu/ $(lsb_release -c -s) main" > /etc/apt/sources.list.d/timescaledb.list
wget --quiet -O - https://packagecloud.io/timescale/timescaledb/gpgkey | apt-key add -
apt update
# Install TimescaleDB
apt install -y timescaledb-2-postgresql-16
# Tune PostgreSQL for TimescaleDB
timescaledb-tune --quiet --yes
# Restart PostgreSQL
systemctl restart postgresql
Task 3.2: Create Database and User
# Switch to postgres user
su - postgres
# Create database and user
psql << EOF
CREATE USER explorer WITH PASSWORD 'CHANGE_THIS_PASSWORD';
CREATE DATABASE explorer OWNER explorer;
\c explorer
CREATE EXTENSION IF NOT EXISTS timescaledb;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
GRANT ALL PRIVILEGES ON DATABASE explorer TO explorer;
EOF
exit
Task 3.3: Run Migrations
cd /home/explorer/explorer-monorepo/backend
go run database/migrations/migrate.go
Task 3.4: Configure PostgreSQL
# Edit postgresql.conf
vim /etc/postgresql/16/main/postgresql.conf
# Recommended settings:
# max_connections = 100
# shared_buffers = 4GB
# effective_cache_size = 12GB
# maintenance_work_mem = 1GB
# checkpoint_completion_target = 0.9
# wal_buffers = 16MB
# default_statistics_target = 100
# random_page_cost = 1.1
# effective_io_concurrency = 200
# work_mem = 20MB
# min_wal_size = 1GB
# max_wal_size = 4GB
# Edit pg_hba.conf for local connections
vim /etc/postgresql/16/main/pg_hba.conf
# Restart PostgreSQL
systemctl restart postgresql
Phase 4: Infrastructure Services
Task 4.1: Deploy Elasticsearch/OpenSearch
# Create docker-compose for infrastructure
cd /home/explorer/explorer-monorepo/deployment
docker compose -f docker-compose.yml up -d elasticsearch redis
Task 4.2: Verify Services
# Check Elasticsearch
curl http://localhost:9200
# Check Redis
redis-cli ping
Phase 5: Application Services
Task 5.1: Create Environment Configuration
# Create production .env file
cd /home/explorer/explorer-monorepo
cp .env.example .env
vim .env
Required Environment Variables:
# Database
DB_HOST=localhost
DB_PORT=5432
DB_USER=explorer
DB_PASSWORD=<SECURE_PASSWORD>
DB_NAME=explorer
DB_MAX_CONNECTIONS=50
# RPC
# Public RPC Endpoints (ChainID 138) - Internal IP Addresses
# Using internal IP for direct connection (no proxy overhead)
RPC_URL=http://192.168.11.221:8545
WS_URL=ws://192.168.11.221:8546
CHAIN_ID=138
# Alternative: Private RPC endpoints available at http://192.168.11.211:8545 (internal) or https://rpc-http-prv.d-bis.org (public)
# Search
SEARCH_URL=http://localhost:9200
SEARCH_INDEX_PREFIX=explorer-prod
# API
PORT=8080
API_GATEWAY_PORT=8081
CHAIN_ID=138
# Frontend
NEXT_PUBLIC_API_URL=https://explorer.d-bis.org/api
NEXT_PUBLIC_CHAIN_ID=138
Task 5.2: Create Systemd Service Files
Indexer Service
cat > /etc/systemd/system/explorer-indexer.service << 'EOF'
[Unit]
Description=Explorer Indexer Service
After=network.target postgresql.service
Requires=postgresql.service
[Service]
Type=simple
User=explorer
Group=explorer
WorkingDirectory=/home/explorer/explorer-monorepo/backend
EnvironmentFile=/home/explorer/explorer-monorepo/.env
ExecStart=/usr/local/bin/explorer-indexer
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=explorer-indexer
[Install]
WantedBy=multi-user.target
EOF
API Service
cat > /etc/systemd/system/explorer-api.service << 'EOF'
[Unit]
Description=Explorer API Service
After=network.target postgresql.service
Requires=postgresql.service
[Service]
Type=simple
User=explorer
Group=explorer
WorkingDirectory=/home/explorer/explorer-monorepo/backend
EnvironmentFile=/home/explorer/explorer-monorepo/.env
ExecStart=/usr/local/bin/explorer-api
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=explorer-api
[Install]
WantedBy=multi-user.target
EOF
Frontend Service
cat > /etc/systemd/system/solacescanscout-frontend.service << 'EOF'
[Unit]
Description=SolaceScan Next Frontend Service
After=network.target explorer-api.service
Requires=explorer-api.service
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/solacescanscout/frontend/current
Environment=NODE_ENV=production
Environment=HOSTNAME=127.0.0.1
Environment=PORT=3000
ExecStart=/usr/bin/node /opt/solacescanscout/frontend/current/server.js
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=solacescanscout-frontend
[Install]
WantedBy=multi-user.target
EOF
Task 5.3: Enable and Start Services
# Reload systemd
systemctl daemon-reload
# Enable services
systemctl enable explorer-indexer
systemctl enable explorer-api
systemctl enable solacescanscout-frontend
# Start services
systemctl start explorer-indexer
systemctl start explorer-api
systemctl start solacescanscout-frontend
# Check status
systemctl status explorer-indexer
systemctl status explorer-api
systemctl status solacescanscout-frontend
Phase 6: Nginx Reverse Proxy
Task 6.1: Install Nginx
apt install -y nginx
Task 6.2: Install Certbot for SSL
apt install -y certbot python3-certbot-nginx
Task 6.3: Configure Nginx
cat > /etc/nginx/sites-available/explorer << 'EOF'
# Rate limiting zones
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=general_limit:10m rate=50r/s;
# Upstream servers
upstream explorer_api {
server 127.0.0.1:8080;
keepalive 32;
}
upstream explorer_frontend {
server 127.0.0.1:3000;
keepalive 32;
}
# Redirect HTTP to HTTPS
server {
listen 80;
listen [::]:80;
server_name explorer.d-bis.org www.explorer.d-bis.org;
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
return 301 https://$server_name$request_uri;
}
}
# Main HTTPS server
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name explorer.d-bis.org www.explorer.d-bis.org;
# SSL Configuration (Cloudflare will handle SSL)
# Certificates managed by Cloudflare Tunnel
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://unpkg.com https://cdnjs.cloudflare.com; style-src 'self' 'unsafe-inline';" always;
# Logging
access_log /var/log/nginx/explorer-access.log;
error_log /var/log/nginx/explorer-error.log;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript;
# Frontend
location / {
limit_req zone=general_limit burst=20 nodelay;
proxy_pass http://explorer_frontend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
}
# API endpoints
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://explorer_api;
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;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
# CORS headers (if needed before Cloudflare)
add_header Access-Control-Allow-Origin "*" always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, X-API-Key" always;
}
# WebSocket support
location /ws {
proxy_pass http://explorer_api;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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_read_timeout 86400s;
}
# Static files caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# Health check endpoint (internal)
location /health {
access_log off;
proxy_pass http://explorer_api/health;
}
}
EOF
# Enable site
ln -s /etc/nginx/sites-available/explorer /etc/nginx/sites-enabled/
rm /etc/nginx/sites-enabled/default
# Test configuration
nginx -t
# Reload Nginx
systemctl reload nginx
Phase 7: Cloudflare Configuration
Task 7.1: Set Up Cloudflare DNS Records
-
Login to Cloudflare Dashboard
- Go to https://dash.cloudflare.com
- Select your domain
-
Add DNS Records
-
A Record (if using direct connection):
- Type: A
- Name: explorer (or @)
- IPv4: [Your server IP]
- Proxy: Proxied (orange cloud)
- TTL: Auto
-
CNAME Record (for www):
- Type: CNAME
- Name: www
- Target: explorer.d-bis.org
- Proxy: Proxied
- TTL: Auto
-
Task 7.2: Configure Cloudflare SSL/TLS
-
Go to SSL/TLS Settings
- Dashboard → SSL/TLS → Overview
-
Set SSL/TLS Encryption Mode
- Select: Full (strict)
- This ensures end-to-end encryption
-
Configure SSL/TLS Options
- Enable: Always Use HTTPS
- Enable: Automatic HTTPS Rewrites
- Enable: Opportunistic Encryption
- Enable: TLS 1.3
- Enable: Automatic Certificate Management
Task 7.3: Set Up Cloudflare Tunnel
Option A: Cloudflare Tunnel (Recommended for no public IP)
# Install cloudflared
cd /tmp
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
dpkg -i cloudflared-linux-amd64.deb
# Authenticate with Cloudflare
cloudflared tunnel login
# Create tunnel
cloudflared tunnel create explorer-tunnel
# Get tunnel ID
cloudflared tunnel list
# Create config file
mkdir -p /etc/cloudflared
cat > /etc/cloudflared/config.yml << EOF
tunnel: <TUNNEL_ID>
credentials-file: /etc/cloudflared/<TUNNEL_ID>.json
ingress:
- hostname: explorer.d-bis.org
service: http://localhost:80
- hostname: www.explorer.d-bis.org
service: http://localhost:80
- service: http_status:404
EOF
# Run tunnel
cloudflared tunnel --config /etc/cloudflared/config.yml run
# Create systemd service
cloudflared service install
# Start tunnel service
systemctl enable cloudflared
systemctl start cloudflared
Option B: Direct Connection (If public IP available)
-
Update DNS Records (from Task 7.1)
- Set A record to your public IP
- Ensure proxy is enabled (orange cloud)
-
Configure Cloudflare Page Rules (Optional)
- Cache static assets
- Bypass cache for API endpoints
Task 7.4: Configure Cloudflare WAF
-
Go to Security → WAF
- Enable Cloudflare Managed Ruleset
- Enable OWASP Core Ruleset
- Configure custom rules as needed
-
Rate Limiting Rules
- Create rule: API rate limiting
- Action: Challenge or Block
- Rate: 100 requests per minute per IP
Task 7.5: Configure Cloudflare Caching
-
Go to Caching → Configuration
- Caching Level: Standard
- Browser Cache TTL: Respect Existing Headers
-
Create Cache Rules
- Static Assets: Cache everything, Edge TTL: 1 year
- API Endpoints: Bypass cache
- Frontend Pages: Cache HTML for 5 minutes
Phase 8: Security Hardening
Task 8.1: Configure Firewall (UFW)
# Enable UFW
ufw --force enable
# Allow SSH
ufw allow 22/tcp
# Allow HTTP/HTTPS (if direct connection)
ufw allow 80/tcp
ufw allow 443/tcp
# Allow Cloudflare Tunnel (if using)
ufw allow from 173.245.48.0/20
ufw allow from 103.21.244.0/22
ufw allow from 103.22.200.0/22
ufw allow from 103.31.4.0/22
ufw allow from 141.101.64.0/18
ufw allow from 108.162.192.0/18
ufw allow from 190.93.240.0/20
ufw allow from 188.114.96.0/20
ufw allow from 197.234.240.0/22
ufw allow from 198.41.128.0/17
ufw allow from 162.158.0.0/15
ufw allow from 104.16.0.0/13
ufw allow from 104.24.0.0/14
ufw allow from 172.64.0.0/13
ufw allow from 131.0.72.0/22
# Check status
ufw status verbose
Task 8.2: Configure Fail2ban
# Create Nginx jail
cat > /etc/fail2ban/jail.d/nginx.conf << 'EOF'
[nginx-limit-req]
enabled = true
port = http,https
logpath = /var/log/nginx/explorer-error.log
maxretry = 10
findtime = 600
bantime = 3600
[nginx-botsearch]
enabled = true
port = http,https
logpath = /var/log/nginx/explorer-access.log
maxretry = 2
findtime = 600
bantime = 86400
EOF
# Restart fail2ban
systemctl restart fail2ban
fail2ban-client status
Task 8.3: Configure Automatic Updates
# Configure unattended-upgrades
cat > /etc/apt/apt.conf.d/50unattended-upgrades << 'EOF'
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::MinimalSteps "true";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "false";
EOF
# Enable automatic updates
systemctl enable unattended-upgrades
systemctl start unattended-upgrades
Task 8.4: Configure Log Rotation
# Configure logrotate for application logs
cat > /etc/logrotate.d/explorer << 'EOF'
/var/log/explorer/*.log {
daily
rotate 30
compress
delaycompress
notifempty
missingok
create 0640 explorer explorer
sharedscripts
postrotate
systemctl reload explorer-indexer explorer-api solacescanscout-frontend > /dev/null 2>&1 || true
endscript
}
EOF
Task 8.5: Set Up Backup Strategy
# Create backup script
cat > /usr/local/bin/explorer-backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/backups/explorer"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
# Backup database
pg_dump -U explorer explorer | gzip > $BACKUP_DIR/db_$DATE.sql.gz
# Backup configuration
tar -czf $BACKUP_DIR/config_$DATE.tar.gz \
/home/explorer/explorer-monorepo/.env \
/etc/nginx/sites-available/explorer \
/etc/systemd/system/explorer-*.service
# Cleanup old backups (keep 30 days)
find $BACKUP_DIR -type f -mtime +30 -delete
EOF
chmod +x /usr/local/bin/explorer-backup.sh
# Add to crontab (daily at 2 AM)
(crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/explorer-backup.sh") | crontab -
Phase 9: Monitoring & Maintenance
Task 9.1: Set Up Health Checks
# Create health check script
cat > /usr/local/bin/explorer-health-check.sh << 'EOF'
#!/bin/bash
API_URL="http://localhost:8080/health"
STATUS=$(curl -s -o /dev/null -w "%{http_code}" $API_URL)
if [ $STATUS -ne 200 ]; then
systemctl restart explorer-api
# Send alert (configure email/Slack/etc)
fi
EOF
chmod +x /usr/local/bin/explorer-health-check.sh
# Add to crontab (every 5 minutes)
(crontab -l 2>/dev/null; echo "*/5 * * * * /usr/local/bin/explorer-health-check.sh") | crontab -
Task 9.2: Configure Log Monitoring
# Install log monitoring tools
apt install -y logwatch
# Configure logwatch
vim /etc/logwatch/conf/logwatch.conf
Task 9.3: Set Up Cloudflare Analytics
-
Go to Analytics → Web Traffic
- Monitor request rates
- Track error rates
- Monitor cache hit ratios
-
Set Up Alerts
- High error rate alerts
- DDoS detection alerts
- Certificate expiration alerts
Post-Deployment Checklist
- All services running and healthy
- DNS resolving correctly
- SSL certificates active
- Cloudflare Tunnel connected (if using)
- Nginx proxying correctly
- API endpoints responding
- Frontend loading correctly
- Database migrations complete
- Indexer processing blocks
- Firewall rules configured
- Backups configured and tested
- Monitoring and alerts configured
- Documentation updated
Troubleshooting
Service Not Starting
# Check service status
systemctl status explorer-api
journalctl -u explorer-api -f
# Check logs
journalctl -u explorer-api --since "1 hour ago"
Database Connection Issues
# Test connection
psql -U explorer -d explorer -h localhost
# Check PostgreSQL logs
tail -f /var/log/postgresql/postgresql-16-main.log
Nginx Issues
# Test configuration
nginx -t
# Check error logs
tail -f /var/log/nginx/explorer-error.log
Cloudflare Tunnel Issues
# Check tunnel status
systemctl status cloudflared
cloudflared tunnel info explorer-tunnel
# View tunnel logs
journalctl -u cloudflared -f
Maintenance Tasks
Daily
- Monitor service status
- Check error logs
- Review Cloudflare analytics
Weekly
- Review security logs
- Check disk space
- Verify backups
Monthly
- Update system packages
- Review and optimize database
- Update application dependencies
- Review and adjust resource allocation
Security Notes
- Never commit .env files with real credentials
- Rotate passwords regularly
- Keep system updated with security patches
- Monitor logs for suspicious activity
- Review Cloudflare WAF logs regularly
- Backup database daily
- Test disaster recovery procedures quarterly
Support & Resources
- Cloudflare Docs: https://developers.cloudflare.com/
- Nginx Docs: https://nginx.org/en/docs/
- Proxmox Docs: https://pve.proxmox.com/pve-docs/
- Project Docs: See
docs/directory
Last Updated: 2024-12-23 Version: 1.0.0