5.6 KiB
5.6 KiB
System Patterns: Bitpoll Nix Flake
Architecture Overview
Flake Structure
bitpoll-nix/
├── flake.nix # Main flake definition
├── flake.lock # Pinned dependencies
├── example-configuration.nix # Usage example
└── memory-bank/ # Documentation
Key Components
1. Package Definition (bitpoll
)
- Source: Fetched from GitHub (fsinfuhh/Bitpoll)
- Build Process: Standard derivation with Python environment
- Dependencies: Comprehensive Python package set
- Outputs: Executable scripts and shared files
2. NixOS Module (nixosModules.bitpoll
)
- Service Configuration: Systemd service definition
- User Management: Dedicated bitpoll user/group
- Security Hardening: Comprehensive systemd restrictions
- Data Management: Proper directory permissions
3. Applications (apps
)
- bitpoll-server: Main web server application
- bitpoll-manage: Django management commands
Technical Patterns
Dependency Management Pattern
# Python environment with comprehensive packages
pythonEnv = pkgs.python3.withPackages (ps: with ps; [
# Core Django
django
# Calendar handling
caldav icalendar python-dateutil pytz
# Security
cryptography django-encrypted-model-fields
# Additional packages via pip in postInstall
]);
Key Decisions:
- Use
python3.withPackages
for core dependencies - Install missing packages via pip in
postInstall
- Separate PYTHONPATH management for proper module resolution
Configuration Management Pattern
# Generate settings_local.py at build time
settingsLocal = pkgs.writeText "settings_local.py" ''
import os
import secrets
SECRET_KEY = os.environ.get('BITPOLL_SECRET_KEY', secrets.token_urlsafe(50))
# ... additional settings
'';
Key Decisions:
- Build-time configuration generation
- Environment variable override support
- Secure defaults with runtime key generation
- Production-ready database and static file paths
Service Architecture Pattern
systemd.services.bitpoll = {
# Service definition
preStart = ''
# Database migrations
# Static file collection
# Permission management
'';
serviceConfig = {
# Security hardening
# User isolation
# Resource restrictions
};
};
Key Decisions:
- Automatic database migrations in preStart
- Comprehensive security hardening
- Proper data directory management
- Graceful restart handling
Design Patterns
1. Layered Configuration
- Build-time: Static configuration in settings_local.py
- Deploy-time: NixOS module options
- Runtime: Environment variable overrides
2. Security-First Design
- Dedicated system user (bitpoll:bitpoll)
- Restricted filesystem access
- No new privileges
- Private temporary directories
- Protected system directories
3. Data Persistence Strategy
- Single data directory:
/var/lib/bitpoll
- Subdirectories:
static/
,media/
, database file - Proper ownership and permissions
- Backup-friendly structure
4. Development vs Production
- Development:
nix develop
shell with tools - Production: Hardened systemd service
- Testing: Direct package execution
- Management: Dedicated management commands
Component Relationships
Build Dependencies
flake.nix
├── nixpkgs (NixOS 25.05)
├── flake-utils (cross-platform)
└── bitpoll source (GitHub)
Runtime Dependencies
bitpoll package
├── Python environment
│ ├── Django ecosystem
│ ├── Calendar libraries
│ └── Security libraries
├── System libraries
│ ├── OpenLDAP
│ └── Cyrus SASL
└── Generated configuration
Service Dependencies
systemd service
├── network.target (after)
├── bitpoll package
├── data directory
└── optional secret files
Critical Implementation Paths
1. Package Build Path
- Fetch Bitpoll source from GitHub
- Create Python environment with core packages
- Generate settings_local.py configuration
- Install additional packages via pip
- Create wrapper scripts with proper PYTHONPATH
- Set up executable permissions
2. Service Deployment Path
- Create bitpoll user and group
- Initialize data directory with proper permissions
- Run database migrations
- Collect static files
- Compile message translations
- Start systemd service
3. Configuration Resolution Path
- Build-time defaults in settings_local.py
- NixOS module option overrides
- Environment variable overrides
- Secret file content injection
Error Handling Patterns
Build-time Errors
- Missing dependencies → Comprehensive package list
- Python path issues → Explicit PYTHONPATH management
- Permission errors → Proper build environment setup
Runtime Errors
- Database issues → Automatic migration in preStart
- Permission errors → Proper user/group setup
- Configuration errors → Clear error messages and validation
Service Errors
- Startup failures → Restart policy with backoff
- Resource exhaustion → systemd resource limits
- Security violations → Comprehensive hardening rules
Performance Considerations
Build Performance
- Pinned dependencies for reproducible builds
- Efficient Python environment construction
- Minimal rebuild triggers
Runtime Performance
- Optimized Django settings
- Proper static file serving
- Database connection management
- Resource-constrained systemd service
Memory Management
- Python environment isolation
- Proper garbage collection
- systemd memory limits
- Efficient static file caching