Something went wrong. Try again.
Rust AppView - highly experimental! forked from parakeet.at/parakeet
Something went wrong. Try again.
parakeet flake.nix
17 kB · 471 lines
Nix
at experiments
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472{ description = "Parakeet is a Rust-based Bluesky AppView"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; crane.url = "github:ipetkov/crane"; flake-utils.url = "github:numtide/flake-utils"; rust-overlay = { url = "github:oxalica/rust-overlay"; inputs.nixpkgs.follows = "nixpkgs"; }; }; outputs = { self, nixpkgs, crane, flake-utils, rust-overlay, ... }: flake-utils.lib.eachDefaultSystem ( system: let pkgs = import nixpkgs { inherit system; overlays = [ (import rust-overlay) ]; }; craneLib = (crane.mkLib pkgs).overrideToolchain ( p: p.rust-bin.selectLatestNightlyWith ( toolchain: toolchain.default.override { extensions = [ "rust-src" "rust-analyzer" ]; } ) );
inherit (pkgs) lib; unfilteredRoot = ./.; # The original, unfiltered source src = lib.fileset.toSource { root = unfilteredRoot; fileset = lib.fileset.unions [ # Default files from crane (Rust and cargo files) (craneLib.fileset.commonCargoSources unfilteredRoot) ]; }; # Common arguments can be set here to avoid repeating them later commonArgs = { inherit src; strictDeps = true; nativeBuildInputs = with pkgs; [ pkg-config ]; buildInputs = [ # Add additional build inputs here pkgs.openssl pkgs.postgresql pkgs.libpq pkgs.clang pkgs.libclang pkgs.lld pkgs.protobuf ] ++ lib.optionals pkgs.stdenv.isDarwin [ # Additional darwin specific inputs can be set here pkgs.libiconv pkgs.darwin.apple_sdk.frameworks.Security ]; LIBCLANG_PATH = "${pkgs.llvmPackages_18.libclang.lib}/lib"; CLANG_PATH = "${pkgs.llvmPackages_18.clang}/bin/clang"; PROTOC_INCLUDE = "${pkgs.protobuf}/include"; PROTOC = "${pkgs.protobuf}/bin/protoc";
# Additional environment variables can be set directly # MY_CUSTOM_VAR = "some value"; };
# Build *just* the cargo dependencies, so we can reuse # all of that work (e.g. via cachix) when running in CI # cargoArtifacts = craneLib.buildDepsOnly commonArgs;
# individualCrateArgs = commonArgs // { # inherit cargoArtifacts; # inherit (craneLib.crateNameFromCargoToml { inherit src; }) version; # # NB: we disable tests since we'll run them all via cargo-nextest # doCheck = false; # }; # fileSetForCrate = # crate: # lib.fileset.toSource { # root = ./.; # fileset = lib.fileset.unions [ # ./Cargo.toml # ./Cargo.lock # ./migrations # ./consumer/src/sources/jetstream/zstd_dictionary # (craneLib.fileset.commonCargoSources ./consumer) # ./consumer/src/db/sql # (craneLib.fileset.commonCargoSources ./dataloader-rs) # (craneLib.fileset.commonCargoSources ./did-resolver) # (craneLib.fileset.commonCargoSources ./lexica) # (craneLib.fileset.commonCargoSources ./parakeet) # ./parakeet/src/sql # (craneLib.fileset.commonCargoSources ./parakeet-db) # ./parakeet-db/src/dicts/post_content_v1.dict # (craneLib.fileset.commonCargoSources ./parakeet-lexgen) # (craneLib.fileset.commonCargoSources crate) # ]; # };
# Build the actual crate itself, reusing the dependency # artifacts from above. # COMMENTED OUT FOR DEV # consumer = craneLib.buildPackage ( # individualCrateArgs # // { # pname = "consumer"; # cargoExtraArgs = "-p consumer"; # src = fileSetForCrate ./consumer; # postInstall = '' # mkdir -p $out/{bin,lib/consumer} # ''; # } # ); # dataloader = craneLib.buildPackage ( # individualCrateArgs # // { # pname = "dataloader"; # cargoExtraArgs = "-p dataloader"; # src = fileSetForCrate ./dataloader-rs; # } # ); # did-resolver = craneLib.buildPackage ( # individualCrateArgs # // { # pname = "did-resolver"; # cargoExtraArgs = "-p did-resolver"; # src = fileSetForCrate ./did-resolver; # } # ); # lexica = craneLib.buildPackage ( # individualCrateArgs # // { # pname = "lexica"; # cargoExtraArgs = "-p lexica"; # src = fileSetForCrate ./lexica; # } # ); # parakeet = craneLib.buildPackage ( # individualCrateArgs # // { # pname = "parakeet"; # cargoExtraArgs = "-p parakeet"; # src = fileSetForCrate ./parakeet; # } # ); # parakeet-db = craneLib.buildPackage ( # individualCrateArgs # // { # pname = "parakeet-db"; # cargoExtraArgs = "-p parakeet-db"; # src = fileSetForCrate ./parakeet-db; # } # ); # parakeet-lexgen = craneLib.buildPackage ( # individualCrateArgs # // { # pname = "parakeet-lexgen"; # cargoExtraArgs = "-p parakeet-lexgen"; # src = fileSetForCrate ./parakeet-lexgen; # } # );
# Dummy derivations to satisfy references consumer = pkgs.writeTextDir "bin/consumer" "echo 'Consumer not built in dev mode'"; dataloader = pkgs.writeTextDir "bin/dataloader" "echo 'Dataloader not built in dev mode'"; did-resolver = pkgs.writeTextDir "bin/did-resolver" "echo 'DID resolver not built in dev mode'"; lexica = pkgs.writeTextDir "bin/lexica" "echo 'Lexica not built in dev mode'"; parakeet = pkgs.writeTextDir "bin/parakeet" "echo 'Parakeet not built in dev mode'"; parakeet-db = pkgs.writeTextDir "bin/parakeet-db" "echo 'Parakeet-db not built in dev mode'"; parakeet-lexgen = pkgs.writeTextDir "bin/parakeet-lexgen" "echo 'Parakeet-lexgen not built in dev mode'"; in { checks = { # Build the crate as part of `nix flake check` for convenience inherit consumer dataloader did-resolver lexica parakeet parakeet-db parakeet-lexgen ; };
packages = { default = parakeet; inherit consumer dataloader did-resolver lexica parakeet parakeet-db parakeet-lexgen ; };
devShells.default = craneLib.devShell { # Inherit inputs from checks. checks = self.checks.${system};
# Manually provision devshell nativeBuildInputs = with pkgs; [ pkg-config ]; buildInputs = [ pkgs.openssl pkgs.postgresql pkgs.libpq pkgs.clang pkgs.libclang pkgs.lld pkgs.protobuf ]; CLANG_PATH = "${pkgs.llvmPackages_18.clang}/bin/clang"; PROTOC_INCLUDE = "${pkgs.protobuf}/include"; PROTOC = "${pkgs.protobuf}/bin/protoc";
# Additional dev-shell environment variables can be set directly RUST_BACKTRACE = 0; NIXOS_OZONE_WL = 1; LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
# Extra inputs can be added here; cargo and rustc are provided by default. packages = with pkgs; [ openssl bacon postgresql rust-analyzer rustfmt clippy git nixd direnv libpq clang libclang diesel-cli tokei ast-grep scc openssl postgresql libpq clang libclang lld protobuf pkg-config ]; }; } ) // flake-utils.lib.eachDefaultSystemPassThrough (system: { nixosModules = { default = { pkgs, lib, config, ... }: with lib; let cfg = config.services.parakeet;
inherit (lib) mkEnableOption mkIf mkOption types ; in { options.services.parakeet = { enable = mkEnableOption "parakeet";
package = mkOption { type = types.package; default = self.packages.${pkgs.system}.default; description = "The path to the parakeet package."; };
workingDirectory = mkOption { type = types.str; default = "/var/lib/parakeet"; description = "Working directory for parakeet services (where Config.toml is located)"; };
environmentFiles = mkOption { type = types.listOf types.path; default = [ "/var/lib/parakeet/config.env" ]; description = '' File to load environment variables from. Loaded variables override values set in {option}`environment`. ''; }; }; config = mkIf cfg.enable { # environment.systemPackages = [ # self.packages.${pkgs.system}.consumer # ]; # systemd.services.consumer = { # description = "consumer"; # after = [ # "network-online.target" # "parakeet.service" # ]; # wants = [ "network-online.target" ]; # requires = [ "parakeet.service" ]; # wantedBy = [ "multi-user.target" ]; # serviceConfig = { # ExecStart = "${self.packages.${pkgs.system}.consumer}/bin/consumer --backfill --indexer"; # Type = "exec"; # WorkingDirectory = cfg.workingDirectory;
# EnvironmentFile = cfg.environmentFiles; # User = "parakeet"; # Group = "parakeet"; # StateDirectory = "parakeet"; # StateDirectoryMode = "0755"; # Restart = "always";
# # Hardening # RemoveIPC = true; # CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; # NoNewPrivileges = true; # PrivateDevices = true; # ProtectClock = true; # ProtectKernelLogs = true; # ProtectControlGroups = true; # ProtectKernelModules = true; # PrivateMounts = true; # SystemCallArchitectures = [ "native" ]; # MemoryDenyWriteExecute = false; # required by V8 JIT # RestrictNamespaces = true; # RestrictSUIDSGID = true; # ProtectHostname = true; # LockPersonality = true; # ProtectKernelTunables = true; # RestrictAddressFamilies = [ # "AF_UNIX" # "AF_INET" # "AF_INET6" # ]; # RestrictRealtime = true; # DeviceAllow = [ "" ]; # ProtectSystem = "full"; # ProtectProc = "invisible"; # ProcSubset = "pid"; # ProtectHome = true; # PrivateUsers = true; # PrivateTmp = true; # UMask = "0077"; # }; # }; # systemd.services.parakeet = { # description = "parakeet"; # after = [ # "network-online.target" # "postgresql.service" # ]; # wants = [ "network-online.target" ]; # requires = [ "postgresql.service" ]; # wantedBy = [ "multi-user.target" ]; # serviceConfig = { # ExecStart = "${cfg.package}/bin/parakeet"; # Type = "exec"; # WorkingDirectory = cfg.workingDirectory;
# EnvironmentFile = cfg.environmentFiles; # User = "parakeet"; # Group = "parakeet"; # StateDirectory = "parakeet"; # StateDirectoryMode = "0755"; # Restart = "always";
# # Hardening # RemoveIPC = true; # CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; # NoNewPrivileges = true; # PrivateDevices = true; # ProtectClock = true; # ProtectKernelLogs = true; # ProtectControlGroups = true; # ProtectKernelModules = true; # PrivateMounts = true; # SystemCallArchitectures = [ "native" ]; # MemoryDenyWriteExecute = false; # required by V8 JIT # RestrictNamespaces = true; # RestrictSUIDSGID = true; # ProtectHostname = true; # LockPersonality = true; # ProtectKernelTunables = true; # RestrictAddressFamilies = [ # "AF_UNIX" # "AF_INET" # "AF_INET6" # ]; # RestrictRealtime = true; # DeviceAllow = [ "" ]; # ProtectSystem = "full"; # ProtectProc = "invisible"; # ProcSubset = "pid"; # ProtectHome = true; # PrivateUsers = true; # PrivateTmp = true; # UMask = "0077"; # }; # }; users = { users.parakeet = { group = "parakeet"; isSystemUser = true; }; groups.parakeet = { }; }; services.postgresql = { enable = true; ensureUsers = [ { name = "parakeet"; ensureDBOwnership = true; } ]; ensureDatabases = [ "parakeet" ]; authentication = pkgs.lib.mkOverride 10 '' #type database DBuser auth-method local all all trust host all all 127.0.0.1/32 trust host all all ::1/128 trust ''; package = mkForce pkgs.postgresql_16; extraPlugins = with pkgs.postgresql16Packages; [ # Note: pg_stat_statements is built into PostgreSQL (contrib module) # and doesn't need to be listed here - just enable via CREATE EXTENSION pgvector # Vector similarity search (future-proofing) timescaledb # Time-series optimization pgrouting # Graph analysis for social graph postgis # Required dependency for pgrouting ]; settings = { # Preload extensions that require early initialization # pg_stat_statements is a contrib module (built-in, not extraPlugins) shared_preload_libraries = "pg_stat_statements,timescaledb";
# pg_stat_statements configuration "pg_stat_statements.max" = "10000"; # Track up to 10k unique queries "pg_stat_statements.track" = "all"; # Track all queries (top-level + nested) }; }; }; }; }; });}