Add initial Bitpoll Nix flake and example configuration
This commit is contained in:
		
							parent
							
								
									1b58a0ded8
								
							
						
					
					
						commit
						8de81ea2ab
					
				
					 4 changed files with 631 additions and 0 deletions
				
			
		
							
								
								
									
										186
									
								
								README.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								README.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,186 @@
 | 
				
			||||||
 | 
					# Bitpoll Nix Flake
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This repository provides a Nix flake for [Bitpoll](https://github.com/fsinfuhh/Bitpoll), a web application for scheduling meetings and general polling.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Features
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- ✅ **Nix Flake**: Uses NixOS 25.05 with pinned dependencies
 | 
				
			||||||
 | 
					- ✅ **Bitpoll Package**: Builds Bitpoll from the current master commit (4a3e6a5)
 | 
				
			||||||
 | 
					- ✅ **NixOS Service**: Complete systemd service configuration
 | 
				
			||||||
 | 
					- ✅ **Data Storage**: All data stored in `/var/lib/bitpoll` as requested
 | 
				
			||||||
 | 
					- ✅ **Security**: Proper user isolation and security hardening
 | 
				
			||||||
 | 
					- ✅ **Cross-platform**: Works on Linux and macOS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Quick Start
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 1. Using the Package Directly
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					# Run Bitpoll development server
 | 
				
			||||||
 | 
					nix run git+https://git.s1q.dev/phg/bitpoll-nix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run management commands
 | 
				
			||||||
 | 
					nix run git+https://git.s1q.dev/phg/bitpoll-nix#bitpoll-manage -- migrate
 | 
				
			||||||
 | 
					nix run git+https://git.s1q.dev/phg/bitpoll-nix#bitpoll-manage -- createsuperuser
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 2. Using as a NixOS Service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Add this flake to your NixOS configuration:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```nix
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  inputs = {
 | 
				
			||||||
 | 
					    nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
 | 
				
			||||||
 | 
					    bitpoll.url = "git+https://git.s1q.dev/phg/bitpoll-nix";
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  outputs = { self, nixpkgs, bitpoll }: {
 | 
				
			||||||
 | 
					    nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
 | 
				
			||||||
 | 
					      system = "x86_64-linux";
 | 
				
			||||||
 | 
					      modules = [
 | 
				
			||||||
 | 
					        bitpoll.nixosModules.default
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          services.bitpoll = {
 | 
				
			||||||
 | 
					            enable = true;
 | 
				
			||||||
 | 
					            port = 8080;
 | 
				
			||||||
 | 
					            host = "0.0.0.0";
 | 
				
			||||||
 | 
					            allowedHosts = [ 
 | 
				
			||||||
 | 
					              "bitpoll.example.com" 
 | 
				
			||||||
 | 
					              "localhost" 
 | 
				
			||||||
 | 
					              "127.0.0.1" 
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          # Open firewall port
 | 
				
			||||||
 | 
					          networking.firewall.allowedTCPPorts = [ 8080 ];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      ];
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Then rebuild your system:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					sudo nixos-rebuild switch --flake .#myhost
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 3. Development Environment
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					# Enter development shell
 | 
				
			||||||
 | 
					nix develop git+https://git.s1q.dev/phg/bitpoll-nix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Or clone and develop locally
 | 
				
			||||||
 | 
					git clone https://git.s1q.dev/phg/bitpoll-nix
 | 
				
			||||||
 | 
					cd bitpoll-nix
 | 
				
			||||||
 | 
					nix develop
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Configuration Options
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The NixOS service provides the following configuration options:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```nix
 | 
				
			||||||
 | 
					services.bitpoll = {
 | 
				
			||||||
 | 
					  enable = true;                    # Enable the service
 | 
				
			||||||
 | 
					  port = 8000;                      # Port to listen on (default: 8000)
 | 
				
			||||||
 | 
					  host = "127.0.0.1";              # Host to bind to (default: 127.0.0.1)
 | 
				
			||||||
 | 
					  dataDir = "/var/lib/bitpoll";     # Data directory (default: /var/lib/bitpoll)
 | 
				
			||||||
 | 
					  secretKeyFile = "/path/to/key";   # Optional: File containing Django secret key
 | 
				
			||||||
 | 
					  allowedHosts = [ "localhost" ];   # List of allowed hosts
 | 
				
			||||||
 | 
					  extraSettings = "";               # Extra Django settings
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Data Storage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All Bitpoll data is stored in `/var/lib/bitpoll` as requested:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `/var/lib/bitpoll/db.sqlite3` - SQLite database
 | 
				
			||||||
 | 
					- `/var/lib/bitpoll/static/` - Static files (CSS, JS, images)
 | 
				
			||||||
 | 
					- `/var/lib/bitpoll/media/` - User uploaded files
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Security
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The service runs with proper security hardening:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Dedicated `bitpoll` user and group
 | 
				
			||||||
 | 
					- Restricted filesystem access
 | 
				
			||||||
 | 
					- No new privileges
 | 
				
			||||||
 | 
					- Private temporary directories
 | 
				
			||||||
 | 
					- Protected system directories
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Production Deployment
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For production use, consider:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. **Use a secret key file**:
 | 
				
			||||||
 | 
					   ```nix
 | 
				
			||||||
 | 
					   services.bitpoll.secretKeyFile = "/etc/bitpoll/secret-key";
 | 
				
			||||||
 | 
					   ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. **Configure allowed hosts properly**:
 | 
				
			||||||
 | 
					   ```nix
 | 
				
			||||||
 | 
					   services.bitpoll.allowedHosts = [ "bitpoll.yourdomain.com" ];
 | 
				
			||||||
 | 
					   ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. **Use a reverse proxy** (nginx, traefik, etc.) for HTTPS termination
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4. **Set up backups** for `/var/lib/bitpoll/`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Example Complete Configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See `example-configuration.nix` for a complete NixOS configuration example.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Building and Testing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					# Check flake
 | 
				
			||||||
 | 
					nix flake check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Build package
 | 
				
			||||||
 | 
					nix build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Test the service
 | 
				
			||||||
 | 
					nix run .#bitpoll-manage -- check
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Dependencies
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This flake includes all necessary dependencies:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Django and related packages
 | 
				
			||||||
 | 
					- Calendar handling (caldav, icalendar)
 | 
				
			||||||
 | 
					- Database support (SQLite by default, PostgreSQL available)
 | 
				
			||||||
 | 
					- Security libraries (cryptography)
 | 
				
			||||||
 | 
					- Markup processing (markdown, bleach)
 | 
				
			||||||
 | 
					- LDAP support (optional)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Version Information
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- **NixOS Version**: 25.05
 | 
				
			||||||
 | 
					- **Bitpoll Version**: master (commit 4a3e6a5)
 | 
				
			||||||
 | 
					- **Python Version**: 3.x (from nixpkgs)
 | 
				
			||||||
 | 
					- **Django Version**: Latest from nixpkgs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Contributing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Fork this repository
 | 
				
			||||||
 | 
					2. Make your changes
 | 
				
			||||||
 | 
					3. Test with `nix flake check`
 | 
				
			||||||
 | 
					4. Submit a pull request
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This flake is provided under the same license as Bitpoll (GPL-3.0).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Support
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For issues with:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- **This flake**: Open an issue at [this repository](https://git.s1q.dev/phg/bitpoll-nix)
 | 
				
			||||||
 | 
					- **Bitpoll itself**: See the [upstream repository](https://github.com/fsinfuhh/Bitpoll)
 | 
				
			||||||
 | 
					- **NixOS**: See the [NixOS manual](https://nixos.org/manual/nixos/stable/)
 | 
				
			||||||
							
								
								
									
										53
									
								
								example-configuration.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								example-configuration.nix
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,53 @@
 | 
				
			||||||
 | 
					# Example NixOS configuration using the Bitpoll flake
 | 
				
			||||||
 | 
					{ config, pkgs, ... }:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  imports = [
 | 
				
			||||||
 | 
					    # Include your hardware configuration
 | 
				
			||||||
 | 
					    ./hardware-configuration.nix
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Enable flakes
 | 
				
			||||||
 | 
					  nix.settings.experimental-features = [ "nix-command" "flakes" ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Basic system configuration
 | 
				
			||||||
 | 
					  boot.loader.systemd-boot.enable = true;
 | 
				
			||||||
 | 
					  boot.loader.efi.canTouchEfiVariables = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  networking.hostName = "bitpoll-server";
 | 
				
			||||||
 | 
					  networking.firewall.allowedTCPPorts = [ 8080 22 ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Enable SSH for remote management
 | 
				
			||||||
 | 
					  services.openssh.enable = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Bitpoll service configuration
 | 
				
			||||||
 | 
					  services.bitpoll = {
 | 
				
			||||||
 | 
					    enable = true;
 | 
				
			||||||
 | 
					    port = 8080;
 | 
				
			||||||
 | 
					    host = "0.0.0.0";  # Listen on all interfaces
 | 
				
			||||||
 | 
					    allowedHosts = [ 
 | 
				
			||||||
 | 
					      "bitpoll.example.com" 
 | 
				
			||||||
 | 
					      "localhost" 
 | 
				
			||||||
 | 
					      "127.0.0.1"
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Optional: Use a secret key file for better security
 | 
				
			||||||
 | 
					    # secretKeyFile = "/etc/bitpoll/secret-key";
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Create a user for administration
 | 
				
			||||||
 | 
					  users.users.admin = {
 | 
				
			||||||
 | 
					    isNormalUser = true;
 | 
				
			||||||
 | 
					    extraGroups = [ "wheel" ]; # Enable 'sudo' for the admin user
 | 
				
			||||||
 | 
					    openssh.authorizedKeys.keys = [
 | 
				
			||||||
 | 
					      # Add your SSH public key here
 | 
				
			||||||
 | 
					      # "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC..."
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # This value determines the NixOS release from which the default
 | 
				
			||||||
 | 
					  # settings for stateful data, like file locations and database versions
 | 
				
			||||||
 | 
					  # on your system were taken. It's perfectly fine and recommended to leave
 | 
				
			||||||
 | 
					  # this value at the release version of the first install of this system.
 | 
				
			||||||
 | 
					  system.stateVersion = "25.05";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										61
									
								
								flake.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								flake.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,61 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "nodes": {
 | 
				
			||||||
 | 
					    "flake-utils": {
 | 
				
			||||||
 | 
					      "inputs": {
 | 
				
			||||||
 | 
					        "systems": "systems"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "locked": {
 | 
				
			||||||
 | 
					        "lastModified": 1731533236,
 | 
				
			||||||
 | 
					        "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
 | 
				
			||||||
 | 
					        "owner": "numtide",
 | 
				
			||||||
 | 
					        "repo": "flake-utils",
 | 
				
			||||||
 | 
					        "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "original": {
 | 
				
			||||||
 | 
					        "owner": "numtide",
 | 
				
			||||||
 | 
					        "repo": "flake-utils",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nixpkgs": {
 | 
				
			||||||
 | 
					      "locked": {
 | 
				
			||||||
 | 
					        "lastModified": 1751211869,
 | 
				
			||||||
 | 
					        "narHash": "sha256-1Cu92i1KSPbhPCKxoiVG5qnoRiKTgR5CcGSRyLpOd7Y=",
 | 
				
			||||||
 | 
					        "owner": "NixOS",
 | 
				
			||||||
 | 
					        "repo": "nixpkgs",
 | 
				
			||||||
 | 
					        "rev": "b43c397f6c213918d6cfe6e3550abfe79b5d1c51",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "original": {
 | 
				
			||||||
 | 
					        "owner": "NixOS",
 | 
				
			||||||
 | 
					        "ref": "nixos-25.05",
 | 
				
			||||||
 | 
					        "repo": "nixpkgs",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "root": {
 | 
				
			||||||
 | 
					      "inputs": {
 | 
				
			||||||
 | 
					        "flake-utils": "flake-utils",
 | 
				
			||||||
 | 
					        "nixpkgs": "nixpkgs"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "systems": {
 | 
				
			||||||
 | 
					      "locked": {
 | 
				
			||||||
 | 
					        "lastModified": 1681028828,
 | 
				
			||||||
 | 
					        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
 | 
				
			||||||
 | 
					        "owner": "nix-systems",
 | 
				
			||||||
 | 
					        "repo": "default",
 | 
				
			||||||
 | 
					        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "original": {
 | 
				
			||||||
 | 
					        "owner": "nix-systems",
 | 
				
			||||||
 | 
					        "repo": "default",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "root": "root",
 | 
				
			||||||
 | 
					  "version": 7
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										331
									
								
								flake.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										331
									
								
								flake.nix
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,331 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  description = "Bitpoll - A web application for scheduling meetings and general polling";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  inputs = {
 | 
				
			||||||
 | 
					    nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
 | 
				
			||||||
 | 
					    flake-utils.url = "github:numtide/flake-utils";
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  outputs = { self, nixpkgs, flake-utils }:
 | 
				
			||||||
 | 
					    flake-utils.lib.eachDefaultSystem (system:
 | 
				
			||||||
 | 
					      let
 | 
				
			||||||
 | 
					        pkgs = nixpkgs.legacyPackages.${system};
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Pin to current master commit
 | 
				
			||||||
 | 
					        bitpollSrc = pkgs.fetchFromGitHub {
 | 
				
			||||||
 | 
					          owner = "fsinfuhh";
 | 
				
			||||||
 | 
					          repo = "Bitpoll";
 | 
				
			||||||
 | 
					          rev = "4a3e6a5e3500308a428a6c7644f50d423adca6fc";
 | 
				
			||||||
 | 
					          sha256 = "sha256-R4OwQdSJu9+EAlkhYOEe2ZOrS9oOA1ifg/iY6uzYSpE=";
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Create settings_local.py for production
 | 
				
			||||||
 | 
					        settingsLocal = pkgs.writeText "settings_local.py" ''
 | 
				
			||||||
 | 
					          import os
 | 
				
			||||||
 | 
					          import secrets
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          # Generate secret key if not provided via environment
 | 
				
			||||||
 | 
					          SECRET_KEY = os.environ.get('BITPOLL_SECRET_KEY', secrets.token_urlsafe(50))
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          # Generate field encryption key if not provided via environment  
 | 
				
			||||||
 | 
					          FIELD_ENCRYPTION_KEY = os.environ.get('BITPOLL_FIELD_ENCRYPTION_KEY', secrets.token_urlsafe(32) + "=")
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          DEBUG = False
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          ALLOWED_HOSTS = ['*']  # Configure appropriately for production
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          # SQLite database configuration
 | 
				
			||||||
 | 
					          DATABASES = {
 | 
				
			||||||
 | 
					              'default': {
 | 
				
			||||||
 | 
					                  'ENGINE': 'django.db.backends.sqlite3',
 | 
				
			||||||
 | 
					                  'NAME': '/var/lib/bitpoll/db.sqlite3',
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          # Static files
 | 
				
			||||||
 | 
					          STATIC_ROOT = '/var/lib/bitpoll/static'
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          # Media files
 | 
				
			||||||
 | 
					          MEDIA_ROOT = '/var/lib/bitpoll/media'
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          # Locale
 | 
				
			||||||
 | 
					          LANGUAGE_CODE = 'en-us'
 | 
				
			||||||
 | 
					          TIME_ZONE = 'UTC'
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          # Site configuration
 | 
				
			||||||
 | 
					          SITE_NAME = 'Bitpoll'
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          # Additional apps
 | 
				
			||||||
 | 
					          INSTALLED_APPS_LOCAL = []
 | 
				
			||||||
 | 
					          MIDDLEWARE_LOCAL = []
 | 
				
			||||||
 | 
					          PIPELINE_LOCAL = {}
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          # Registration enabled by default
 | 
				
			||||||
 | 
					          REGISTER_ENABLED = True
 | 
				
			||||||
 | 
					          GROUP_MANAGEMENT = True
 | 
				
			||||||
 | 
					        '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bitpoll = pkgs.python3Packages.buildPythonApplication rec {
 | 
				
			||||||
 | 
					          pname = "bitpoll";
 | 
				
			||||||
 | 
					          version = "master-${builtins.substring 0 7 bitpollSrc.rev}";
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          src = bitpollSrc;
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          format = "other";
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          propagatedBuildInputs = with pkgs.python3Packages; [
 | 
				
			||||||
 | 
					            # Core Django dependencies
 | 
				
			||||||
 | 
					            django
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # Calendar and date handling
 | 
				
			||||||
 | 
					            caldav
 | 
				
			||||||
 | 
					            icalendar
 | 
				
			||||||
 | 
					            python-dateutil
 | 
				
			||||||
 | 
					            pytz
 | 
				
			||||||
 | 
					            vobject
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # Crypto and security
 | 
				
			||||||
 | 
					            cryptography
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # Web and HTTP
 | 
				
			||||||
 | 
					            requests
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # Markup and styling
 | 
				
			||||||
 | 
					            markdown
 | 
				
			||||||
 | 
					            bleach
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # Data handling
 | 
				
			||||||
 | 
					            pydantic
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # Database
 | 
				
			||||||
 | 
					            psycopg2
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # Utilities
 | 
				
			||||||
 | 
					            six
 | 
				
			||||||
 | 
					            lxml
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # Additional dependencies
 | 
				
			||||||
 | 
					            setuptools
 | 
				
			||||||
 | 
					            wheel
 | 
				
			||||||
 | 
					          ] ++ [
 | 
				
			||||||
 | 
					            # System dependencies
 | 
				
			||||||
 | 
					            pkgs.gettext
 | 
				
			||||||
 | 
					          ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          nativeBuildInputs = with pkgs; [
 | 
				
			||||||
 | 
					            gettext
 | 
				
			||||||
 | 
					          ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          buildInputs = with pkgs; [
 | 
				
			||||||
 | 
					            # LDAP support
 | 
				
			||||||
 | 
					            openldap
 | 
				
			||||||
 | 
					            cyrus_sasl
 | 
				
			||||||
 | 
					          ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          # Don't run tests during build
 | 
				
			||||||
 | 
					          doCheck = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          preBuild = ''
 | 
				
			||||||
 | 
					            # Copy our settings file
 | 
				
			||||||
 | 
					            cp ${settingsLocal} bitpoll/settings_local.py
 | 
				
			||||||
 | 
					          '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          installPhase = ''
 | 
				
			||||||
 | 
					            runHook preInstall
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            mkdir -p $out/share/bitpoll
 | 
				
			||||||
 | 
					            cp -r . $out/share/bitpoll/
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # Create wrapper script
 | 
				
			||||||
 | 
					            mkdir -p $out/bin
 | 
				
			||||||
 | 
					            cat > $out/bin/bitpoll-manage << EOF
 | 
				
			||||||
 | 
					            #!/bin/sh
 | 
				
			||||||
 | 
					            cd $out/share/bitpoll
 | 
				
			||||||
 | 
					            export PYTHONPATH=$out/share/bitpoll:\$PYTHONPATH
 | 
				
			||||||
 | 
					            exec ${pkgs.python3}/bin/python manage.py "\$@"
 | 
				
			||||||
 | 
					            EOF
 | 
				
			||||||
 | 
					            chmod +x $out/bin/bitpoll-manage
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            # Create server script
 | 
				
			||||||
 | 
					            cat > $out/bin/bitpoll-server << EOF
 | 
				
			||||||
 | 
					            #!/bin/sh
 | 
				
			||||||
 | 
					            cd $out/share/bitpoll
 | 
				
			||||||
 | 
					            export PYTHONPATH=$out/share/bitpoll:\$PYTHONPATH
 | 
				
			||||||
 | 
					            exec ${pkgs.python3}/bin/python manage.py runserver "\$@"
 | 
				
			||||||
 | 
					            EOF
 | 
				
			||||||
 | 
					            chmod +x $out/bin/bitpoll-server
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            runHook postInstall
 | 
				
			||||||
 | 
					          '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          meta = with pkgs.lib; {
 | 
				
			||||||
 | 
					            description = "A web application for scheduling meetings and general polling";
 | 
				
			||||||
 | 
					            homepage = "https://github.com/fsinfuhh/Bitpoll";
 | 
				
			||||||
 | 
					            license = licenses.gpl3Only;
 | 
				
			||||||
 | 
					            maintainers = [ ];
 | 
				
			||||||
 | 
					            platforms = platforms.unix;
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      in {
 | 
				
			||||||
 | 
					        packages = {
 | 
				
			||||||
 | 
					          default = bitpoll;
 | 
				
			||||||
 | 
					          bitpoll = bitpoll;
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        apps = {
 | 
				
			||||||
 | 
					          default = {
 | 
				
			||||||
 | 
					            type = "app";
 | 
				
			||||||
 | 
					            program = "${bitpoll}/bin/bitpoll-server";
 | 
				
			||||||
 | 
					            meta = {
 | 
				
			||||||
 | 
					              description = "Run Bitpoll development server";
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					          bitpoll-manage = {
 | 
				
			||||||
 | 
					            type = "app";
 | 
				
			||||||
 | 
					            program = "${bitpoll}/bin/bitpoll-manage";
 | 
				
			||||||
 | 
					            meta = {
 | 
				
			||||||
 | 
					              description = "Run Bitpoll management commands";
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        devShells.default = pkgs.mkShell {
 | 
				
			||||||
 | 
					          buildInputs = with pkgs; [
 | 
				
			||||||
 | 
					            python3
 | 
				
			||||||
 | 
					            python3Packages.pip
 | 
				
			||||||
 | 
					            python3Packages.virtualenv
 | 
				
			||||||
 | 
					            gettext
 | 
				
			||||||
 | 
					            openldap
 | 
				
			||||||
 | 
					            cyrus_sasl
 | 
				
			||||||
 | 
					          ];
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ) // {
 | 
				
			||||||
 | 
					      nixosModules.default = self.nixosModules.bitpoll;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      nixosModules.bitpoll = { config, lib, pkgs, ... }:
 | 
				
			||||||
 | 
					        with lib;
 | 
				
			||||||
 | 
					        let
 | 
				
			||||||
 | 
					          cfg = config.services.bitpoll;
 | 
				
			||||||
 | 
					          bitpollPackage = self.packages.${pkgs.system}.bitpoll;
 | 
				
			||||||
 | 
					        in {
 | 
				
			||||||
 | 
					          options.services.bitpoll = {
 | 
				
			||||||
 | 
					            enable = mkEnableOption "Bitpoll service";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            package = mkOption {
 | 
				
			||||||
 | 
					              type = types.package;
 | 
				
			||||||
 | 
					              default = bitpollPackage;
 | 
				
			||||||
 | 
					              description = "The Bitpoll package to use";
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            port = mkOption {
 | 
				
			||||||
 | 
					              type = types.port;
 | 
				
			||||||
 | 
					              default = 8000;
 | 
				
			||||||
 | 
					              description = "Port to listen on";
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            host = mkOption {
 | 
				
			||||||
 | 
					              type = types.str;
 | 
				
			||||||
 | 
					              default = "127.0.0.1";
 | 
				
			||||||
 | 
					              description = "Host to bind to";
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            dataDir = mkOption {
 | 
				
			||||||
 | 
					              type = types.path;
 | 
				
			||||||
 | 
					              default = "/var/lib/bitpoll";
 | 
				
			||||||
 | 
					              description = "Directory to store Bitpoll data";
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            secretKeyFile = mkOption {
 | 
				
			||||||
 | 
					              type = types.nullOr types.path;
 | 
				
			||||||
 | 
					              default = null;
 | 
				
			||||||
 | 
					              description = "File containing the Django secret key";
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            allowedHosts = mkOption {
 | 
				
			||||||
 | 
					              type = types.listOf types.str;
 | 
				
			||||||
 | 
					              default = [ "localhost" "127.0.0.1" ];
 | 
				
			||||||
 | 
					              description = "List of allowed hosts";
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            extraSettings = mkOption {
 | 
				
			||||||
 | 
					              type = types.lines;
 | 
				
			||||||
 | 
					              default = "";
 | 
				
			||||||
 | 
					              description = "Extra settings to append to settings_local.py";
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          config = mkIf cfg.enable {
 | 
				
			||||||
 | 
					            users.users.bitpoll = {
 | 
				
			||||||
 | 
					              isSystemUser = true;
 | 
				
			||||||
 | 
					              group = "bitpoll";
 | 
				
			||||||
 | 
					              home = cfg.dataDir;
 | 
				
			||||||
 | 
					              createHome = true;
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            users.groups.bitpoll = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            systemd.services.bitpoll = {
 | 
				
			||||||
 | 
					              description = "Bitpoll web application";
 | 
				
			||||||
 | 
					              wantedBy = [ "multi-user.target" ];
 | 
				
			||||||
 | 
					              after = [ "network.target" ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              environment = {
 | 
				
			||||||
 | 
					                PYTHONPATH = "${cfg.package}/share/bitpoll";
 | 
				
			||||||
 | 
					                BITPOLL_DATA_DIR = cfg.dataDir;
 | 
				
			||||||
 | 
					              } // optionalAttrs (cfg.secretKeyFile != null) {
 | 
				
			||||||
 | 
					                BITPOLL_SECRET_KEY_FILE = cfg.secretKeyFile;
 | 
				
			||||||
 | 
					              };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              preStart = ''
 | 
				
			||||||
 | 
					                # Ensure data directory exists and has correct permissions
 | 
				
			||||||
 | 
					                mkdir -p ${cfg.dataDir}/{static,media}
 | 
				
			||||||
 | 
					                chown -R bitpoll:bitpoll ${cfg.dataDir}
 | 
				
			||||||
 | 
					                chmod 750 ${cfg.dataDir}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                # Create runtime settings if secret key file is provided
 | 
				
			||||||
 | 
					                if [ -n "''${BITPOLL_SECRET_KEY_FILE:-}" ] && [ -f "$BITPOLL_SECRET_KEY_FILE" ]; then
 | 
				
			||||||
 | 
					                  export BITPOLL_SECRET_KEY="$(cat "$BITPOLL_SECRET_KEY_FILE")"
 | 
				
			||||||
 | 
					                fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                # Run database migrations
 | 
				
			||||||
 | 
					                cd ${cfg.package}/share/bitpoll
 | 
				
			||||||
 | 
					                ${cfg.package}/bin/bitpoll-manage migrate --noinput
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                # Collect static files
 | 
				
			||||||
 | 
					                ${cfg.package}/bin/bitpoll-manage collectstatic --noinput --clear
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                # Compile messages
 | 
				
			||||||
 | 
					                ${cfg.package}/bin/bitpoll-manage compilemessages
 | 
				
			||||||
 | 
					              '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              serviceConfig = {
 | 
				
			||||||
 | 
					                Type = "exec";
 | 
				
			||||||
 | 
					                User = "bitpoll";
 | 
				
			||||||
 | 
					                Group = "bitpoll";
 | 
				
			||||||
 | 
					                WorkingDirectory = "${cfg.package}/share/bitpoll";
 | 
				
			||||||
 | 
					                ExecStart = "${cfg.package}/bin/bitpoll-server ${cfg.host}:${toString cfg.port}";
 | 
				
			||||||
 | 
					                Restart = "always";
 | 
				
			||||||
 | 
					                RestartSec = "10s";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                # Security settings
 | 
				
			||||||
 | 
					                NoNewPrivileges = true;
 | 
				
			||||||
 | 
					                PrivateTmp = true;
 | 
				
			||||||
 | 
					                ProtectSystem = "strict";
 | 
				
			||||||
 | 
					                ProtectHome = true;
 | 
				
			||||||
 | 
					                ReadWritePaths = [ cfg.dataDir ];
 | 
				
			||||||
 | 
					                PrivateDevices = true;
 | 
				
			||||||
 | 
					                ProtectKernelTunables = true;
 | 
				
			||||||
 | 
					                ProtectKernelModules = true;
 | 
				
			||||||
 | 
					                ProtectControlGroups = true;
 | 
				
			||||||
 | 
					              };
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Open firewall port if needed
 | 
				
			||||||
 | 
					            # networking.firewall.allowedTCPPorts = [ cfg.port ];
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue