Files
usda-dash-config/default.nix
2025-12-18 18:58:25 -05:00

224 lines
7.1 KiB
Nix

{ inputs, ... }@moduleArgs:
# ============================================================================
# USDA Dashboard External System Module
# ============================================================================
# External system configuration for usda-dash
# This module can be referenced from nixos-systems/inventory.nix using:
#
# nix-lxc = {
# devices = {
# "usda-dash" = builtins.fetchGit {
# url = "https://git.factory.uga.edu/MODEL/usda-dash-config.git";
# rev = "commit-hash";
# };
# };
# };
{
config,
lib,
pkgs,
...
}:
let
# Get the directory where this module is located
moduleDir = builtins.toString (builtins.dirOf moduleArgs);
# Create a derivation that packages the usda-vision directory
usda-vision-app = pkgs.stdenv.mkDerivation {
pname = "usda-vision";
version = "1.0.0";
# Use the directory from this repository with explicit source filtering
src = lib.cleanSourceWith {
src = "${moduleDir}/usda-vision";
filter = path: type:
let
baseName = baseNameOf path;
in
# Exclude git, but include everything else
baseName != ".git" &&
baseName != ".cursor" &&
baseName != "__pycache__" &&
baseName != "node_modules" &&
baseName != ".venv";
};
nativeBuildInputs = [ pkgs.makeWrapper pkgs.rsync ];
# Don't run these phases, we'll do everything in installPhase
dontBuild = true;
dontConfigure = true;
installPhase = ''
mkdir -p $out/opt/usda-vision
# Debug: show what's in source
echo "Source directory contents:"
ls -la $src/ || true
# Copy all application files using rsync to preserve everything
${pkgs.rsync}/bin/rsync -av --exclude='.git' $src/ $out/opt/usda-vision/
# Verify files were copied
echo "Destination directory contents:"
ls -la $out/opt/usda-vision/ || true
# Remove any existing .env files
rm -f $out/opt/usda-vision/management-dashboard-web-app/.env
rm -f $out/opt/usda-vision/.env
# Update docker-compose.yml to use /var/lib/usda-vision/.env
# Use temp file in /tmp to avoid permission issues
if [ -f $out/opt/usda-vision/docker-compose.yml ]; then
${pkgs.gnused}/bin/sed 's|env_file:.*management-dashboard-web-app/\.env|env_file: /var/lib/usda-vision/.env|g; s|\./management-dashboard-web-app/\.env|/var/lib/usda-vision/.env|g' \
$out/opt/usda-vision/docker-compose.yml > /tmp/docker-compose.yml.tmp
mv /tmp/docker-compose.yml.tmp $out/opt/usda-vision/docker-compose.yml
fi
# Create convenience scripts
mkdir -p $out/bin
cat > $out/bin/usda-vision-start <<'EOF'
#!/usr/bin/env bash
cd $out/opt/usda-vision
${pkgs.docker-compose}/bin/docker-compose up -d --build
EOF
cat > $out/bin/usda-vision-stop <<'EOF'
#!/usr/bin/env bash
cd $out/opt/usda-vision
${pkgs.docker-compose}/bin/docker-compose down
EOF
cat > $out/bin/usda-vision-logs <<'EOF'
#!/usr%bin/env bash
cd $out/opt/usda-vision
${pkgs.docker-compose}/bin/docker-compose logs -f "$@"
EOF
cat > $out/bin/usda-vision-restart <<'EOF'
#!/usr/bin/env bash
cd $out/opt/usda-vision
${pkgs.docker-compose}/bin/docker-compose restart "$@"
EOF
chmod +x $out/bin/usda-vision-*
'';
meta = {
description = "USDA Vision camera management system";
maintainers = [ "UGA Innovation Factory" ];
};
};
in
{
# ========== Module Configuration ==========
config = {
# System packages specific to usda-dash
environment.systemPackages = with pkgs; [
# Core tools
git
vim
htop
curl
wget
# Docker and Docker Compose for running usda-vision
docker
docker-compose
# Supabase
supabase-cli
# USDA Vision application package with convenience scripts
usda-vision-app
];
# Enable Docker service
virtualisation.docker = {
enable = true;
autoPrune.enable = true;
};
# Configure users
athenix.users.sv22900.enable = true;
athenix.users.hdh20267.enable = true;
# Add users to docker group
users.users.sv22900.extraGroups = [ "docker" ];
# Create persistent directories and .env file location
systemd.tmpfiles.rules = [
"d /var/lib/usda-vision 0755 root root -"
"f /var/lib/usda-vision/.env 0644 root root -"
];
# Supabase CLI configuration in usda-vision-app directory
systemd.services.supabase-cli = {
enable = true;
description = "Supabase CLI Service";
serviceConfig = {
WorkingDirectory = "${usda-vision-app}/opt/usda-vision/management-dashboard-web-app";
ExecStart = "${pkgs.supabase-cli}/bin/supabase start";
Type = "oneshot";
RemainAfterExit = true;
User = "root";
Group = "root";
};
};
# Systemd service to manage usda-vision docker compose
systemd.services.usda-vision = {
description = "USDA Vision Docker Compose Stack";
after = [ "docker.service" "network-online.target" "systemd-tmpfiles-setup.service" ];
wants = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
# Only start if .env file exists and is not empty
unitConfig = {
ConditionPathExists = "/var/lib/usda-vision/.env";
ConditionPathIsReadWrite = "/var/lib/usda-vision/.env";
};
preStart = ''
# Ensure .env file exists with defaults if empty
if [ ! -s /var/lib/usda-vision/.env ]; then
if [ -f ${usda-vision-app}/opt/usda-vision/.env.example ]; then
echo "Copying .env.example to /var/lib/usda-vision/.env"
cp ${usda-vision-app}/opt/usda-vision/.env.example /var/lib/usda-vision/.env
echo "Please edit /var/lib/usda-vision/.env with your configuration"
fi
fi
'';
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
WorkingDirectory = "${usda-vision-app}/opt/usda-vision";
User = "root";
Group = "root";
# Start: pull latest images and start containers
ExecStart = "${pkgs.docker-compose}/bin/docker-compose -f ${usda-vision-app}/opt/usda-vision/docker-compose.yml up -d --build";
# Stop: gracefully stop containers
ExecStop = "${pkgs.docker-compose}/bin/docker-compose -f ${usda-vision-app}/opt/usda-vision/docker-compose.yml down";
# Reload: restart containers
ExecReload = "${pkgs.bash}/bin/bash -c '${pkgs.docker-compose}/bin/docker-compose -f ${usda-vision-app}/opt/usda-vision/docker-compose.yml down && ${pkgs.docker-compose}/bin/docker-compose -f ${usda-vision-app}/opt/usda-vision/docker-compose.yml up -d --build'";
TimeoutStartSec = 300;
TimeoutStopSec = 120;
};
};
# Firewall configuration
# networking.firewall.allowedTCPPorts = [ 80 443 ];
# Any other usda-dash specific configuration
};
}