mirror of
https://github.com/harivansh-afk/nix.git
synced 2026-04-15 06:04:42 +00:00
finish
This commit is contained in:
parent
1dc4ed5f1a
commit
9cfe51145d
3 changed files with 341 additions and 10 deletions
26
README.md
26
README.md
|
|
@ -49,14 +49,20 @@ just fmt
|
|||
## layout
|
||||
|
||||
```
|
||||
hosts/darwin/ - macOS host entrypoint
|
||||
hosts/netty/ - NixOS VPS entrypoint (disko + hardware)
|
||||
modules/ - shared system modules + devshells
|
||||
modules/hosts/ - flake-parts host output definitions
|
||||
modules/nixpkgs.nix - shared flake context (hosts, args, pkgs helpers)
|
||||
home/ - Home Manager modules
|
||||
lib/hosts.nix - host metadata used by the flake
|
||||
lib/ - shared package sets and theme system
|
||||
config/ - repo-owned config files (nvim, tmux, etc.)
|
||||
scripts/ - secret management and utility scripts
|
||||
hosts/darwin/ - macOS host entrypoint
|
||||
hosts/netty/ - NixOS VPS entrypoint (disko + hardware + services)
|
||||
modules/ - shared system modules + devshells
|
||||
modules/hosts/ - flake-parts host output definitions
|
||||
modules/nixpkgs.nix - shared flake context (hosts, specialArgs, pkgs)
|
||||
home/default.nix - unified home entry (conditional on hostConfig)
|
||||
home/common.nix - modules shared across all hosts
|
||||
home/xdg.nix - XDG compliance (env vars, config files)
|
||||
home/security.nix - SSH/GPG permission enforcement
|
||||
home/ - per-tool home-manager modules
|
||||
lib/hosts.nix - host metadata + feature flags
|
||||
lib/theme.nix - centralized color system (gruvbox)
|
||||
lib/package-sets.nix - shared + host-gated package lists
|
||||
config/ - repo-owned config files (nvim, tmux, etc.)
|
||||
scripts/ - secret management and utility scripts
|
||||
nix-maxxing.txt - architecture and operations guide
|
||||
```
|
||||
|
|
|
|||
|
|
@ -102,12 +102,166 @@ in
|
|||
environment.systemPackages = packageSets.extras ++ [
|
||||
pkgs.bubblewrap
|
||||
pkgs.pnpm
|
||||
pkgs.nodejs
|
||||
];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"L /usr/bin/bwrap - - - - ${pkgs.bubblewrap}/bin/bwrap"
|
||||
];
|
||||
|
||||
# --- ACME / Let's Encrypt ---
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = "rathiharivansh@gmail.com";
|
||||
};
|
||||
|
||||
# --- Nginx reverse proxy ---
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
clientMaxBodySize = "512m";
|
||||
|
||||
virtualHosts."sandbox.example.dev" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/".proxyPass = "http://127.0.0.1:2470";
|
||||
};
|
||||
|
||||
virtualHosts."git.example.dev" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/".proxyPass = "http://127.0.0.1:3000";
|
||||
};
|
||||
};
|
||||
|
||||
# --- Forgejo ---
|
||||
users.users.git = {
|
||||
isSystemUser = true;
|
||||
home = "/var/lib/forgejo";
|
||||
group = "git";
|
||||
shell = "${pkgs.bash}/bin/bash";
|
||||
};
|
||||
users.groups.git = { };
|
||||
|
||||
services.forgejo = {
|
||||
enable = true;
|
||||
user = "git";
|
||||
group = "git";
|
||||
settings = {
|
||||
server = {
|
||||
DOMAIN = "git.example.dev";
|
||||
ROOT_URL = "https://git.example.dev/";
|
||||
HTTP_PORT = 3000;
|
||||
SSH_DOMAIN = "git.example.dev";
|
||||
};
|
||||
service.DISABLE_REGISTRATION = true;
|
||||
session.COOKIE_SECURE = true;
|
||||
mirror = {
|
||||
DEFAULT_INTERVAL = "1h";
|
||||
MIN_INTERVAL = "10m";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# --- Forgejo mirror sync (hourly) ---
|
||||
systemd.services.forgejo-mirror-sync = {
|
||||
description = "Sync GitHub mirrors to Forgejo";
|
||||
after = [ "forgejo.service" ];
|
||||
requires = [ "forgejo.service" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
EnvironmentFile = "/etc/forgejo-mirror.env";
|
||||
};
|
||||
path = [ pkgs.curl pkgs.jq pkgs.coreutils ];
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
|
||||
# Fetch all GitHub repos
|
||||
page=1
|
||||
repos=""
|
||||
while true; do
|
||||
batch=$(curl -sf -H "Authorization: token $GITHUB_TOKEN" \
|
||||
"https://api.github.com/user/repos?per_page=100&page=$page&affiliation=owner")
|
||||
count=$(echo "$batch" | jq length)
|
||||
[ "$count" -eq 0 ] && break
|
||||
repos="$repos$batch"
|
||||
page=$((page + 1))
|
||||
done
|
||||
|
||||
echo "$repos" | jq -r '.[].clone_url' | while read -r clone_url; do
|
||||
repo_name=$(basename "$clone_url" .git)
|
||||
|
||||
# Check if mirror already exists in Forgejo
|
||||
status=$(curl -sf -o /dev/null -w '%{http_code}' \
|
||||
-H "Authorization: token $FORGEJO_TOKEN" \
|
||||
"$FORGEJO_URL/api/v1/repos/$FORGEJO_OWNER/$repo_name")
|
||||
|
||||
if [ "$status" = "404" ]; then
|
||||
# Create mirror
|
||||
curl -sf -X POST \
|
||||
-H "Authorization: token $FORGEJO_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
"$FORGEJO_URL/api/v1/repos/migrate" \
|
||||
-d "{
|
||||
\"clone_addr\": \"$clone_url\",
|
||||
\"auth_token\": \"$GITHUB_TOKEN\",
|
||||
\"uid\": $(curl -sf -H "Authorization: token $FORGEJO_TOKEN" "$FORGEJO_URL/api/v1/user" | jq .id),
|
||||
\"repo_name\": \"$repo_name\",
|
||||
\"mirror\": true,
|
||||
\"service\": \"github\"
|
||||
}"
|
||||
echo "Created mirror: $repo_name"
|
||||
else
|
||||
# Trigger sync on existing mirror
|
||||
curl -sf -X POST \
|
||||
-H "Authorization: token $FORGEJO_TOKEN" \
|
||||
"$FORGEJO_URL/api/v1/repos/$FORGEJO_OWNER/$repo_name/mirror-sync" || true
|
||||
echo "Synced mirror: $repo_name"
|
||||
fi
|
||||
done
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.timers.forgejo-mirror-sync = {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "hourly";
|
||||
Persistent = true;
|
||||
RandomizedDelaySec = "5m";
|
||||
};
|
||||
};
|
||||
|
||||
# --- Sandbox Agent (declarative systemd services) ---
|
||||
systemd.services.sandbox-agent = {
|
||||
description = "Sandbox Agent";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = username;
|
||||
Group = "users";
|
||||
EnvironmentFile = "/home/${username}/.config/sandbox-agent/agent.env";
|
||||
ExecStart = "/home/${username}/.local/bin/sandbox-agent";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 5;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.sandbox-cors-proxy = {
|
||||
description = "Sandbox CORS Proxy";
|
||||
after = [ "sandbox-agent.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = username;
|
||||
Group = "users";
|
||||
ExecStart = "${pkgs.nodejs}/bin/node /home/${username}/.config/sandbox-agent/cors-proxy.js";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 5;
|
||||
};
|
||||
};
|
||||
|
||||
system.configurationRevision = self.rev or self.dirtyRev or null;
|
||||
system.stateVersion = "24.11";
|
||||
}
|
||||
|
|
|
|||
171
nix-maxxing.txt
171
nix-maxxing.txt
|
|
@ -0,0 +1,171 @@
|
|||
Nix Config - Architecture and Operations Guide
|
||||
================================================
|
||||
|
||||
1. WHY STATIC IP (NOT DHCP)
|
||||
----------------------------
|
||||
DHCP on a VPS is dangerous. If the DHCP lease expires or the server
|
||||
reboots while the DHCP server is unreachable, the machine loses its IP
|
||||
and becomes inaccessible via SSH. This happened on netty (2026-03-30).
|
||||
|
||||
Static config in hosts/netty/configuration.nix:
|
||||
- IP: 152.53.195.59/22
|
||||
- Gateway: 152.53.192.1
|
||||
- Interface: ens3
|
||||
- DNS: 1.1.1.1, 8.8.8.8
|
||||
|
||||
Always verify the interface name with `ip link show` before changing
|
||||
network config. Keep VNC console access available as a fallback.
|
||||
|
||||
|
||||
2. HOST ABSTRACTION (hostConfig)
|
||||
---------------------------------
|
||||
lib/hosts.nix defines each machine with:
|
||||
- isDarwin / isLinux / isNixOS booleans
|
||||
- features map (rust, go, node, python, aws, claude, docker, tex)
|
||||
|
||||
modules/nixpkgs.nix passes hostConfig via specialArgs so all home-manager
|
||||
modules can use it. This replaces scattered `pkgs.stdenv.isDarwin` checks.
|
||||
|
||||
To add a new host:
|
||||
1. Add entry to lib/hosts.nix with all fields
|
||||
2. Create hosts/<name>/configuration.nix (NixOS) or add darwin case
|
||||
3. Add host output in modules/hosts/<name>.nix
|
||||
4. home/default.nix auto-selects modules based on hostConfig flags
|
||||
|
||||
home/default.nix is the unified entry point - no separate per-host home
|
||||
modules needed.
|
||||
|
||||
|
||||
3. XDG COMPLIANCE
|
||||
------------------
|
||||
home/xdg.nix sets environment variables so tools respect XDG dirs:
|
||||
|
||||
CARGO_HOME -> $XDG_DATA_HOME/cargo
|
||||
RUSTUP_HOME -> $XDG_DATA_HOME/rustup
|
||||
GOPATH -> $XDG_DATA_HOME/go
|
||||
GOMODCACHE -> $XDG_CACHE_HOME/go/mod
|
||||
NPM_CONFIG_USERCONFIG -> $XDG_CONFIG_HOME/npm/npmrc
|
||||
NODE_REPL_HISTORY -> $XDG_STATE_HOME/node_repl_history
|
||||
PYTHON_HISTORY -> $XDG_STATE_HOME/python_history
|
||||
AWS_CONFIG_FILE -> $XDG_CONFIG_HOME/aws/config
|
||||
DOCKER_CONFIG -> $XDG_CONFIG_HOME/docker
|
||||
CLAUDE_CONFIG_DIR -> $XDG_CONFIG_HOME/claude
|
||||
PSQL_HISTORY -> $XDG_STATE_HOME/psql_history
|
||||
SQLITE_HISTORY -> $XDG_STATE_HOME/sqlite_history
|
||||
LESSHISTFILE -> "-" (disabled)
|
||||
|
||||
All gated by hostConfig.features so tools only get configured when
|
||||
the feature flag is set for that host.
|
||||
|
||||
|
||||
4. SECURITY MODULE
|
||||
-------------------
|
||||
home/security.nix runs activation scripts on every `home-manager switch`:
|
||||
- ~/.ssh/ dir: 700, private keys: 600, pub/known_hosts/config: 644
|
||||
- ~/.gnupg/ dirs: 700, files: 600
|
||||
|
||||
No manual chmod needed after restoring keys from Bitwarden.
|
||||
|
||||
|
||||
5. THEME SYSTEM
|
||||
----------------
|
||||
lib/theme.nix is the single source of truth for colors.
|
||||
|
||||
Shared palette (gruvbox-inspired) used across:
|
||||
- Ghostty terminal (renderGhostty)
|
||||
- Tmux status bar (renderTmux)
|
||||
- fzf color scheme (renderFzf)
|
||||
- Zsh syntax highlighting (renderZshHighlights)
|
||||
- Bat (batTheme)
|
||||
- Git delta (deltaTheme)
|
||||
|
||||
Runtime toggle: `theme toggle` writes "light" or "dark" to
|
||||
$XDG_STATE_HOME/theme/current, then updates Ghostty, tmux, fzf,
|
||||
and Neovim (via RPC) live. Bat and delta are static at build time.
|
||||
|
||||
|
||||
6. SHELL SETUP
|
||||
---------------
|
||||
oh-my-zsh with agnoster theme (powerline arrows + git branch coloring).
|
||||
Vim mode via defaultKeymap = "viins" with cursor shape switching
|
||||
(beam for insert, block for normal).
|
||||
|
||||
History: 50k entries, dedup, ignoreSpace, extended format, stored at
|
||||
$XDG_STATE_HOME/zsh_history.
|
||||
|
||||
zoxide: declarative via programs.zoxide (no manual eval).
|
||||
|
||||
PATH: managed via home.sessionPath in xdg.nix + initContent block
|
||||
in zsh.nix for entries that need conditional logic.
|
||||
|
||||
|
||||
7. SERVER SERVICES (netty)
|
||||
---------------------------
|
||||
All in hosts/netty/configuration.nix:
|
||||
|
||||
Nginx reverse proxy with ACME SSL:
|
||||
- sandbox.example.dev -> 127.0.0.1:2470 (sandbox agent)
|
||||
- git.example.dev -> 127.0.0.1:3000 (forgejo)
|
||||
|
||||
Forgejo:
|
||||
- Self-hosted git, registration disabled
|
||||
- Runs as git user on port 3000
|
||||
- GitHub mirror sync via hourly systemd timer
|
||||
- Requires /etc/forgejo-mirror.env with GITHUB_TOKEN, FORGEJO_TOKEN,
|
||||
FORGEJO_URL, FORGEJO_OWNER
|
||||
|
||||
Sandbox Agent:
|
||||
- System-level systemd services (not user units)
|
||||
- sandbox-agent on :2470, env from ~/.config/sandbox-agent/agent.env
|
||||
- sandbox-cors-proxy on :2468 (Node.js)
|
||||
- No cloudflared - nginx handles SSL termination
|
||||
|
||||
Garbage collection: 3-day retention (vs 14-day on darwin).
|
||||
Disk guards: min-free 100MB, max-free 1GB.
|
||||
Journald: 1-week retention.
|
||||
|
||||
|
||||
8. DEPLOY COMMANDS
|
||||
-------------------
|
||||
Darwin (local):
|
||||
just switch
|
||||
|
||||
Netty (from mac):
|
||||
just switch-netty
|
||||
|
||||
First-time netty install:
|
||||
nix run github:nix-community/nixos-anywhere -- \
|
||||
--flake .#netty --target-host netty --build-on-remote
|
||||
|
||||
|
||||
9. ROLLBACK
|
||||
-------------
|
||||
Each phase is a separate git commit.
|
||||
|
||||
NixOS rollback:
|
||||
ssh netty "nixos-rebuild switch --rollback"
|
||||
|
||||
Or boot previous generation from GRUB (3 kept).
|
||||
|
||||
Darwin rollback:
|
||||
git revert <commit> && just switch
|
||||
|
||||
Home Manager rollback:
|
||||
home-manager generations # list
|
||||
home-manager switch --flake .#<host> # after git revert
|
||||
|
||||
|
||||
10. FEATURE FLAGS REFERENCE
|
||||
-----------------------------
|
||||
| Feature | darwin | netty |
|
||||
|---------|--------|-------|
|
||||
| rust | yes | yes |
|
||||
| go | yes | yes |
|
||||
| node | yes | yes |
|
||||
| python | yes | yes |
|
||||
| aws | yes | yes |
|
||||
| claude | yes | yes |
|
||||
| docker | yes | no |
|
||||
| tex | yes | no |
|
||||
|
||||
Set in lib/hosts.nix, consumed by home/xdg.nix and lib/package-sets.nix.
|
||||
Loading…
Add table
Add a link
Reference in a new issue