TWN Stack

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

ComponentSpecificationPurpose
Proxmox VE8.0+Hypervisor cluster
Paymenter VM4 vCPU, 8GB RAM, 100GB SSDApplication server
PostgreSQL VM4 vCPU, 8GB RAM, 200GB SSDDatabase server
Redis VM2 vCPU, 4GB RAM, 50GB SSDCache server
StorageCeph or ZFSVM 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

  1. Log in to Proxmox VE web interface
  2. Navigate to Datacenter > Permissions > API Tokens
  3. Click Add
  4. Select user: root@pam (or create dedicated paymenter@pve user)
  5. Token ID: paymenter
  6. Uncheck "Privilege Separation" (for full access)
  7. 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:

  1. Navigate to: Admin > Products > Create

  2. Product Types:

    • VPS (KVM)
    • Storage (S3-compatible)
    • Kubernetes Cluster
  3. Proxmox Settings per Product:

    • Node selection
    • Template ID
    • Resource limits (CPU, RAM, Disk)
    • Network configuration

Pricing Configuration

Example pricing structure:

ResourceUnit PriceBilling Cycle
vCPU$5/monthMonthly
RAM (GB)$3/monthMonthly
Storage (GB)$0.05/monthMonthly

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

IssueSolution
500 ErrorCheck storage/logs/laravel.log
Queue not processingRestart worker: systemctl restart paymenter-worker
Proxmox connection failedVerify API token and SSL settings
Database connection refusedCheck pg_hba.conf and firewall
Slow performanceEnable 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