211 lines
5.6 KiB
Markdown
211 lines
5.6 KiB
Markdown
# 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
|
|
```nix
|
|
# 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
|
|
```nix
|
|
# 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
|
|
```nix
|
|
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
|
|
1. Fetch Bitpoll source from GitHub
|
|
2. Create Python environment with core packages
|
|
3. Generate settings_local.py configuration
|
|
4. Install additional packages via pip
|
|
5. Create wrapper scripts with proper PYTHONPATH
|
|
6. Set up executable permissions
|
|
|
|
### 2. Service Deployment Path
|
|
1. Create bitpoll user and group
|
|
2. Initialize data directory with proper permissions
|
|
3. Run database migrations
|
|
4. Collect static files
|
|
5. Compile message translations
|
|
6. Start systemd service
|
|
|
|
### 3. Configuration Resolution Path
|
|
1. Build-time defaults in settings_local.py
|
|
2. NixOS module option overrides
|
|
3. Environment variable overrides
|
|
4. 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
|