diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..617b2f3 --- /dev/null +++ b/flake.lock @@ -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": 1785301185, + "narHash": "sha256-eoS3KQTO0aPWXZvIaRbRAzSSHW3l5wdMFXtT1ISfoKA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9bc02893134c733dd85de46ee4fb2fac696b5529", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "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 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..f0a607f --- /dev/null +++ b/flake.nix @@ -0,0 +1,202 @@ +{ + description = "Asepharyana Hub — Nix builds for infrastructure and app services"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { + inherit system; + config.allowUnfree = true; + }; + + # ── mkApp generator ── + mkApp = { name, src, buildScript, installScript, nativeBuildInputs ? [], buildInputs ? [] }: + pkgs.stdenv.mkDerivation { + inherit name src; + + nativeBuildInputs = with pkgs; [ + cacert curl gcc gnumake openssl pkg-config python3 + ] ++ nativeBuildInputs; + + buildInputs = with pkgs; [ + nodejs openssl + ] ++ buildInputs; + + SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; + NODE_EXTRA_CA_CERTS = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; + NODE_ENV = "production"; + + phases = [ "unpackPhase" "buildPhase" "installPhase" ]; + buildPhase = buildScript; + installPhase = installScript; + }; + + # ── Node.js ── + nodejs = pkgs.nodejs-slim_22; + pnpm = pkgs.pnpm.override { inherit nodejs; }; + + # ── Common Rust build deps ── + cargoDeps = with pkgs; [ rustc cargo clang cmake pkg-config openssl.dev zlib ]; + + # ── Submodule repos — URLs from .gitmodules ── + submoduleRepos = { + hub = "https://github.com/asepharyana/asepharyana-hub-hub.git"; + scraper = "https://github.com/asepharyana/asepharyana-hub-scraper.git"; + tools = "https://github.com/asepharyana/asepharyana-hub-tools.git"; + llm-api = "https://github.com/asepharyana/asepharyana-hub-llm-api.git"; + }; + + # ── Fetch submodule source ── + submoduleSrc = name: builtins.fetchGit { + url = submoduleRepos.${name}; + rev = if name == "hub" then "b007ced615dcc78392fc938350a23e8f022d83b7" + else if name == "scraper" then "bc782ae4f825892f2d28901f4a5527f353106db1" + else if name == "tools" then "3956b90c3ce39ffa7ffba8084937f20e11364d6b" + else if name == "llm-api" then "HEAD" + else "HEAD"; + submodules = true; + }; + + # ─── App Derivations ─── + hub = mkApp { + name = "hub-0.1.0"; + src = submoduleSrc "hub"; + + nativeBuildInputs = with pkgs; [ bun ]; + + buildScript = '' + echo "=== Installing dependencies ===" + bun install 2>&1 + echo "=== Building Next.js ===" + bun run build 2>&1 + ''; + + installScript = '' + mkdir -p $out/share/hub $out/bin + cp -r .next $out/share/hub/ + cp -r public $out/share/hub/ 2>/dev/null || true + cp package.json $out/share/hub/ + cp -r node_modules $out/share/hub/ + cat > $out/bin/hub << WRAPPER +#!${pkgs.runtimeShell} +exec ${pkgs.bun}/bin/bun run --cwd $out/share/hub start +WRAPPER + chmod +x $out/bin/hub + ''; + }; + + scraper = mkApp { + name = "scraper-0.1.0"; + src = submoduleSrc "scraper"; + nativeBuildInputs = cargoDeps; + + buildScript = '' + echo "=== Building scraper ===" + cargo build --release 2>&1 + ''; + + installScript = '' + mkdir -p $out/bin + cp target/release/scraper $out/bin/scraper + ''; + }; + + tools-gateway = mkApp { + name = "tools-gateway-0.1.0"; + src = submoduleSrc "tools"; + nativeBuildInputs = cargoDeps ++ [ pkgs.tesseract ]; + + buildScript = '' + cd backend + echo "=== Building tools-gateway ===" + cargo build --release --features tesseract --bin tools-gateway 2>&1 + ''; + + installScript = '' + mkdir -p $out/bin + cp backend/target/release/tools-gateway $out/bin/tools-gateway + ''; + }; + + tools-workers = mkApp { + name = "tools-workers-0.1.0"; + src = submoduleSrc "tools"; + nativeBuildInputs = cargoDeps ++ [ pkgs.tesseract ]; + + buildScript = '' + cd backend + echo "=== Building tools-workers ===" + cargo build --release --features tesseract --bin tools-workers 2>&1 + ''; + + installScript = '' + mkdir -p $out/bin + cp backend/target/release/tools-workers $out/bin/tools-workers + ''; + }; + + tools-frontend = mkApp { + name = "tools-frontend-0.1.0"; + src = submoduleSrc "tools"; + nativeBuildInputs = with pkgs; [ bun ]; + + buildScript = '' + cd frontend + echo "=== Installing dependencies ===" + bun install 2>&1 + echo "=== Building Next.js ===" + bun run build 2>&1 + ''; + + installScript = '' + mkdir -p $out/share/tools-frontend $out/bin + cp -r frontend/.next $out/share/tools-frontend/ + cp -r frontend/public $out/share/tools-frontend/ 2>/dev/null || true + cp frontend/package.json $out/share/tools-frontend/ + cp -r frontend/node_modules $out/share/tools-frontend/ + cat > $out/bin/tools-frontend << WRAPPER +#!${pkgs.runtimeShell} +exec ${pkgs.bun}/bin/bun run --cwd $out/share/tools-frontend start +WRAPPER + chmod +x $out/bin/tools-frontend + ''; + }; + + llm-api = mkApp { + name = "llm-api-0.1.0"; + src = submoduleSrc "llm-api"; + nativeBuildInputs = cargoDeps; + + buildScript = '' + echo "=== Building llm-api ===" + cargo build --release 2>&1 + ''; + + installScript = '' + mkdir -p $out/bin + cp target/release/llm-api $out/bin/llm-api + ''; + }; + + in + { + packages = { + inherit hub scraper tools-gateway tools-workers tools-frontend llm-api; + default = hub; + }; + + apps.hub = { + type = "app"; + program = "${hub}/bin/hub"; + }; + + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ nodejs-slim_22 bun pnpm rustc cargo ]; + }; + }); +} diff --git a/infra/traefik/dynamic/apps.yaml b/infra/traefik/dynamic/apps.yaml index 955290f..f47d221 100644 --- a/infra/traefik/dynamic/apps.yaml +++ b/infra/traefik/dynamic/apps.yaml @@ -54,7 +54,7 @@ http: hub-service: loadBalancer: servers: - - url: 'http://hub:3000' + - url: 'http://host.docker.internal:3099' scraper-service: loadBalancer: diff --git a/result b/result new file mode 120000 index 0000000..54bea07 --- /dev/null +++ b/result @@ -0,0 +1 @@ +/nix/store/zycvvdznc30cn5h0cdl5ymag7qzffxhi-hub-0.1.0 \ No newline at end of file