playbook base initial skeleton
This commit is contained in:
commit
b97263495b
44
flake.lock
generated
Normal file
44
flake.lock
generated
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1741600792,
|
||||||
|
"narHash": "sha256-yfDy6chHcM7pXpMF4wycuuV+ILSTG486Z/vLx/Bdi6Y=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "ebe2788eafd539477f83775ef93c3c7e244421d3",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-24.11",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-unstable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1741708242,
|
||||||
|
"narHash": "sha256-cNRqdQD4sZpN7JLqxVOze4+WsWTmv2DGH0wNCOVwrWc=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "b62d2a95c72fb068aecd374a7262b37ed92df82b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "b62d2a95c72fb068aecd374a7262b37ed92df82b",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"nixpkgs-unstable": "nixpkgs-unstable"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
39
flake.nix
Normal file
39
flake.nix
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# self-host-playbook-base/flake.nix
|
||||||
|
{
|
||||||
|
description = "Base configuration for self-host-playbook";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
|
||||||
|
nixpkgs-unstable.url = "github:NixOS/nixpkgs/b62d2a95c72fb068aecd374a7262b37ed92df82b";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = {
|
||||||
|
self,
|
||||||
|
nixpkgs,
|
||||||
|
nixpkgs-unstable,
|
||||||
|
}: {
|
||||||
|
nixosModules = {
|
||||||
|
default = {tier ? "starter"}: {
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
nixpkgs.overlays = [
|
||||||
|
(final: _prev: {
|
||||||
|
unstable = import nixpkgs-unstable {
|
||||||
|
system = final.system;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
imports = [
|
||||||
|
./modules/core.nix
|
||||||
|
(import ./modules/services.nix {
|
||||||
|
inherit lib config pkgs;
|
||||||
|
tier = tier;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
69
justfiles/main.just
Normal file
69
justfiles/main.just
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import? "/etc/self-host-playbook/tiers/core.just"
|
||||||
|
import? "/etc/self-host-playbook/tiers/starter.just"
|
||||||
|
import? "/etc/self-host-playbook/tiers/premium.just"
|
||||||
|
|
||||||
|
@default:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Function to show the header
|
||||||
|
show_header() {
|
||||||
|
gum style \
|
||||||
|
--foreground 212 --border double --border-foreground 212 \
|
||||||
|
--align center --width 50 --margin "1 2" --padding "1 2" \
|
||||||
|
"🚀 DevOps Control Center 🚀"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to create menu items with icons and descriptions
|
||||||
|
create_menu() {
|
||||||
|
echo "📊 Status - Show running docker containers"
|
||||||
|
echo "📝 Logs - View container logs"
|
||||||
|
echo "💾 Disk Usage - Show docker disk usage"
|
||||||
|
echo "🔄 Restart - Restart a specific container"
|
||||||
|
echo "🐳 Update Docker - Update Docker containers"
|
||||||
|
echo "❌ Exit"
|
||||||
|
}
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
clear
|
||||||
|
show_header
|
||||||
|
|
||||||
|
# Show menu and get selection
|
||||||
|
choice=$(create_menu | gum choose --cursor.foreground 212 --selected.foreground 212 --header "Select an action:" --cursor "➜ ")
|
||||||
|
|
||||||
|
# Exit if no selection
|
||||||
|
if [ -z "$choice" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Process selection
|
||||||
|
case $choice in
|
||||||
|
"📊 Status"*)
|
||||||
|
just status
|
||||||
|
;;
|
||||||
|
"📝 Logs"*)
|
||||||
|
just logs
|
||||||
|
;;
|
||||||
|
"🛑 Stop All"*)
|
||||||
|
just docker-stop-all
|
||||||
|
;;
|
||||||
|
"🗑️ Prune"*)
|
||||||
|
just docker-prune
|
||||||
|
;;
|
||||||
|
"💾 Disk Usage"*)
|
||||||
|
just docker-disk
|
||||||
|
;;
|
||||||
|
"🔄 Restart"*)
|
||||||
|
just docker-restart
|
||||||
|
;;
|
||||||
|
"🐳 Update Docker"*)
|
||||||
|
just update-containers
|
||||||
|
;;
|
||||||
|
"❌ Exit")
|
||||||
|
echo "Goodbye! 👋" | gum style --foreground 212
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Pause after command execution
|
||||||
|
gum confirm "Press Enter to continue..." --default=true --affirmative "Continue" --negative "Exit" || exit 0
|
||||||
|
done
|
101
justfiles/tiers/core.just
Normal file
101
justfiles/tiers/core.just
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
status:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
gum style --foreground 212 --bold --border normal --align center --width 50 --margin "1 2" "📊 Running Containers"
|
||||||
|
docker ps --format "table {{"{{.Names}}\t{{.Status}}"}}" | gum table
|
||||||
|
|
||||||
|
# Interactive logs viewer with gum
|
||||||
|
logs:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
gum style --foreground 212 --bold --border normal --align center --width 50 --margin "1 2" "📝 Docker Logs Viewer"
|
||||||
|
|
||||||
|
# Get running container names
|
||||||
|
containers=($(docker ps --format "{{"{{.Names}}"}}"))
|
||||||
|
|
||||||
|
if [ ${#containers[@]} -eq 0 ]; then
|
||||||
|
gum style --foreground 1 "⚠️ No running containers found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Select container using gum choose
|
||||||
|
container=$(printf "%s\n" "${containers[@]}" | gum choose --header "Select a container:" --cursor.foreground 212)
|
||||||
|
|
||||||
|
if [ -z "$container" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Select number of lines using gum choose
|
||||||
|
lines=$(gum choose --header "Select number of log lines:" --cursor.foreground 212 \
|
||||||
|
"5 lines" "10 lines" "25 lines" "50 lines" "100 lines" "200 lines")
|
||||||
|
|
||||||
|
if [ -z "$lines" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract number from selection
|
||||||
|
lines=${lines%% *}
|
||||||
|
|
||||||
|
# Show spinner while fetching logs
|
||||||
|
gum spin --spinner dot --title "Fetching logs..." -- sleep 1
|
||||||
|
|
||||||
|
# Show logs
|
||||||
|
docker logs "$container" 2>&1 | tail -n "$lines" | gum pager
|
||||||
|
|
||||||
|
docker-disk:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
gum style --foreground 212 --bold --border normal --align center --width 50 --margin "1 2" "💾 Docker Disk Usage"
|
||||||
|
docker system df | gum table
|
||||||
|
|
||||||
|
docker-restart:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
containers=($(docker ps --format "{{"{{.Names}}"}}"))
|
||||||
|
if [ ${#containers[@]} -eq 0 ]; then
|
||||||
|
gum style --foreground 1 "⚠️ No running containers found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
container=$(printf "%s\n" "${containers[@]}" | gum choose --header "Select a container to restart:" --cursor.foreground 212)
|
||||||
|
if [ -n "$container" ]; then
|
||||||
|
gum spin --spinner dot --title "Restarting $container..." -- docker restart "$container"
|
||||||
|
gum style --foreground 212 "✅ Container $container restarted successfully!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
update-containers:
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e # Exit on error
|
||||||
|
CONTAINERS=($(docker ps --format "{{"{{.Names}}"}}"))
|
||||||
|
|
||||||
|
echo "Will update these containers:"
|
||||||
|
printf '%s\n' "${CONTAINERS[@]}" | gum table && \
|
||||||
|
gum confirm "Continue?" || exit 0
|
||||||
|
|
||||||
|
# First collect all image information
|
||||||
|
declare -A CONTAINER_IMAGES
|
||||||
|
echo "Collecting image information..."
|
||||||
|
for container in "${CONTAINERS[@]}"; do
|
||||||
|
FULL_IMAGE=$(docker inspect "$container" --format '{{"{{.Config.Image}}"}}')
|
||||||
|
CONTAINER_IMAGES[$container]=$(echo "$FULL_IMAGE" | sed 's/@sha256.*$//')
|
||||||
|
echo "$container -> ${CONTAINER_IMAGES[$container]}"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Stopping containers..." && \
|
||||||
|
for container in "${CONTAINERS[@]}"; do
|
||||||
|
echo "Stopping $container..."
|
||||||
|
sudo systemctl stop "docker-$container.service"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Pulling new images..." && \
|
||||||
|
for container in "${CONTAINERS[@]}"; do
|
||||||
|
IMAGE="${CONTAINER_IMAGES[$container]}"
|
||||||
|
echo -e "\n📥 Pulling $IMAGE for $container..." | gum style --foreground 99
|
||||||
|
if ! docker pull "$IMAGE" --quiet=false; then
|
||||||
|
echo "❌ Failed to pull $IMAGE" | gum style --foreground 196
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "------------------------"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Starting containers..." && \
|
||||||
|
for container in "${CONTAINERS[@]}"; do
|
||||||
|
echo "Starting $container..."
|
||||||
|
sudo systemctl start "docker-$container.service"
|
||||||
|
done && \
|
||||||
|
gum style --foreground 212 "✅ Containers updated successfully!"
|
0
justfiles/tiers/premium.just
Normal file
0
justfiles/tiers/premium.just
Normal file
0
justfiles/tiers/starter.just
Normal file
0
justfiles/tiers/starter.just
Normal file
95
modules/core.nix
Normal file
95
modules/core.nix
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
{pkgs, ...}: {
|
||||||
|
imports = [
|
||||||
|
./hardware-configuration.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
# Enable flakes and nix commands
|
||||||
|
nix = {
|
||||||
|
settings = {
|
||||||
|
experimental-features = ["nix-command" "flakes"];
|
||||||
|
# Enable automatic garbage collection
|
||||||
|
auto-optimise-store = true;
|
||||||
|
};
|
||||||
|
# Automatic cleanup of old generations
|
||||||
|
gc = {
|
||||||
|
automatic = true;
|
||||||
|
dates = "weekly";
|
||||||
|
options = "--delete-older-than 30d";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Boot configuration
|
||||||
|
boot.loader.grub = {
|
||||||
|
enable = true;
|
||||||
|
efiSupport = true;
|
||||||
|
efiInstallAsRemovable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Your base configuration here
|
||||||
|
system.autoUpgrade = {
|
||||||
|
enable = true;
|
||||||
|
allowReboot = true;
|
||||||
|
dates = "04:00";
|
||||||
|
flake = "path:/etc/nixos/current";
|
||||||
|
randomizedDelaySec = "45min";
|
||||||
|
flags = [
|
||||||
|
"--update-input nixpkgs"
|
||||||
|
"--update-input base-config"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Other base configurations...
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
PermitRootLogin = "no";
|
||||||
|
PasswordAuthentication = false;
|
||||||
|
MaxAuthTries = 3;
|
||||||
|
LoginGraceTime = "30s";
|
||||||
|
};
|
||||||
|
ports = [2222];
|
||||||
|
};
|
||||||
|
|
||||||
|
# System packages
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
# Docker tools
|
||||||
|
docker
|
||||||
|
docker-compose
|
||||||
|
# System utilities
|
||||||
|
neovim
|
||||||
|
git
|
||||||
|
unstable.gum
|
||||||
|
just
|
||||||
|
jq
|
||||||
|
(pkgs.writeShellScriptBin "shp" ''
|
||||||
|
exec sudo ${pkgs.just}/bin/just -f /etc/self-host-playbook/justfile "$@"
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
|
# Enable Docker with recommended settings
|
||||||
|
virtualisation = {
|
||||||
|
docker = {
|
||||||
|
enable = true;
|
||||||
|
# Enable docker daemon to start on boot
|
||||||
|
enableOnBoot = true;
|
||||||
|
# Use overlay2 storage driver
|
||||||
|
storageDriver = "overlay2";
|
||||||
|
# Enable live restore
|
||||||
|
liveRestore = true;
|
||||||
|
};
|
||||||
|
oci-containers = {
|
||||||
|
backend = "docker";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc = {
|
||||||
|
# Main justfile
|
||||||
|
"self-host-playbook/justfile".source = ../justfiles/main.just;
|
||||||
|
|
||||||
|
# Tier justfiles
|
||||||
|
"self-host-playbook/tiers/core.just".source = ../justfiles/tiers/core.just;
|
||||||
|
"self-host-playbook/tiers/starter.just".source = ../justfiles/tiers/starter.just;
|
||||||
|
};
|
||||||
|
# System state version (do not change)
|
||||||
|
system.stateVersion = "24.11";
|
||||||
|
}
|
26
modules/hardware-configuration.nix
Normal file
26
modules/hardware-configuration.nix
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
modulesPath,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/profiles/qemu-guest.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = ["ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod"];
|
||||||
|
boot.initrd.kernelModules = [];
|
||||||
|
boot.kernelModules = [];
|
||||||
|
boot.extraModulePackages = [];
|
||||||
|
|
||||||
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
|
# still possible to use this option, but it's recommended to use it in conjunction
|
||||||
|
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.ens18.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
}
|
37
modules/services.nix
Normal file
37
modules/services.nix
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# modules/services.nix
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
tier ? "starter",
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
tiers = {
|
||||||
|
starter = {
|
||||||
|
services = ["portainer" "caddy" "n8n"];
|
||||||
|
description = "Basic management tools";
|
||||||
|
};
|
||||||
|
premium = {
|
||||||
|
services = ["portainer" "caddy" "n8n" "baserow"];
|
||||||
|
description = "Automation and database tools";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
imports =
|
||||||
|
map
|
||||||
|
(serviceName: import ../services/${serviceName})
|
||||||
|
tiers.${tier}.services;
|
||||||
|
|
||||||
|
options.services.selfHostPlaybook = {
|
||||||
|
enable = mkEnableOption "self host playbook";
|
||||||
|
tier = mkOption {
|
||||||
|
type = types.enum ["starter" "premium"];
|
||||||
|
default = "starter";
|
||||||
|
description = "Service tier to enable";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf config.services.selfHostPlaybook.enable {
|
||||||
|
# Add any additional configuration here if needed
|
||||||
|
};
|
||||||
|
}
|
9
services/baserow/default.nix
Normal file
9
services/baserow/default.nix
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
virtualisation.oci-containers.containers.baserow = {
|
||||||
|
image = "docker.io/baserow/baserow:latest";
|
||||||
|
environmentFiles = ["/etc/environment-files/baserow.env"];
|
||||||
|
ports = ["127.0.0.1:3000:80"];
|
||||||
|
volumes = ["baserow_data:/baserow/data"];
|
||||||
|
extraOptions = ["--network=web"];
|
||||||
|
};
|
||||||
|
}
|
3
services/caddy/default.nix
Normal file
3
services/caddy/default.nix
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
services.caddy.enable = true;
|
||||||
|
}
|
28
services/core/default.nix
Normal file
28
services/core/default.nix
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./baserow
|
||||||
|
./n8n
|
||||||
|
./portainer
|
||||||
|
];
|
||||||
|
|
||||||
|
virtualisation.oci-containers.backend = "docker";
|
||||||
|
|
||||||
|
systemd.services.docker-network-web = {
|
||||||
|
description = "Create Docker Network Web";
|
||||||
|
requires = ["docker.service"];
|
||||||
|
after = ["docker.service"];
|
||||||
|
wantedBy = ["multi-user.target"];
|
||||||
|
|
||||||
|
# Run on startup if network doesn't exist
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
script = ''
|
||||||
|
if ! /run/current-system/sw/bin/docker network ls | grep -q 'web'; then
|
||||||
|
/run/current-system/sw/bin/docker network create web
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
9
services/n8n/default.nix
Normal file
9
services/n8n/default.nix
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
virtualisation.oci-containers.containers.n8n = {
|
||||||
|
image = "docker.io/n8nio/n8n:latest";
|
||||||
|
environmentFiles = ["/etc/environment-files/n8n.env"];
|
||||||
|
ports = ["127.0.0.1:5678:5678"];
|
||||||
|
volumes = ["n8n_data:/home/node/.n8n"];
|
||||||
|
extraOptions = ["--network=web"];
|
||||||
|
};
|
||||||
|
}
|
11
services/portainer/default.nix
Normal file
11
services/portainer/default.nix
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
virtualisation.oci-containers.containers.portainer = {
|
||||||
|
image = "docker.io/portainer/portainer-ce:latest";
|
||||||
|
ports = ["127.0.0.1:9000:9000"];
|
||||||
|
volumes = [
|
||||||
|
"/etc/localtime:/etc/localtime:ro"
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||||
|
"portainer_data:/data"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user