refactor: improve local development environment setup

This commit is contained in:
2025-08-16 23:20:50 +02:00
parent 9cbfc36647
commit 94880d476e
2 changed files with 196 additions and 121 deletions

View File

@@ -1,4 +1,4 @@
{ pkgs, lib ? pkgs.lib, cloudServerNames, isLiveIso ? false, ... }:
{ pkgs, lib ? pkgs.lib, cloudServerNames, isLiveIso ? false, ... }:
let
# Only include isoImage config when building ISO
@@ -8,26 +8,62 @@ let
makeUsbBootable = true;
};
};
# Complete Co-op Cloud recipe list (based on your ABRA_RECIPES.md and more)
allRecipes = [
# Tier 1 - Production Ready (Score 5)
"gitea" "mealie" "nextcloud"
"gitea"
"mealie"
"nextcloud"
# Tier 2 - Stable (Score 4)
"gotosocial" "wordpress"
"gotosocial"
"wordpress"
# Tier 3 - Community (Score 3)
"collabora" "croc" "custom-php" "dokuwiki" "engelsystem" "fab-manager"
"ghost" "karrot" "lauti" "loomio" "mattermost" "mattermost-lts" "mrbs"
"onlyoffice" "open-inventory" "outline" "owncast" "rallly"
"collabora"
"croc"
"custom-php"
"dokuwiki"
"engelsystem"
"fab-manager"
"ghost"
"karrot"
"lauti"
"loomio"
"mattermost"
"mattermost-lts"
"mrbs"
"onlyoffice"
"open-inventory"
"outline"
"owncast"
"rallly"
# Additional recipes from Co-op Cloud catalog
"hedgedoc" "mediawiki" "seafile" "jitsi-meet" "matrix-synapse"
"rocketchat" "prestashop" "invoiceninja" "kimai" "pretix"
"drone" "n8n" "gitlab" "jupyter-lab" "plausible" "matomo"
"uptime-kuma" "grafana" "peertube" "funkwhale" "mastodon"
"pixelfed" "jellyfin"
"hedgedoc"
"mediawiki"
"seafile"
"jitsi-meet"
"matrix-synapse"
"rocketchat"
"prestashop"
"invoiceninja"
"kimai"
"pretix"
"drone"
"n8n"
"gitlab"
"jupyter-lab"
"plausible"
"matomo"
"uptime-kuma"
"grafana"
"peertube"
"funkwhale"
"mastodon"
"pixelfed"
"jellyfin"
];
in
@@ -35,10 +71,10 @@ isoConfig // {
system.stateVersion = "25.05";
networking = {
wireless.enable = false; # Disable to avoid conflicts
wireless.enable = false; # Disable to avoid conflicts
networkmanager = {
enable = true;
dns = "none"; # Critical: Don't let NetworkManager manage DNS
dns = "none"; # Critical: Don't let NetworkManager manage DNS
};
hostName = if isLiveIso then "workshop-live" else "workshop-vm";
};
@@ -49,24 +85,24 @@ isoConfig // {
settings = {
# Wildcard: *.workshop.local -> 127.0.0.1
address = "/.workshop.local/127.0.0.1";
# Use upstream DNS for everything else
server = [ "8.8.8.8" "1.1.1.1" ];
# Listen on all interfaces (important for VM/container access)
listen-address = [ "127.0.0.1" ];
# Bind to interfaces
bind-interfaces = true;
# Don't read /etc/hosts for our custom domains
no-hosts = false;
# Cache settings
cache-size = 1000;
log-queries = true;
log-dhcp = true;
# Local domain handling
local = "/workshop.local/";
domain-needed = true;
@@ -108,7 +144,7 @@ isoConfig // {
tree
nano
dnsutils
dig # For DNS debugging
dig # For DNS debugging
];
# Auto-install abra and setup Docker Swarm
@@ -118,7 +154,7 @@ isoConfig // {
wants = [ "network-online.target" ];
script = ''
export HOME=/home/workshop
# Wait for network and services with better testing
echo "Waiting for services to start..."
for i in {1..30}; do
@@ -129,7 +165,7 @@ isoConfig // {
fi
sleep 2
done
# Test DNS resolution specifically
for i in {1..20}; do
if ${pkgs.dnsutils}/bin/nslookup test.workshop.local 127.0.0.1 >/dev/null 2>&1; then
@@ -139,7 +175,7 @@ isoConfig // {
echo "🔄 Waiting for DNS... (attempt $i)"
sleep 2
done
# Test Docker
for i in {1..10}; do
if ${pkgs.docker}/bin/docker info >/dev/null 2>&1; then
@@ -148,22 +184,22 @@ isoConfig // {
fi
sleep 2
done
# Install abra for workshop user
if [ ! -f /home/workshop/.local/bin/abra ]; then
sudo -u workshop mkdir -p /home/workshop/.local/bin
cd /home/workshop
sudo -u workshop ${pkgs.curl}/bin/curl -fsSL https://install.abra.coopcloud.tech | sudo -u workshop ${pkgs.bash}/bin/bash
fi
# Initialize Docker Swarm
if ! ${pkgs.docker}/bin/docker info | grep -q "Swarm: active"; then
${pkgs.docker}/bin/docker swarm init --advertise-addr 127.0.0.1 2>/dev/null || true
fi
# Ensure workshop user is in docker group
usermod -aG docker workshop
# Test final DNS resolution
if ${pkgs.dnsutils}/bin/nslookup test.workshop.local 127.0.0.1; then
echo "🎉 All services ready!"
@@ -185,7 +221,7 @@ isoConfig // {
echo "🚀 CODE CRISPIES Workshop Environment"
echo "Mode: Local Development + Cloud Access"
echo ""
# Test DNS immediately on login
if command -v nslookup &> /dev/null; then
if nslookup test.workshop.local 127.0.0.1 >/dev/null 2>&1; then
@@ -208,7 +244,7 @@ isoConfig // {
COMPREPLY=()
cur="''${COMP_WORDS[COMP_CWORD]}"
prev="''${COMP_WORDS[COMP_CWORD-1]}"
case "''${prev}" in
deploy|browser)
opts="$ALL_RECIPES"
@@ -226,107 +262,144 @@ isoConfig // {
setup-traefik() {
echo "🔧 Setting up local Traefik proxy..."
# Test DNS first
# Test DNS first
if ! nslookup traefik.workshop.local 127.0.0.1 >/dev/null 2>&1; then
echo " DNS not resolving *.workshop.local"
echo "🔄 Restarting dnsmasq..."
sudo systemctl restart dnsmasq
sleep 3
if ! nslookup traefik.workshop.local 127.0.0.1 >/dev/null 2>&1; then
echo " DNS still not working!"
echo "🔍 Debug info:"
echo " systemctl status dnsmasq"
echo " nslookup traefik.workshop.local 127.0.0.1"
return 1
fi
fi
echo " DNS resolution working"
# Rest of your existing setup-traefik function...
# Ensure Docker Swarm is initialized
if ! docker info 2>/dev/null | grep -q "Swarm: active"; then
echo "🔥 Initializing Docker Swarm..."
docker swarm init --advertise-addr 127.0.0.1 || true
sleep 2
fi
# Create proxy network (CRITICAL for Traefik)
if ! docker network ls | grep -q "proxy"; then
echo "📡 Creating proxy overlay network..."
docker network create -d overlay proxy
fi
# Ensure abra is available
if ! command -v abra &> /dev/null; then
echo " Abra not found. Installing..."
sudo systemctl restart workshop-abra-setup
sleep 5
export PATH="$HOME/.local/bin:$PATH"
fi
# Ensure Docker Swarm is ready
if ! docker info 2>/dev/null | grep -q "Swarm: active"; then
echo "🔥 Initializing Docker Swarm..."
docker swarm init --advertise-addr 127.0.0.1 || true
fi
# Create abra context if not exists
if ! abra server ls 2>/dev/null | grep -q "workshop-local"; then
echo "🏗 Creating local abra context..."
# Check current server setup
echo "📋 Current servers:"
abra server ls || echo "No servers configured"
# Add local server if not exists (default name is "default")
if ! abra server ls 2>/dev/null | grep -q "default"; then
echo "🏗 Adding local server context..."
abra server add --local
sleep 2
fi
#echo "🚀 Deploying Traefik..."
#abra app new traefik -S --domain=traefik.workshop.local --server=workshop-local
#abra app deploy traefik.workshop.local
# Wait for Traefik to be ready
echo " Waiting for Traefik to start..."
for i in {1..30}; do
if curl -s http://traefik.workshop.local >/dev/null 2>&1; then
echo " Traefik deployed! Dashboard: http://traefik.workshop.local"
echo "🚀 Now you can deploy apps with 'deploy <recipe>'"
# Verify server is accessible
echo "📋 Servers after setup:"
abra server ls
# Check if Traefik app already exists
if abra app ls 2>/dev/null | grep -q "traefik"; then
echo " Traefik already configured"
traefik_domain=$(abra app ls | grep traefik | awk \'{print $1}\' | head -1)
echo "📍 Existing Traefik: $traefik_domain"
else
echo "🚀 Creating new Traefik app..."
# Use proper server context (default, not workshop-local)
abra app new traefik --domain=traefik.workshop.local --server=default
# Configure Traefik environment
echo " Configuring Traefik..."
traefik_env_file="$HOME/.abra/servers/default/traefik.workshop.local.env"
if [ -f "$traefik_env_file" ]; then
# Set required environment variables
if ! grep -q "LETS_ENCRYPT_EMAIL" "$traefik_env_file"; then
echo "LETS_ENCRYPT_EMAIL=workshop@local.dev" >> "$traefik_env_file"
fi
if ! grep -q "DASHBOARD_ENABLED" "$traefik_env_file"; then
echo "DASHBOARD_ENABLED=true" >> "$traefik_env_file"
fi
else
echo " Traefik env file not found at: $traefik_env_file"
fi
echo "📦 Deploying Traefik..."
abra app deploy traefik.workshop.local
traefik_domain="traefik.workshop.local"
fi
# Wait for Traefik to be ready
echo " Waiting for Traefik to be ready..."
for i in {1..60}; do
if curl -s --connect-timeout 3 --max-time 5 http://traefik.workshop.local/ping >/dev/null 2>&1; then
echo " Traefik is ready! Dashboard: http://traefik.workshop.local"
echo "🚀 You can now deploy apps with: deploy <recipe>"
return 0
fi
sleep 2
done
echo " Traefik deployed but may still be starting..."
echo "🔍 Debug: docker service ls | curl -I http://traefik.workshop.local"
echo " Traefik deployment timed out but may still be starting..."
echo ""
echo "🔍 Debug commands:"
echo " abra app ps traefik.workshop.local"
echo " abra app logs traefik.workshop.local"
echo " docker service ls"
echo " docker service logs \$(docker service ls --filter name=traefik -q)"
}
deploy() {
if [ -z "$1" ]; then
echo "Usage: deploy <recipe>"
echo "Example: deploy wordpress"
echo "Available recipes: $ALL_RECIPES"
echo ""
echo "🔍 Use tab completion or run 'recipes' for categorized list"
return 1
fi
local recipe="$1"
local domain="$recipe.workshop.local"
echo "🚀 Deploying $recipe locally..."
echo "Domain: $domain"
if ! command -v abra &> /dev/null; then
echo " Abra not found. Run 'sudo systemctl restart workshop-abra-setup'"
return 1
# Ensure Traefik is running first
if ! curl -s --max-time 3 http://traefik.workshop.local/ping >/dev/null 2>&1; then
echo " Traefik not responding. Setting up..."
setup-traefik || return 1
fi
# Check if Traefik is running
if ! curl -s http://traefik.workshop.local >/dev/null 2>&1; then
echo " Traefik not detected. Running setup first..."
setup-traefik
fi
echo "📦 Creating app: $recipe"
abra app new "$recipe" -S --domain="$domain" --server=workshop-local
# Use correct server name
abra app new "$recipe" --domain="$domain" --server=default -S 2>/dev/null || \
abra app new "$recipe" --domain="$domain" --server=default
echo "🚀 Deploying app: $domain"
abra app deploy "$domain"
echo " Waiting for deployment..."
for i in {1..60}; do
if curl -s http://$domain >/dev/null 2>&1; then
if curl -s --max-time 3 http://$domain >/dev/null 2>&1; then
echo " Deployed! Access at: http://$domain"
echo "🌐 Quick launch: browser $recipe"
return 0
fi
sleep 3
done
echo " Deployment completed but app may still be starting..."
echo "🔍 Debug: docker service ls | dig @127.0.0.1 $domain +short"
echo "🌐 Try: browser $recipe (in a few moments)"
echo " Deployment may still be starting..."
echo "🔍 Debug: abra app ps $domain"
}
connect() {
@@ -337,7 +410,7 @@ isoConfig // {
browser() {
local target_url="about:blank"
if [ -n "$1" ]; then
# Specific app requested
target_url="http://$1.workshop.local"
@@ -345,7 +418,7 @@ isoConfig // {
else
echo "🌐 Opening Firefox browser"
fi
if [ -n "$DISPLAY" ]; then
firefox "$target_url" &
else
@@ -360,7 +433,7 @@ isoConfig // {
echo " Tier 1 - Production Ready (Score 5):"
echo " gitea mealie nextcloud"
echo ""
echo "🔧 Tier 2 - Stable (Score 4):"
echo "🔧 Tier 2 - Stable (Score 4):"
echo " gotosocial wordpress"
echo ""
echo "🧪 Tier 3 - Community (Score 3):"