Find a file
2025-07-03 17:35:13 +02:00
example-configuration.nix Initial Bitpoll Nix package and service 2025-07-03 17:35:13 +02:00
flake.nix Initial Bitpoll Nix package and service 2025-07-03 17:35:13 +02:00
module.nix Initial Bitpoll Nix package and service 2025-07-03 17:35:13 +02:00
package.nix Initial Bitpoll Nix package and service 2025-07-03 17:35:13 +02:00
README.md Initial Bitpoll Nix package and service 2025-07-03 17:35:13 +02:00

Bitpoll Nix Package

This repository contains a Nix flake for packaging Bitpoll, a web application for scheduling meetings and general polling.

Features

  • Complete Nix Package: Bitpoll packaged as a Nix derivation with all Python dependencies
  • NixOS Service Module: Ready-to-use systemd service with PostgreSQL integration
  • Security Hardened: Runs with minimal privileges and security restrictions
  • Configurable: All major settings exposed as NixOS options
  • Production Ready: Uses uWSGI with proper process management

Quick Start

1. Add to your NixOS configuration

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
    bitpoll.url = "github:your-username/bitpoll-nix";
  };

  outputs = { self, nixpkgs, bitpoll }: {
    nixosConfigurations.your-host = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        bitpoll.nixosModules.default
        {
          services.bitpoll = {
            enable = true;
            secretKey = "your-secret-key-here";
            encryptionKey = "your-encryption-key-here";
            allowedHosts = [ "your-domain.com" ];
          };
        }
      ];
    };
  };
}

2. Generate required keys

# Generate Django secret key
python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"

# Generate field encryption key (32 bytes, base64 encoded)
python -c "import base64, os; print(base64.b64encode(os.urandom(32)).decode())"

3. Deploy

sudo nixos-rebuild switch --flake .#your-host

Configuration Options

Basic Configuration

services.bitpoll = {
  enable = true;
  
  # Required security keys
  secretKey = "your-django-secret-key";
  encryptionKey = "your-field-encryption-key";
  
  # Network settings
  listenAddress = "127.0.0.1";
  port = 3008;           # uWSGI socket
  httpPort = 3009;       # HTTP port (null to disable)
  
  # Django settings
  debug = false;
  allowedHosts = [ "your-domain.com" ];
  language = "en-us";
  timezone = "Europe/Berlin";
};

Database Configuration

services.bitpoll = {
  # PostgreSQL is enabled by default
  enablePostgreSQL = true;
  
  database = {
    name = "bitpoll";
    user = "bitpoll";
    password = ""; # Leave empty for peer authentication
    host = "localhost";
    port = 5432;
  };
};

Performance Tuning

services.bitpoll = {
  # uWSGI process management
  processes = 8;           # Max processes
  threads = 4;             # Threads per process
  cheaperProcesses = 2;    # Min processes
  
  # Additional uWSGI configuration
  extraUwsgiConfig = ''
    max-requests = 1000
    reload-on-rss = 512
  '';
};

Advanced Settings

services.bitpoll = {
  # Additional Django settings
  extraSettings = {
    PIPELINE_LOCAL = {
      JS_COMPRESSOR = "pipeline.compressors.uglifyjs.UglifyJSCompressor";
      CSS_COMPRESSOR = "pipeline.compressors.cssmin.CSSMinCompressor";
    };
    CSP_ADDITIONAL_SCRIPT_SRC = [ "your-analytics-domain.com" ];
  };
};

Reverse Proxy Setup

Nginx Example

services.nginx = {
  enable = true;
  virtualHosts."your-domain.com" = {
    enableACME = true;
    forceSSL = true;
    locations = {
      "/" = {
        proxyPass = "http://127.0.0.1:3009";
        proxyWebsockets = true;
        extraConfig = ''
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
        '';
      };
      "/static/" = {
        alias = "/var/lib/bitpoll/static/";
        extraConfig = ''
          expires 1y;
          add_header Cache-Control "public, immutable";
        '';
      };
    };
  };
};

Data Storage

All persistent data is stored in /var/lib/bitpoll/:

  • media/ - User uploaded files
  • static/ - Collected static files
  • Database data (if using PostgreSQL, stored in PostgreSQL data directory)

Security

The service runs with extensive security hardening:

  • Dedicated user account (bitpoll)
  • Restricted filesystem access
  • No network access except required ports
  • Memory execution protection
  • System call filtering

Development

Building the package

nix build .#bitpoll

Development shell

nix develop

Testing the module

nixos-rebuild build-vm --flake .#test-vm

Troubleshooting

Check service status

systemctl status bitpoll
journalctl -u bitpoll -f

Database issues

# Check PostgreSQL status
systemctl status postgresql

# Connect to database
sudo -u postgres psql bitpoll

Permission issues

# Fix data directory permissions
sudo chown -R bitpoll:bitpoll /var/lib/bitpoll
sudo chmod -R u=rwX,g=rX,o= /var/lib/bitpoll

License

This packaging is released under the same license as Bitpoll (GPL-3.0).