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/explorer-frontend.service << 'EOF'
[Unit]
Description=Explorer Frontend Service
After=network.target explorer-api.service
Requires=explorer-api.service
[Service]
Type=simple
User=explorer
Group=explorer
WorkingDirectory=/home/explorer/explorer-monorepo/frontend
EnvironmentFile=/home/explorer/explorer-monorepo/.env
ExecStart=/usr/bin/npm start
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=explorer-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 explorer-frontend
# Start services
systemctl start explorer-indexer
systemctl start explorer-api
systemctl start explorer-frontend
# Check status
systemctl status explorer-indexer
systemctl status explorer-api
systemctl status explorer-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 explorer-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