diff options
| author | Max Audron <me@audron.dev> | 2026-01-30 18:34:22 +0100 |
|---|---|---|
| committer | Max Audron <me@audron.dev> | 2026-01-30 18:34:22 +0100 |
| commit | 34fbe3dd65e37c95019113b8f94f15a4cb0440db (patch) | |
| tree | 57c5903a18eee88aebe864530ef921de7828560e | |
| parent | init (diff) | |
add flake
Diffstat (limited to '')
| -rw-r--r-- | .envrc | 1 | ||||
| -rw-r--r-- | .gitignore | 5 | ||||
| -rw-r--r-- | flake.lock | 292 | ||||
| -rw-r--r-- | flake.nix | 145 | ||||
| -rw-r--r-- | src/main.rs | 5 |
5 files changed, 447 insertions, 1 deletions
@@ -0,0 +1 @@ +use flake @@ -1,2 +1,7 @@ /target /.serena + +# Nix +result +result-* +.direnv diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..954dfec --- /dev/null +++ b/flake.lock @@ -0,0 +1,292 @@ +{ + "nodes": { + "crane": { + "flake": false, + "locked": { + "lastModified": 1758758545, + "narHash": "sha256-NU5WaEdfwF6i8faJ2Yh+jcK9vVFrofLcwlD/mP65JrI=", + "owner": "ipetkov", + "repo": "crane", + "rev": "95d528a5f54eaba0d12102249ce42f4d01f4e364", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "ref": "v0.21.1", + "repo": "crane", + "type": "github" + } + }, + "dream2nix": { + "inputs": { + "nixpkgs": [ + "nci", + "nixpkgs" + ], + "purescript-overlay": "purescript-overlay", + "pyproject-nix": "pyproject-nix" + }, + "locked": { + "lastModified": 1765953015, + "narHash": "sha256-5FBZbbWR1Csp3Y2icfRkxMJw/a/5FGg8hCXej2//bbI=", + "owner": "nix-community", + "repo": "dream2nix", + "rev": "69eb01fa0995e1e90add49d8ca5bcba213b0416f", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "dream2nix", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1768135262, + "narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "mk-naked-shell": { + "flake": false, + "locked": { + "lastModified": 1681286841, + "narHash": "sha256-3XlJrwlR0nBiREnuogoa5i1b4+w/XPe0z8bbrJASw0g=", + "owner": "90-008", + "repo": "mk-naked-shell", + "rev": "7612f828dd6f22b7fb332cc69440e839d7ffe6bd", + "type": "github" + }, + "original": { + "owner": "90-008", + "repo": "mk-naked-shell", + "type": "github" + } + }, + "nci": { + "inputs": { + "crane": "crane", + "dream2nix": "dream2nix", + "mk-naked-shell": "mk-naked-shell", + "nixpkgs": [ + "nixpkgs" + ], + "parts": "parts", + "rust-overlay": "rust-overlay", + "treefmt": "treefmt" + }, + "locked": { + "lastModified": 1769755038, + "narHash": "sha256-4LW7O06gafHpnd2QTU7S8AHcpH7smxX0Egb8bF5dZEc=", + "owner": "yusdacra", + "repo": "nix-cargo-integration", + "rev": "bbd754b60e2f803a4bdd2007387d921262ce6971", + "type": "github" + }, + "original": { + "owner": "yusdacra", + "repo": "nix-cargo-integration", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1769461804, + "narHash": "sha256-msG8SU5WsBUfVVa/9RPLaymvi5bI8edTavbIq3vRlhI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "bfc1b8a4574108ceef22f02bafcf6611380c100d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1765674936, + "narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "parts": { + "inputs": { + "nixpkgs-lib": [ + "nci", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1768135262, + "narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "purescript-overlay": { + "inputs": { + "flake-compat": "flake-compat", + "nixpkgs": [ + "nci", + "dream2nix", + "nixpkgs" + ], + "slimlock": "slimlock" + }, + "locked": { + "lastModified": 1728546539, + "narHash": "sha256-Sws7w0tlnjD+Bjck1nv29NjC5DbL6nH5auL9Ex9Iz2A=", + "owner": "thomashoneyman", + "repo": "purescript-overlay", + "rev": "4ad4c15d07bd899d7346b331f377606631eb0ee4", + "type": "github" + }, + "original": { + "owner": "thomashoneyman", + "repo": "purescript-overlay", + "type": "github" + } + }, + "pyproject-nix": { + "inputs": { + "nixpkgs": [ + "nci", + "dream2nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1763017646, + "narHash": "sha256-Z+R2lveIp6Skn1VPH3taQIuMhABg1IizJd8oVdmdHsQ=", + "owner": "pyproject-nix", + "repo": "pyproject.nix", + "rev": "47bd6f296502842643078d66128f7b5e5370790c", + "type": "github" + }, + "original": { + "owner": "pyproject-nix", + "repo": "pyproject.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-parts": "flake-parts", + "nci": "nci", + "nixpkgs": "nixpkgs" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "nci", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1769742225, + "narHash": "sha256-roSD/OJ3x9nF+Dxr+/bLClX3U8FP9EkCQIFpzxKjSUM=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "bcdd8d37594f0e201639f55889c01c827baf5c75", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "slimlock": { + "inputs": { + "nixpkgs": [ + "nci", + "dream2nix", + "purescript-overlay", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688756706, + "narHash": "sha256-xzkkMv3neJJJ89zo3o2ojp7nFeaZc2G0fYwNXNJRFlo=", + "owner": "thomashoneyman", + "repo": "slimlock", + "rev": "cf72723f59e2340d24881fd7bf61cb113b4c407c", + "type": "github" + }, + "original": { + "owner": "thomashoneyman", + "repo": "slimlock", + "type": "github" + } + }, + "treefmt": { + "inputs": { + "nixpkgs": [ + "nci", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1769691507, + "narHash": "sha256-8aAYwyVzSSwIhP2glDhw/G0i5+wOrren3v6WmxkVonM=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "28b19c5844cc6e2257801d43f2772a4b4c050a1b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..32bde23 --- /dev/null +++ b/flake.nix @@ -0,0 +1,145 @@ +{ + description = "AC Cup Server - Assetto Corsa Content Update Protocol Server"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-parts.url = "github:hercules-ci/flake-parts"; + nci.url = "github:yusdacra/nix-cargo-integration"; + nci.inputs.nixpkgs.follows = "nixpkgs"; + }; + + outputs = inputs @ { flake-parts, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { + systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; + + imports = [ + inputs.nci.flakeModule + ]; + + perSystem = { config, pkgs, system, ... }: + let + projectName = "ac-cup-server"; + crateOutputs = config.nci.outputs.${projectName}; + in + { + nci.projects.${projectName}.path = ./.; + nci.crates.${projectName} = { }; + + packages = { + default = crateOutputs.packages.release; + ac-cup-server = crateOutputs.packages.release; + }; + + devShells.default = crateOutputs.devShell.overrideAttrs (old: { + packages = (old.packages or [ ]) ++ (with pkgs; [ + rust-analyzer + cargo-watch + cargo-edit + ]); + }); + + apps.default = { + type = "app"; + program = "${crateOutputs.packages.release}/bin/ac-cup-server"; + }; + }; + + flake = { + nixosModules.default = { config, lib, pkgs, ... }: + with lib; + let + cfg = config.services.ac-cup-server; + in + { + options.services.ac-cup-server = { + enable = mkEnableOption "AC Cup Server"; + + package = mkOption { + type = types.package; + default = inputs.self.packages.${pkgs.system}.default; + defaultText = literalExpression "inputs.self.packages.\${pkgs.system}.default"; + description = "The ac-cup-server package to use."; + }; + + host = mkOption { + type = types.str; + default = "0.0.0.0"; + example = "127.0.0.1"; + description = "IP address to bind to."; + }; + + port = mkOption { + type = types.port; + default = 3000; + description = "Port to listen on."; + }; + + storagePath = mkOption { + type = types.str; + default = "/var/lib/ac-cup-server/storage.json"; + description = "Path to the storage JSON file."; + }; + + environmentFile = mkOption { + type = types.nullOr types.path; + default = null; + description = "Environment file to load additional configuration from."; + }; + + logLevel = mkOption { + type = types.str; + default = "info"; + example = "debug"; + description = "Log level for the service (trace, debug, info, warn, error)."; + }; + }; + + config = mkIf cfg.enable { + systemd.services.ac-cup-server = { + description = "AC Cup Server"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + Type = "simple"; + DynamicUser = true; + StateDirectory = "ac-cup-server"; + ExecStart = "${cfg.package}/bin/ac-cup-server"; + Restart = "on-failure"; + RestartSec = "5s"; + + # Hardening + NoNewPrivileges = true; + PrivateTmp = true; + ProtectSystem = "strict"; + ProtectHome = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectControlGroups = true; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + LockPersonality = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + PrivateDevices = true; + ProtectClock = true; + }; + + environment = { + HOST = cfg.host; + PORT = toString cfg.port; + STORAGE_PATH = cfg.storagePath; + RUST_LOG = "ac_cup_server=${cfg.logLevel},tower_http=${cfg.logLevel},axum=${cfg.logLevel}"; + }; + + inherit (cfg) environmentFile; + }; + }; + }; + }; + }; +} + + + + diff --git a/src/main.rs b/src/main.rs index e49cada..b45132c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -48,12 +48,15 @@ async fn main() { .layer(TraceLayer::new_for_http()) .with_state(shared_storage); + let host = env::var("HOST") + .unwrap_or_else(|_| "0.0.0.0".to_string()); + let port = env::var("PORT") .unwrap_or_else(|_| "3000".to_string()) .parse::<u16>() .expect("PORT must be a valid number"); - let addr = format!("0.0.0.0:{}", port); + let addr = format!("{}:{}", host, port); let listener = tokio::net::TcpListener::bind(&addr) .await .expect("Failed to bind to address"); |
