8.9 KiB
Container Deployment (LXC)
BotServer uses LXC (Linux Containers) for isolated component deployment. This provides system-level containerization without the overhead of full virtualization.
What is LXC?
LXC is a lightweight container technology that runs on Linux:
- System containers - Full Linux userspace (like lightweight VMs)
- Shared kernel - More efficient than virtual machines
- Isolation - Separate process trees, networking, filesystems
- Resource control - CPU, memory, and I/O limits
BotServer uses LXC to run PostgreSQL, drive, and cache in isolated containers.
Automatic Container Setup
When you run BotServer with --container flag:
./botserver --container
The bootstrap process automatically:
- Detects LXC/LXD - Checks if
lxccommand is available - Initializes LXD - Runs
lxd init --autoif needed - Creates containers - Launches Debian 12 containers for each component
- Mounts directories - Binds host paths for persistent data
- Configures networking - Maps container ports to localhost
- Installs components - Runs installation inside containers
- Creates services - Sets up systemd inside containers
- Starts containers - Everything starts automatically
Container Architecture
Container Naming
Each component runs in a dedicated container:
{tenant}-tables → PostgreSQL database
{tenant}-drive → Drive (S3-compatible object storage)
{tenant}-cache → Cache (Valkey)
{tenant}-llm → LLM server (optional)
{tenant}-email → Stalwart mail (optional)
Default tenant is default, so containers are named:
default-tablesdefault-drivedefault-cache
Directory Mounting
Host directories are mounted into containers for persistence:
Host: botserver-stack/tables/data/
→ Container: /opt/gbo/data/
Host: botserver-stack/tables/conf/
→ Container: /opt/gbo/conf/
Host: botserver-stack/tables/logs/
→ Container: /opt/gbo/logs/
Data persists even if containers are deleted!
Port Forwarding
Container ports are mapped to localhost:
Container: 5432 → Host: 5432 (PostgreSQL)
Container: 9000 → Host: 9000 (Drive API)
Container: 9001 → Host: 9001 (Drive Console)
Container: 6379 → Host: 6379 (Cache)
Access services on localhost as if they were running natively!
Manual Container Operations
List Containers
lxc list
Output:
+----------------+---------+----------------------+
| NAME | STATE | IPV4 |
+----------------+---------+----------------------+
| default-tables | RUNNING | 10.x.x.x (eth0) |
| default-drive | RUNNING | 10.x.x.x (eth0) |
| default-cache | RUNNING | 10.x.x.x (eth0) |
+----------------+---------+----------------------+
Execute Commands in Container
# PostgreSQL container
lxc exec default-tables -- psql -U gbuser botserver
# Drive container
lxc exec default-drive -- mc admin info local
# Cache container
lxc exec default-cache -- valkey-cli ping
View Container Logs
# Container system logs
lxc exec default-tables -- journalctl -u tables
# Service logs (mounted from host)
tail -f botserver-stack/tables/logs/postgresql.log
Stop/Start Containers
# Stop a container
lxc stop default-tables
# Start a container
lxc start default-tables
# Restart a container
lxc restart default-drive
Delete Containers
# Stop and delete
lxc stop default-tables
lxc delete default-tables
# Or force delete
lxc delete default-tables --force
Note: Data in mounted directories persists!
Container Configuration
Resource Limits
Limit CPU and memory per container:
# Limit to 2 CPU cores
lxc config set default-tables limits.cpu 2
# Limit to 4GB RAM
lxc config set default-tables limits.memory 4GB
# View configuration
lxc config show default-tables
Privileged vs Unprivileged
By default, BotServer creates privileged containers for compatibility:
lxc launch images:debian/12 default-tables \
-c security.privileged=true
For better security, use unprivileged containers (may require additional setup):
lxc launch images:debian/12 default-tables \
-c security.privileged=false
Storage Backends
LXC supports multiple storage backends:
- dir - Simple directory (default)
- btrfs - Copy-on-write filesystem
- zfs - Advanced filesystem with snapshots
- lvm - Logical volume management
Check current backend:
lxc storage list
Advanced Usage
Container Snapshots
Create snapshots before updates:
# Create snapshot
lxc snapshot default-tables backup-2024-01-15
# List snapshots
lxc info default-tables
# Restore snapshot
lxc restore default-tables backup-2024-01-15
# Delete snapshot
lxc delete default-tables/backup-2024-01-15
Container Cloning
Clone containers for testing:
# Clone a container
lxc copy default-tables test-tables
# Start the clone
lxc start test-tables
Network Configuration
View container network:
# Show network interfaces
lxc exec default-tables -- ip addr
# Show network devices
lxc config device show default-tables
Add additional network interfaces:
lxc config device add default-tables eth1 nic \
nictype=bridged parent=lxdbr0
Troubleshooting
LXC Not Installed
# Ubuntu/Debian
sudo snap install lxd
sudo lxd init --auto
# Or APT (older)
sudo apt install lxd lxd-client
sudo lxd init --auto
Permission Denied
# Add your user to lxd group
sudo usermod -aG lxd $USER
# Logout and login again
newgrp lxd
Container Won't Start
# Check container status
lxc info default-tables
# View container logs
lxc console default-tables --show-log
# Check for errors
lxc exec default-tables -- dmesg | tail
Port Already in Use
# Check what's using the port
sudo netstat -tulpn | grep 5432
# Change port forwarding
lxc config device remove default-tables port-5432
lxc config device add default-tables port-5433 proxy \
listen=tcp:0.0.0.0:5433 connect=tcp:127.0.0.1:5432
Container Can't Access Network
# Restart LXD networking
sudo systemctl restart lxd-agent
# Check firewall rules
sudo iptables -L
Monitoring
Resource Usage
# CPU and memory usage
lxc list --columns ns4t
# Detailed info
lxc info default-tables
Disk Usage
# Check container disk usage
lxc exec default-tables -- df -h
# Check all containers
lxc list --format json | jq -r '.[].name' | while read container; do
echo -n "$container: "
lxc exec $container -- df -h / --output=used | tail -n1
done
Process Monitoring
# Show processes in container
lxc exec default-tables -- ps aux
# Show top processes
lxc exec default-tables -- htop
Security Best Practices
1. Use Unprivileged Containers
When possible, avoid privileged containers:
lxc launch images:debian/12 default-tables \
-c security.privileged=false
2. Isolate Networks
Create separate networks for different tenants:
lxc network create tenant1-net
lxc network attach tenant1-net tenant1-tables eth0
3. Limit Resources
Prevent resource exhaustion:
lxc config set default-tables limits.cpu 4
lxc config set default-tables limits.memory 8GB
lxc config set default-tables limits.disk 50GB
4. Regular Updates
Keep containers updated:
lxc exec default-tables -- apt update
lxc exec default-tables -- apt upgrade -y
5. Backup Snapshots
Regular snapshots for disaster recovery:
# Create daily snapshot
lxc snapshot default-tables daily-$(date +%Y%m%d)
# Automated with cron
0 2 * * * lxc snapshot default-tables daily-$(date +\%Y\%m\%d)
Container vs Local Mode
When to Use Containers
✅ Use containers when:
- You want clean isolation
- Running multiple BotServer instances
- Easy cleanup/reinstall is important
- Testing new versions
- Security isolation is critical
When to Use Local Mode
✅ Use local when:
- Maximum performance needed
- LXC not available
- Simple single-instance deployment
- Direct access to services preferred
Migration
Local to Container
- Export data from local installation
- Install in container mode
- Import data
# Backup local data
pg_dump botserver > backup.sql
# Switch to container mode
./botserver --container
# Restore data
lxc exec default-tables -- psql -U gbuser botserver < backup.sql
Container to Local
# Backup from container
lxc exec default-tables -- pg_dump -U gbuser botserver > backup.sql
# Uninstall containers
./botserver uninstall tables
# Install locally
./botserver install tables --local
# Restore data
psql -U gbuser botserver < backup.sql
Next Steps
- Architecture Overview - Understand the system design
- Building from Source - Compile with container support
- Service Layer - Learn about service management