Paymenter Deployment on Proxmox
Complete guide to deploying Paymenter billing backend on Proxmox VE
Paymenter Deployment on Proxmox VE
This guide covers the complete deployment of Paymenter—an open-source billing and client management panel—on Proxmox VE for tasmanian.cloud's billing backend.
Overview
Paymenter serves as the billing backend for tasmanian.cloud. It integrates with Proxmox VE to provide automated VM provisioning, billing, and invoicing. The customer-facing interface is OpenSelfServe (O2S), which communicates with Paymenter for billing operations.
Key Features
- Automated Provisioning: VM creation and management via Proxmox API
- Billing & Invoicing: Automated billing cycles, payment processing
- Product Management: Configurable service plans and pricing
- Multi-gateway Payments: Stripe, PayPal, and custom integrations
- Ticket System: Built-in support ticketing
- Extensible: Plugin architecture for custom extensions
Architecture
flowchart TB
subgraph "Internet"
Users[Customers]
Admin[Administrators]
end
subgraph "tasmanian.cloud Network"
subgraph "DMZ"
LB[HAProxy Load Balancer]
WAF[Cloudflare/WAF]
end
subgraph "Application Tier"
O2S[OpenSelfServe
Customer Portal]
Paymenter[Paymenter
Billing Backend]
Redis[Redis Cache]
end
subgraph "Database Tier"
Postgres[(PostgreSQL
Primary)]
PostgresRep[(PostgreSQL
Replica)]
end
subgraph "Proxmox Cluster"
PVE1[Proxmox Node 1]
PVE2[Proxmox Node 2]
PVE3[Proxmox Node 3]
CEPH[Ceph Storage Cluster]
end
end
Users -->|HTTPS| WAF --> LB
Admin -->|HTTPS| WAF --> LB
LB --> O2S
O2S --> Paymenter
Paymenter --> Redis
Paymenter --> Postgres
Postgres -->|Replication| PostgresRep
Paymenter -->|API| PVE1
Paymenter -->|API| PVE2
Paymenter -->|API| PVE3
PVE1 --> CEPH
PVE2 --> CEPH
PVE3 --> CEPH
Prerequisites
Infrastructure Requirements
| Component | Specification | Purpose |
|---|---|---|
| Proxmox VE | 8.0+ | Hypervisor cluster |
| Paymenter VM | 4 vCPU, 8GB RAM, 100GB SSD | Application server |
| PostgreSQL VM | 4 vCPU, 8GB RAM, 200GB SSD | Database server |
| Redis VM | 2 vCPU, 4GB RAM, 50GB SSD | Cache server |
| Storage | Ceph or ZFS | VM disk storage |
Software Requirements
- OS: Debian 12 (Bookworm) or Ubuntu 22.04 LTS
- Web Server: Nginx or Apache
- PHP: 8.2+ with required extensions
- Database: PostgreSQL 15+ or MySQL 8.0+
- Cache: Redis 7.0+
- Queue: Redis or RabbitMQ
Network Requirements
- Internal network access to Proxmox API (port 8006)
- Internal access from O2S portal
- Outbound for payment gateways
Installation
Step 1: Create Proxmox VM
Create a new VM in Proxmox for the Paymenter application:
# On Proxmox host
qm create 9000 \
--name paymenter-app \
--memory 8192 \
--cores 4 \
--cpu host \
--net0 virtio,bridge=vmbr0 \
--scsihw virtio-scsi-single \
--scsi0 local-zfs:100,format=raw \
--ostype l26 \
--agent enabled=1
# Import Debian cloud image
wget https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2
qm disk import 9000 debian-12-generic-amd64.qcow2 local-zfs
qm set 9000 --scsi0 local-zfs:vm-9000-disk-1
# Configure cloud-init
qm set 9000 --ide2 local-zfs:cloudinit
qm set 9000 --ciuser paymenter
qm set 9000 --cipassword $(openssl rand -base64 32)
qm set 9000 --ipconfig0 ip=10.0.10.50/24,gw=10.0.10.1
qm set 9000 --nameserver 1.1.1.1
qm set 9000 --sshkeys ~/.ssh/id_rsa.pub
Step 2: System Preparation
# Update system
apt update && apt upgrade -y
# Install dependencies
apt install -y \
nginx \
php8.2-fpm \
php8.2-cli \
php8.2-pgsql \
php8.2-redis \
php8.2-mbstring \
php8.2-xml \
php8.2-curl \
php8.2-zip \
php8.2-bcmath \
php8.2-gd \
php8.2-intl \
composer \
redis-server \
postgresql-client \
git \
curl \
unzip \
certbot \
python3-certbot-nginx
# Configure PHP
sed -i 's/memory_limit = .*/memory_limit = 512M/' /etc/php/8.2/fpm/php.ini
sed -i 's/max_execution_time = .*/max_execution_time = 300/' /etc/php/8.2/fpm/php.ini
sed -i 's/upload_max_filesize = .*/upload_max_filesize = 100M/' /etc/php/8.2/fpm/php.ini
systemctl restart php8.2-fpm
Step 3: Database Setup
# On PostgreSQL server
sudo -u postgres psql
CREATE DATABASE paymenter;
CREATE USER paymenter WITH ENCRYPTED PASSWORD 'your_secure_password';
GRANT ALL PRIVILEGES ON DATABASE paymenter TO paymenter;
\q
# Allow Paymenter VM access
# Edit /etc/postgresql/15/main/pg_hba.conf
host paymenter paymenter 10.0.10.50/32 scram-sha-256
# Restart PostgreSQL
systemctl restart postgresql
Step 4: Install Paymenter
# Create application directory
mkdir -p /var/www/paymenter
cd /var/www/paymenter
# Clone Paymenter (or download release)
git clone https://github.com/paymenter/paymenter.git .
# Install dependencies
composer install --no-dev --optimize-autoloader
# Set permissions
chown -R www-data:www-data /var/www/paymenter
chmod -R 755 /var/www/paymenter
chmod -R 775 /var/www/paymenter/storage
chmod -R 775 /var/www/paymenter/bootstrap/cache
# Create environment file
cp .env.example .env
Step 5: Configure Environment
Edit /var/www/paymenter/.env:
APP_NAME="tasmanian.cloud Billing"
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=https://billing.internal.tasmanian.cloud
LOG_CHANNEL=stack
LOG_LEVEL=error
DB_CONNECTION=pgsql
DB_HOST=10.0.10.10
DB_PORT=5432
DB_DATABASE=paymenter
DB_USERNAME=paymenter
DB_PASSWORD=your_secure_password
BROADCAST_DRIVER=redis
CACHE_DRIVER=redis
FILESYSTEM_DISK=local
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis
SESSION_LIFETIME=120
REDIS_HOST=10.0.10.20
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mail.tasmanian.cloud
MAIL_PORT=587
MAIL_USERNAME=noreply@tasmanian.cloud
MAIL_PASSWORD=your_mail_password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=noreply@tasmanian.cloud
MAIL_FROM_NAME="tasmanian.cloud"
# Proxmox Integration
PROXMOX_HOST=https://pve1.internal.tasmanian.cloud:8006
PROXMOX_USER=paymenter@pve
PROXMOX_TOKEN_NAME=paymenter
PROXMOX_TOKEN_SECRET=your-api-token
PROXMOX_VERIFY_SSL=true
Generate application key:
cd /var/www/paymenter
php artisan key:generate
Step 6: Database Migration
cd /var/www/paymenter
php artisan migrate --force
php artisan db:seed --force
Step 7: Queue Worker Setup
Create /etc/systemd/system/paymenter-worker.service:
[Unit]
Description=Paymenter Queue Worker
After=network.target
[Service]
User=www-data
Group=www-data
Restart=always
ExecStart=/usr/bin/php /var/www/paymenter/artisan queue:work --sleep=3 --tries=3 --max-time=3600
[Install]
WantedBy=multi-user.target
Enable and start:
systemctl daemon-reload
systemctl enable paymenter-worker
systemctl start paymenter-worker
Step 8: Schedule Tasks
Add to crontab:
# Edit crontab for www-data
sudo crontab -u www-data -e
# Add line
* * * * * cd /var/www/paymenter && php artisan schedule:run >> /dev/null 2>&1
Step 9: Nginx Configuration
Create /etc/nginx/sites-available/paymenter:
server {
listen 80;
server_name billing.internal.tasmanian.cloud;
root /var/www/paymenter/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By;
}
location ~ /\.(?!well-known).* {
deny all;
}
# Security headers
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;
}
Enable site:
ln -s /etc/nginx/sites-available/paymenter /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
Proxmox Integration
API Token Creation
- Log in to Proxmox VE web interface
- Navigate to Datacenter > Permissions > API Tokens
- Click Add
- Select user:
root@pam(or create dedicatedpaymenter@pveuser) - Token ID:
paymenter - Uncheck "Privilege Separation" (for full access)
- Copy the generated token secret
Required Permissions
Create a dedicated role for Paymenter:
# On Proxmox host
pveum role add Paymenter -privs "VM.Allocate VM.Audit VM.Config.Disk VM.Config.CPU VM.Config.Memory VM.Config.Network VM.Config.Options VM.Console VM.Monitor VM.PowerMgmt Datastore.AllocateSpace Datastore.Audit Sys.Audit Sys.Console"
# Create user
pveum user add paymenter@pve --password $(openssl rand -base64 32)
# Assign role
pveum aclmod / -user paymenter@pve -role Paymenter
VM Templates
Create base templates for automated provisioning:
# Download cloud images
wget https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2
# Create VM template
qm create 9001 --name debian-12-template --memory 2048 --cores 2
qm importdisk 9001 debian-12-generic-amd64.qcow2 local-zfs
qm set 9001 --scsi0 local-zfs:vm-9001-disk-0
qm set 9001 --ide2 local-zfs:cloudinit
qm set 9001 --boot order=scsi0
qm set 9001 --serial0 socket --vga serial0
qm set 9001 --agent enabled=1
qm template 9001
Configuration
Product Configuration
Create products in Paymenter admin panel:
-
Navigate to: Admin > Products > Create
-
Product Types:
- VPS (KVM)
- Storage (S3-compatible)
- Kubernetes Cluster
-
Proxmox Settings per Product:
- Node selection
- Template ID
- Resource limits (CPU, RAM, Disk)
- Network configuration
Pricing Configuration
Example pricing structure:
| Resource | Unit Price | Billing Cycle |
|---|---|---|
| vCPU | $5/month | Monthly |
| RAM (GB) | $3/month | Monthly |
| Storage (GB) | $0.05/month | Monthly |
Security Hardening
Firewall Rules
# UFW configuration
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow from 10.0.10.0/24 to any port 80 # Only internal access
ufw allow from 10.0.10.0/24 to any port 5432 # PostgreSQL
ufw allow from 10.0.10.0/24 to any port 6379 # Redis
ufw enable
Fail2Ban
Create /etc/fail2ban/jail.local:
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
[nginx-http-auth]
enabled = true
[nginx-limit-req]
enabled = true
filter = nginx-limit-req
action = iptables-multiport[name=ReqLimit, port="http,https", protocol=tcp]
logpath = /var/log/nginx/error.log
Backup Strategy
# Database backup script
#!/bin/bash
BACKUP_DIR="/backup/paymenter"
DATE=$(date +%Y%m%d_%H%M%S)
# PostgreSQL backup
pg_dump -h 10.0.10.10 -U paymenter paymenter | gzip > $BACKUP_DIR/db_$DATE.sql.gz
# File backup
tar -czf $BACKUP_DIR/files_$DATE.tar.gz /var/www/paymenter/storage
# Retention: Keep 30 days
find $BACKUP_DIR -name "*.gz" -mtime +30 -delete
Troubleshooting
Common Issues
| Issue | Solution |
|---|---|
| 500 Error | Check storage/logs/laravel.log |
| Queue not processing | Restart worker: systemctl restart paymenter-worker |
| Proxmox connection failed | Verify API token and SSL settings |
| Database connection refused | Check pg_hba.conf and firewall |
| Slow performance | Enable Redis caching, optimize queries |
Log Locations
/var/www/paymenter/storage/logs/laravel.log # Application logs
/var/log/nginx/error.log # Nginx errors
/var/log/postgresql/postgresql-15-main.log # Database logs
/var/log/redis/redis-server.log # Redis logs
journalctl -u paymenter-worker # Queue worker logs
Maintenance Mode
cd /var/www/paymenter
php artisan down --message="Maintenance in progress" --retry=60
# ... perform maintenance ...
php artisan up
Updates
Update Procedure
cd /var/www/paymenter
# Enable maintenance mode
php artisan down
# Backup first
pg_dump -h 10.0.10.10 -U paymenter paymenter > backup_$(date +%Y%m%d).sql
# Pull updates
git pull origin main
composer install --no-dev --optimize-autoloader
# Run migrations
php artisan migrate --force
# Clear caches
php artisan cache:clear
php artisan config:clear
php artisan view:clear
# Restart worker
systemctl restart paymenter-worker
# Disable maintenance mode
php artisan up