## Summary C2 Mikado chain to deploy [JobSync](https://github.com/Gsync/jobsync) — a self-hosted job application tracker — to ringtail's k3s cluster. ### Mikado Graph ``` deploy-jobsync (goal) ├── build-jobsync-container │ └── mirror-jobsync └── integrate-jobsync-ollama ``` ### What is JobSync? Next.js app with SQLite for tracking job applications. Features resume management, application pipeline tracking, and AI-powered resume review/job matching. ### Key Decisions - **Ringtail k3s** (not minikube-indri) — colocates with Ollama for zero-latency AI - **Nix container** via `buildLayeredImage` — no Dockerfile, mirrors upstream source on forge - **Ollama for AI** — uses existing deployment, no API keys needed for AI features - **No upstream fork** — vanilla JobSync, Anthropic AI deferred to future work if needed ### Current Status Planning phase — cards committed, ready for review before implementation begins. Reviewed-on: #288
126 lines
3.3 KiB
Nix
126 lines
3.3 KiB
Nix
# Nix-built JobSync container
|
|
# Next.js job application tracker with Prisma/SQLite
|
|
# Built with dockerTools.buildLayeredImage for efficient layer caching
|
|
{ pkgs ? import <nixpkgs> { } }:
|
|
|
|
let
|
|
version = "1.1.4";
|
|
|
|
prismaEngines = pkgs.prisma-engines;
|
|
|
|
src = pkgs.fetchgit {
|
|
url = "https://forge.ops.eblu.me/mirrors/jobsync.git";
|
|
rev = "v${version}";
|
|
hash = "sha256-59W5OF36yD67jEK5xa9jSL4EVN9RG+Ez/w9Mq2VykSA=";
|
|
};
|
|
|
|
jobsync = pkgs.buildNpmPackage {
|
|
inherit src version;
|
|
pname = "jobsync";
|
|
npmDepsHash = "sha256-yRNOxtz66qSlmfjR3QDPUQe0C8sdg06tBbuK1Ws1gEA=";
|
|
|
|
nodejs = pkgs.nodejs_20;
|
|
|
|
# Patch out Google Fonts import (nix sandbox blocks network access at
|
|
# build time). Replace with a simple object; app uses system sans-serif.
|
|
postPatch = ''
|
|
substituteInPlace src/app/layout.tsx \
|
|
--replace-fail 'import { Inter } from "next/font/google";' "" \
|
|
--replace-fail 'const inter = Inter({
|
|
subsets: ["latin"],
|
|
variable: "--font-inter",
|
|
});' 'const inter = { variable: "" };'
|
|
'';
|
|
|
|
# Point Prisma at nixpkgs-built engines (no network download in sandbox)
|
|
env = {
|
|
PRISMA_QUERY_ENGINE_LIBRARY = "${prismaEngines}/lib/libquery_engine.node";
|
|
PRISMA_QUERY_ENGINE_BINARY = "${prismaEngines}/bin/query-engine";
|
|
PRISMA_SCHEMA_ENGINE_BINARY = "${prismaEngines}/bin/schema-engine";
|
|
PRISMA_FMT_BINARY = "${prismaEngines}/bin/prisma-fmt";
|
|
PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING = "1";
|
|
DATABASE_URL = "file:/tmp/build.db";
|
|
NEXT_TELEMETRY_DISABLED = "1";
|
|
};
|
|
|
|
buildPhase = ''
|
|
runHook preBuild
|
|
|
|
# Generate Prisma client using nixpkgs engines
|
|
npx prisma generate
|
|
|
|
# Build Next.js
|
|
npm run build
|
|
|
|
runHook postBuild
|
|
'';
|
|
|
|
installPhase = ''
|
|
runHook preInstall
|
|
|
|
mkdir -p $out/app
|
|
|
|
# Copy Next.js standalone output
|
|
cp -r .next/standalone/. $out/app/
|
|
cp -r .next/static $out/app/.next/static
|
|
cp -r public $out/app/public
|
|
|
|
# Copy Prisma schema and migrations for runtime migrate deploy
|
|
cp -r prisma $out/app/prisma
|
|
|
|
# Copy entrypoint
|
|
cp ${./entrypoint.sh} $out/app/entrypoint.sh
|
|
|
|
runHook postInstall
|
|
'';
|
|
|
|
dontNpmBuild = true;
|
|
};
|
|
|
|
entrypoint = pkgs.writeShellScript "jobsync-entrypoint" ''
|
|
cd ${jobsync}/app
|
|
exec ${pkgs.bash}/bin/bash entrypoint.sh "$@"
|
|
'';
|
|
in
|
|
|
|
pkgs.dockerTools.buildLayeredImage {
|
|
name = "blumeops/jobsync";
|
|
tag = "latest";
|
|
|
|
contents = [
|
|
jobsync
|
|
prismaEngines
|
|
pkgs.nodejs_20
|
|
pkgs.cacert
|
|
pkgs.tzdata
|
|
pkgs.bash
|
|
pkgs.coreutils
|
|
];
|
|
|
|
# Create writable directories and FHS symlinks for nix container
|
|
extraCommands = ''
|
|
mkdir -p tmp data usr/bin
|
|
ln -s ${pkgs.coreutils}/bin/env usr/bin/env
|
|
'';
|
|
|
|
config = {
|
|
Entrypoint = [ "${entrypoint}" ];
|
|
WorkingDir = "${jobsync}/app";
|
|
Env = [
|
|
"SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"
|
|
"TZDIR=${pkgs.tzdata}/share/zoneinfo"
|
|
"NODE_ENV=production"
|
|
"PORT=3000"
|
|
"DATABASE_URL=file:/data/dev.db"
|
|
"PRISMA_QUERY_ENGINE_LIBRARY=${prismaEngines}/lib/libquery_engine.node"
|
|
"PRISMA_SCHEMA_ENGINE_BINARY=${prismaEngines}/bin/schema-engine"
|
|
"PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING=1"
|
|
];
|
|
ExposedPorts = {
|
|
"3000/tcp" = { };
|
|
};
|
|
Volumes = {
|
|
"/data" = { };
|
|
};
|
|
};
|
|
}
|