Enhance README and build scripts for hardware-specific optimizations
- Updated README.md to clarify development setup for macOS/Docker and added production build instructions for specific hardware. - Introduced new build scripts for optimized OS images targeting Start9 Server Pure, HP ProDesk 400 G4 DM, and Dell OptiPlex. - Enhanced Dockerfile to specify platform compatibility and improved Alpine profile for Archipelago builds. - Updated configuration files and init scripts to support new hardware profiles and ensure proper service management.
This commit is contained in:
@@ -1,38 +1,38 @@
|
||||
#!/bin/sh
|
||||
# Alpine mkimage profile for Archipelago Bitcoin Node OS
|
||||
# Based on Alpine's standard profile
|
||||
|
||||
# Source the standard profile functions
|
||||
. "$(dirname "$0")/mkimg.standard.sh"
|
||||
|
||||
# Additional packages for Archipelago
|
||||
apks="$apks
|
||||
systemd
|
||||
systemd-openrc
|
||||
podman
|
||||
podman-compose
|
||||
crun
|
||||
fuse-overlayfs
|
||||
slirp4netns
|
||||
networkmanager
|
||||
networkmanager-openrc
|
||||
openssh
|
||||
openssh-openrc
|
||||
nginx
|
||||
nginx-openrc
|
||||
"
|
||||
|
||||
# Kernel flavor
|
||||
kernel_flavors="lts"
|
||||
|
||||
# Bootloader
|
||||
boot_addons="grub-efi"
|
||||
|
||||
# Initfs features
|
||||
initfs_features="base squashfs ext4 usb pcmcia scsi mmc nvme virtio"
|
||||
|
||||
# Initfs modules
|
||||
initfs_modules="loop squashfs"
|
||||
profile_archipelago() {
|
||||
profile_standard
|
||||
|
||||
# Additional packages for Archipelago
|
||||
apks="$apks
|
||||
systemd
|
||||
systemd-openrc
|
||||
podman
|
||||
podman-compose
|
||||
crun
|
||||
fuse-overlayfs
|
||||
slirp4netns
|
||||
networkmanager
|
||||
networkmanager-openrc
|
||||
openssh
|
||||
openssh-openrc
|
||||
nginx
|
||||
nginx-openrc
|
||||
"
|
||||
|
||||
# Kernel flavor
|
||||
kernel_flavors="lts"
|
||||
|
||||
# Bootloader
|
||||
boot_addons="grub-efi"
|
||||
|
||||
# Initfs features
|
||||
initfs_features="base squashfs ext4 usb pcmcia scsi mmc nvme virtio"
|
||||
|
||||
# Initfs modules
|
||||
initfs_modules="loop squashfs"
|
||||
}
|
||||
|
||||
# Post-install hook - called after base system is installed
|
||||
profile_apkovl() {
|
||||
@@ -54,36 +54,36 @@ profile_apkovl() {
|
||||
|
||||
# Create first boot script
|
||||
mkdir -p "$apkroot"/etc/local.d
|
||||
cat > "$apkroot"/etc/local.d/archipelago-install.start <<'INSTALL_EOF'
|
||||
#!/bin/sh
|
||||
# First boot installation script for Archipelago
|
||||
|
||||
# Install backend APK if available
|
||||
if [ -f /tmp/archipelago-backend.apk ]; then
|
||||
apk add --allow-untrusted /tmp/archipelago-backend.apk
|
||||
rm /tmp/archipelago-backend.apk
|
||||
fi
|
||||
|
||||
# Enable services
|
||||
rc-update add archipelago default 2>/dev/null || true
|
||||
systemctl enable archipelago 2>/dev/null || true
|
||||
|
||||
# Create archipelago user if needed
|
||||
if ! id archipelago >/dev/null 2>&1; then
|
||||
adduser -D -s /bin/bash archipelago
|
||||
echo "archipelago ALL=(ALL) NOPASSWD: /usr/bin/podman" >> /etc/sudoers
|
||||
fi
|
||||
|
||||
# Setup Podman for archipelago user
|
||||
mkdir -p /home/archipelago/.config/containers
|
||||
chown -R archipelago:archipelago /home/archipelago
|
||||
|
||||
# Create data directories
|
||||
mkdir -p /var/lib/archipelago/{apps,secrets,logs,backups}
|
||||
chown -R archipelago:archipelago /var/lib/archipelago
|
||||
|
||||
# Start services
|
||||
rc-service archipelago start 2>/dev/null || systemctl start archipelago 2>/dev/null || true
|
||||
INSTALL_EOF
|
||||
{
|
||||
echo '#!/bin/sh'
|
||||
echo '# First boot installation script for Archipelago'
|
||||
echo ''
|
||||
echo '# Install backend APK if available'
|
||||
echo 'if [ -f /tmp/archipelago-backend.apk ]; then'
|
||||
echo ' apk add --allow-untrusted /tmp/archipelago-backend.apk'
|
||||
echo ' rm /tmp/archipelago-backend.apk'
|
||||
echo 'fi'
|
||||
echo ''
|
||||
echo '# Enable services'
|
||||
echo 'rc-update add archipelago default 2>/dev/null || true'
|
||||
echo 'systemctl enable archipelago 2>/dev/null || true'
|
||||
echo ''
|
||||
echo '# Create archipelago user if needed'
|
||||
echo 'if ! id archipelago >/dev/null 2>&1; then'
|
||||
echo ' adduser -D -s /bin/bash archipelago'
|
||||
echo ' echo "archipelago ALL=(ALL) NOPASSWD: /usr/bin/podman" >>/etc/sudoers'
|
||||
echo 'fi'
|
||||
echo ''
|
||||
echo '# Setup Podman for archipelago user'
|
||||
echo 'mkdir -p /home/archipelago/.config/containers'
|
||||
echo 'chown -R archipelago:archipelago /home/archipelago'
|
||||
echo ''
|
||||
echo '# Create data directories'
|
||||
echo 'mkdir -p /var/lib/archipelago/apps /var/lib/archipelago/secrets /var/lib/archipelago/logs /var/lib/archipelago/backups'
|
||||
echo 'chown -R archipelago:archipelago /var/lib/archipelago'
|
||||
echo ''
|
||||
echo '# Start services'
|
||||
echo 'rc-service archipelago start 2>/dev/null || systemctl start archipelago 2>/dev/null || true'
|
||||
} > "$apkroot"/etc/local.d/archipelago-install.start
|
||||
chmod +x "$apkroot"/etc/local.d/archipelago-install.start
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/bin/sh
|
||||
# Hardware detection and optimization script
|
||||
# Auto-generated for specific hardware target
|
||||
|
||||
detect_hardware() {
|
||||
echo "=== Hardware Detection ==="
|
||||
|
||||
# CPU info
|
||||
if [ -f /proc/cpuinfo ]; then
|
||||
echo "CPU: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d':' -f2 | xargs)"
|
||||
echo "Cores: $(grep -c processor /proc/cpuinfo)"
|
||||
fi
|
||||
|
||||
# Memory
|
||||
if [ -f /proc/meminfo ]; then
|
||||
echo "Memory: $(grep MemTotal /proc/meminfo | awk '{printf "%.1f GB", $2/1024/1024}')"
|
||||
fi
|
||||
|
||||
# Storage
|
||||
if command -v lsblk >/dev/null 2>&1; then
|
||||
echo "Storage:"
|
||||
lsblk -d -o NAME,SIZE,TYPE | grep disk
|
||||
fi
|
||||
|
||||
# Network
|
||||
if command -v ip >/dev/null 2>&1; then
|
||||
echo "Network interfaces:"
|
||||
ip -br link show | grep -v lo
|
||||
fi
|
||||
|
||||
# PCI devices (for hardware identification)
|
||||
if command -v lspci >/dev/null 2>&1; then
|
||||
echo "PCI devices:"
|
||||
lspci | grep -E "VGA|Ethernet|Network"
|
||||
fi
|
||||
}
|
||||
|
||||
optimize_for_hardware() {
|
||||
echo "=== Hardware Optimization ==="
|
||||
|
||||
# Load Intel microcode if Intel CPU
|
||||
if grep -q Intel /proc/cpuinfo; then
|
||||
echo "Intel CPU detected, loading microcode..."
|
||||
modprobe intel_rapl_common 2>/dev/null || true
|
||||
modprobe intel_powerclamp 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Enable hardware acceleration for graphics
|
||||
if lspci | grep -q "Intel.*Graphics"; then
|
||||
echo "Intel Graphics detected"
|
||||
modprobe i915 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optimize for NVMe if present
|
||||
if [ -e /dev/nvme0n1 ]; then
|
||||
echo "NVMe SSD detected, optimizing..."
|
||||
echo none > /sys/block/nvme0n1/queue/scheduler 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optimize for SATA SSD if present
|
||||
if [ -e /dev/sda ]; then
|
||||
if hdparm -I /dev/sda 2>/dev/null | grep -q "Solid State"; then
|
||||
echo "SATA SSD detected, optimizing..."
|
||||
echo deadline > /sys/block/sda/queue/scheduler 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Run detection
|
||||
detect_hardware
|
||||
optimize_for_hardware
|
||||
@@ -0,0 +1,26 @@
|
||||
# Hardware profile for HP ProDesk 400 G4 DM
|
||||
# Auto-generated during build
|
||||
|
||||
[hardware]
|
||||
target = "hp-prodesk"
|
||||
name = "HP ProDesk 400 G4 DM"
|
||||
cpu_vendor = "intel"
|
||||
cpu_model = "varies"
|
||||
min_ram = "8GB"
|
||||
min_storage = "128GB"
|
||||
architecture = "x86_64"
|
||||
|
||||
[optimizations]
|
||||
enabled = intel-graphics intel-networking sata-ssd
|
||||
|
||||
[network]
|
||||
interfaces = "1x Gigabit Ethernet"
|
||||
|
||||
[usb]
|
||||
ports = "4x USB 3.0, 2x USB 2.0"
|
||||
|
||||
[build]
|
||||
version = "0.1.0"
|
||||
alpine_version = "3.19"
|
||||
build_date = "2026-01-31T19:47:29Z"
|
||||
build_type = "iso"
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
# First boot hardware detection and optimization
|
||||
|
||||
HARDWARE_INFO="/etc/archipelago/hardware-info.sh"
|
||||
|
||||
if [ -x "$HARDWARE_INFO" ]; then
|
||||
echo "🔍 Detecting hardware..."
|
||||
$HARDWARE_INFO > /var/log/archipelago-hardware.log 2>&1
|
||||
echo "✓ Hardware detection complete"
|
||||
fi
|
||||
|
||||
# Create system info file
|
||||
cat > /etc/archipelago/system-info.txt <<INFO
|
||||
Archipelago OS System Information
|
||||
Generated: $(date)
|
||||
|
||||
$(cat /etc/archipelago/hardware.toml 2>/dev/null)
|
||||
|
||||
Runtime Detection:
|
||||
$(cat /var/log/archipelago-hardware.log 2>/dev/null)
|
||||
INFO
|
||||
@@ -0,0 +1,38 @@
|
||||
# Archipelago Node OS Configuration
|
||||
|
||||
[server]
|
||||
# Server listening configuration
|
||||
host = "0.0.0.0" # Listen on all interfaces
|
||||
port = 8100
|
||||
data_dir = "/var/lib/archipelago"
|
||||
|
||||
[network]
|
||||
# Automatic Ethernet configuration
|
||||
auto_configure = true
|
||||
dhcp = true
|
||||
dns_servers = ["8.8.8.8", "8.8.4.4", "1.1.1.1"]
|
||||
|
||||
[containers]
|
||||
# Container runtime (Podman)
|
||||
runtime = "podman"
|
||||
rootless = true
|
||||
auto_start = true
|
||||
|
||||
[apps]
|
||||
# App directory
|
||||
apps_dir = "/var/lib/archipelago/apps"
|
||||
auto_start_enabled = true
|
||||
|
||||
[security]
|
||||
# Security settings
|
||||
require_auth = false # Disable for first boot, enable after setup
|
||||
secrets_dir = "/var/lib/archipelago/secrets"
|
||||
|
||||
[logging]
|
||||
level = "info"
|
||||
dir = "/var/lib/archipelago/logs"
|
||||
|
||||
[ui]
|
||||
# Web UI settings
|
||||
enabled = true
|
||||
path = "/usr/share/archipelago/web"
|
||||
71
image-recipe/alpine-profile/overlay-merged/etc/archipelago/hardware-info.sh
Executable file
71
image-recipe/alpine-profile/overlay-merged/etc/archipelago/hardware-info.sh
Executable file
@@ -0,0 +1,71 @@
|
||||
#!/bin/sh
|
||||
# Hardware detection and optimization script
|
||||
# Auto-generated for specific hardware target
|
||||
|
||||
detect_hardware() {
|
||||
echo "=== Hardware Detection ==="
|
||||
|
||||
# CPU info
|
||||
if [ -f /proc/cpuinfo ]; then
|
||||
echo "CPU: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d':' -f2 | xargs)"
|
||||
echo "Cores: $(grep -c processor /proc/cpuinfo)"
|
||||
fi
|
||||
|
||||
# Memory
|
||||
if [ -f /proc/meminfo ]; then
|
||||
echo "Memory: $(grep MemTotal /proc/meminfo | awk '{printf "%.1f GB", $2/1024/1024}')"
|
||||
fi
|
||||
|
||||
# Storage
|
||||
if command -v lsblk >/dev/null 2>&1; then
|
||||
echo "Storage:"
|
||||
lsblk -d -o NAME,SIZE,TYPE | grep disk
|
||||
fi
|
||||
|
||||
# Network
|
||||
if command -v ip >/dev/null 2>&1; then
|
||||
echo "Network interfaces:"
|
||||
ip -br link show | grep -v lo
|
||||
fi
|
||||
|
||||
# PCI devices (for hardware identification)
|
||||
if command -v lspci >/dev/null 2>&1; then
|
||||
echo "PCI devices:"
|
||||
lspci | grep -E "VGA|Ethernet|Network"
|
||||
fi
|
||||
}
|
||||
|
||||
optimize_for_hardware() {
|
||||
echo "=== Hardware Optimization ==="
|
||||
|
||||
# Load Intel microcode if Intel CPU
|
||||
if grep -q Intel /proc/cpuinfo; then
|
||||
echo "Intel CPU detected, loading microcode..."
|
||||
modprobe intel_rapl_common 2>/dev/null || true
|
||||
modprobe intel_powerclamp 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Enable hardware acceleration for graphics
|
||||
if lspci | grep -q "Intel.*Graphics"; then
|
||||
echo "Intel Graphics detected"
|
||||
modprobe i915 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optimize for NVMe if present
|
||||
if [ -e /dev/nvme0n1 ]; then
|
||||
echo "NVMe SSD detected, optimizing..."
|
||||
echo none > /sys/block/nvme0n1/queue/scheduler 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optimize for SATA SSD if present
|
||||
if [ -e /dev/sda ]; then
|
||||
if hdparm -I /dev/sda 2>/dev/null | grep -q "Solid State"; then
|
||||
echo "SATA SSD detected, optimizing..."
|
||||
echo deadline > /sys/block/sda/queue/scheduler 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Run detection
|
||||
detect_hardware
|
||||
optimize_for_hardware
|
||||
@@ -0,0 +1,26 @@
|
||||
# Hardware profile for HP ProDesk 400 G4 DM
|
||||
# Auto-generated during build
|
||||
|
||||
[hardware]
|
||||
target = "hp-prodesk"
|
||||
name = "HP ProDesk 400 G4 DM"
|
||||
cpu_vendor = "intel"
|
||||
cpu_model = "varies"
|
||||
min_ram = "8GB"
|
||||
min_storage = "128GB"
|
||||
architecture = "x86_64"
|
||||
|
||||
[optimizations]
|
||||
enabled = intel-graphics intel-networking sata-ssd
|
||||
|
||||
[network]
|
||||
interfaces = "1x Gigabit Ethernet"
|
||||
|
||||
[usb]
|
||||
ports = "4x USB 3.0, 2x USB 2.0"
|
||||
|
||||
[build]
|
||||
version = "0.1.0"
|
||||
alpine_version = "3.19"
|
||||
build_date = "2026-01-31T19:47:29Z"
|
||||
build_type = "iso"
|
||||
1
image-recipe/alpine-profile/overlay-merged/etc/hostname
Normal file
1
image-recipe/alpine-profile/overlay-merged/etc/hostname
Normal file
@@ -0,0 +1 @@
|
||||
archipelago
|
||||
4
image-recipe/alpine-profile/overlay-merged/etc/hosts
Normal file
4
image-recipe/alpine-profile/overlay-merged/etc/hosts
Normal file
@@ -0,0 +1,4 @@
|
||||
127.0.0.1 localhost archipelago
|
||||
::1 localhost archipelago ip6-localhost ip6-loopback
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
||||
52
image-recipe/alpine-profile/overlay-merged/etc/init.d/archipelago
Executable file
52
image-recipe/alpine-profile/overlay-merged/etc/init.d/archipelago
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/sbin/openrc-run
|
||||
# Archipelago Bitcoin Node OS Backend
|
||||
|
||||
name="Archipelago"
|
||||
description="Archipelago Bitcoin Node OS Backend Server"
|
||||
command="/usr/bin/archipelago-backend"
|
||||
command_user="archipelago:archipelago"
|
||||
command_background=true
|
||||
pidfile="/var/run/archipelago.pid"
|
||||
start_stop_daemon_args="--make-pidfile"
|
||||
|
||||
# Working directory and environment
|
||||
directory="/var/lib/archipelago"
|
||||
export RUST_LOG="${RUST_LOG:-info}"
|
||||
export ARCHIPELAGO_DATA_DIR="/var/lib/archipelago"
|
||||
export ARCHIPELAGO_PORT="${ARCHIPELAGO_PORT:-8100}"
|
||||
|
||||
depend() {
|
||||
need net
|
||||
need localmount
|
||||
after firewall
|
||||
use podman docker
|
||||
}
|
||||
|
||||
start_pre() {
|
||||
# Ensure directories exist
|
||||
checkpath --directory --mode 0755 --owner archipelago:archipelago \
|
||||
/var/lib/archipelago \
|
||||
/var/lib/archipelago/apps \
|
||||
/var/lib/archipelago/secrets \
|
||||
/var/lib/archipelago/logs \
|
||||
/var/lib/archipelago/backups
|
||||
|
||||
# Wait for network to be fully ready
|
||||
local retries=30
|
||||
while [ $retries -gt 0 ]; do
|
||||
if ping -c 1 -W 1 8.8.8.8 >/dev/null 2>&1; then
|
||||
einfo "Network is ready"
|
||||
return 0
|
||||
fi
|
||||
retries=$((retries - 1))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
ewarn "Network may not be fully ready"
|
||||
return 0
|
||||
}
|
||||
|
||||
start_post() {
|
||||
einfo "Archipelago backend started"
|
||||
einfo "Access the UI at: http://$(hostname -I | awk '{print $1}'):8100"
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
# Alpine Linux boot configuration for Archipelago
|
||||
# This runs early in the boot process
|
||||
|
||||
# Enable essential services
|
||||
rc-update add devfs sysinit 2>/dev/null || true
|
||||
rc-update add dmesg sysinit 2>/dev/null || true
|
||||
rc-update add mdev sysinit 2>/dev/null || true
|
||||
rc-update add hwdrivers sysinit 2>/dev/null || true
|
||||
|
||||
# Enable boot services
|
||||
rc-update add bootmisc boot 2>/dev/null || true
|
||||
rc-update add hostname boot 2>/dev/null || true
|
||||
rc-update add hwclock boot 2>/dev/null || true
|
||||
rc-update add modules boot 2>/dev/null || true
|
||||
rc-update add swap boot 2>/dev/null || true
|
||||
rc-update add sysctl boot 2>/dev/null || true
|
||||
rc-update add syslog boot 2>/dev/null || true
|
||||
rc-update add networking boot 2>/dev/null || true
|
||||
rc-update add urandom boot 2>/dev/null || true
|
||||
|
||||
# Enable default services
|
||||
rc-update add local default 2>/dev/null || true
|
||||
rc-update add sshd default 2>/dev/null || true
|
||||
rc-update add archipelago default 2>/dev/null || true
|
||||
|
||||
# Enable shutdown services
|
||||
rc-update add killprocs shutdown 2>/dev/null || true
|
||||
rc-update add mount-ro shutdown 2>/dev/null || true
|
||||
rc-update add savecache shutdown 2>/dev/null || true
|
||||
|
||||
echo "✓ Archipelago boot services configured"
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
# First boot hardware detection and optimization
|
||||
|
||||
HARDWARE_INFO="/etc/archipelago/hardware-info.sh"
|
||||
|
||||
if [ -x "$HARDWARE_INFO" ]; then
|
||||
echo "🔍 Detecting hardware..."
|
||||
$HARDWARE_INFO > /var/log/archipelago-hardware.log 2>&1
|
||||
echo "✓ Hardware detection complete"
|
||||
fi
|
||||
|
||||
# Create system info file
|
||||
cat > /etc/archipelago/system-info.txt <<INFO
|
||||
Archipelago OS System Information
|
||||
Generated: $(date)
|
||||
|
||||
$(cat /etc/archipelago/hardware.toml 2>/dev/null)
|
||||
|
||||
Runtime Detection:
|
||||
$(cat /var/log/archipelago-hardware.log 2>/dev/null)
|
||||
INFO
|
||||
@@ -0,0 +1,88 @@
|
||||
#!/bin/sh
|
||||
# First boot network and service setup for Archipelago
|
||||
|
||||
# Configure hostname
|
||||
if [ ! -f /etc/hostname.configured ]; then
|
||||
echo "archipelago-node" > /etc/hostname
|
||||
hostname archipelago-node
|
||||
touch /etc/hostname.configured
|
||||
fi
|
||||
|
||||
# Configure networking - Ethernet with DHCP
|
||||
if [ ! -f /etc/network/interfaces.configured ]; then
|
||||
cat > /etc/network/interfaces <<'NETEOF'
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
# Automatic Ethernet configuration (DHCP)
|
||||
auto eth0
|
||||
iface eth0 inet dhcp
|
||||
hostname archipelago-node
|
||||
|
||||
# Fallback for other ethernet names
|
||||
auto enp0s3
|
||||
iface enp0s3 inet dhcp
|
||||
hostname archipelago-node
|
||||
|
||||
auto enp0s25
|
||||
iface enp0s25 inet dhcp
|
||||
hostname archipelago-node
|
||||
|
||||
auto ens0
|
||||
iface ens0 inet dhcp
|
||||
hostname archipelago-node
|
||||
NETEOF
|
||||
touch /etc/network/interfaces.configured
|
||||
fi
|
||||
|
||||
# Enable and start networking
|
||||
rc-update add networking boot 2>/dev/null || true
|
||||
rc-service networking start 2>/dev/null || true
|
||||
|
||||
# Wait for network to be ready
|
||||
echo "Waiting for network..."
|
||||
retries=30
|
||||
while [ $retries -gt 0 ]; do
|
||||
if ip route | grep -q default; then
|
||||
echo "✓ Network is ready"
|
||||
ip addr show | grep "inet " | grep -v "127.0.0.1"
|
||||
break
|
||||
fi
|
||||
retries=$((retries - 1))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Enable DNS
|
||||
if [ ! -f /etc/resolv.conf.configured ]; then
|
||||
cat > /etc/resolv.conf <<'DNSEOF'
|
||||
nameserver 8.8.8.8
|
||||
nameserver 8.8.4.4
|
||||
nameserver 1.1.1.1
|
||||
DNSEOF
|
||||
touch /etc/resolv.conf.configured
|
||||
fi
|
||||
|
||||
# Test internet connectivity
|
||||
echo "Testing internet connectivity..."
|
||||
if ping -c 2 8.8.8.8 >/dev/null 2>&1; then
|
||||
echo "✓ Internet connection established"
|
||||
else
|
||||
echo "⚠ Warning: No internet connection detected"
|
||||
fi
|
||||
|
||||
# Enable Archipelago service
|
||||
rc-update add archipelago default 2>/dev/null || true
|
||||
|
||||
# Display access information
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "🏝️ Archipelago Bitcoin Node OS"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "Network Configuration:"
|
||||
ip -4 addr show | grep inet | grep -v 127.0.0.1 | awk '{print " IP Address: " $2}'
|
||||
echo ""
|
||||
echo "Access the Archipelago UI at:"
|
||||
ip -4 addr show | grep inet | grep -v 127.0.0.1 | awk '{print " http://" $2}' | sed 's|/.*|:8100|'
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/bin/sh
|
||||
# First boot installation script for Archipelago
|
||||
# This script runs on first boot to complete Archipelago setup
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Archipelago first boot setup..."
|
||||
|
||||
# Install backend APK if available
|
||||
if [ -f /tmp/archipelago-backend.apk ]; then
|
||||
echo "📦 Installing Archipelago backend..."
|
||||
apk add --allow-untrusted /tmp/archipelago-backend.apk || true
|
||||
rm -f /tmp/archipelago-backend.apk
|
||||
fi
|
||||
|
||||
# Create archipelago user if needed
|
||||
if ! id archipelago >/dev/null 2>&1; then
|
||||
echo "👤 Creating archipelago user..."
|
||||
adduser -D -s /bin/bash archipelago || true
|
||||
echo "archipelago ALL=(ALL) NOPASSWD: /usr/bin/podman" >> /etc/sudoers || true
|
||||
fi
|
||||
|
||||
# Setup Podman for archipelago user
|
||||
echo "🐳 Configuring Podman..."
|
||||
mkdir -p /home/archipelago/.config/containers
|
||||
chown -R archipelago:archipelago /home/archipelago || true
|
||||
|
||||
# Create data directories
|
||||
echo "📁 Creating data directories..."
|
||||
mkdir -p /var/lib/archipelago/{apps,secrets,logs,backups}
|
||||
chown -R archipelago:archipelago /var/lib/archipelago || true
|
||||
|
||||
# Enable services
|
||||
echo "⚙️ Enabling services..."
|
||||
rc-update add archipelago default 2>/dev/null || true
|
||||
systemctl enable archipelago 2>/dev/null || true
|
||||
|
||||
# Start services
|
||||
echo "🚀 Starting services..."
|
||||
rc-service archipelago start 2>/dev/null || systemctl start archipelago 2>/dev/null || true
|
||||
|
||||
echo "✅ Archipelago setup complete!"
|
||||
echo " Web UI: http://$(hostname -I | awk '{print $1}'):8100"
|
||||
echo " API: http://$(hostname -I | awk '{print $1}'):5959"
|
||||
@@ -0,0 +1,29 @@
|
||||
[Unit]
|
||||
Description=Archipelago Bitcoin Node OS Backend
|
||||
After=network.target podman.service
|
||||
Wants=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=archipelago
|
||||
Group=archipelago
|
||||
WorkingDirectory=/var/lib/archipelago
|
||||
ExecStart=/usr/bin/archipelago
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
# Security
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/var/lib/archipelago /tmp
|
||||
|
||||
# Environment
|
||||
Environment="RUST_LOG=info"
|
||||
Environment="ARCHIPELAGO_DATA_DIR=/var/lib/archipelago"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/bin/sh
|
||||
# Hardware detection and optimization script
|
||||
# Auto-generated for specific hardware target
|
||||
|
||||
detect_hardware() {
|
||||
echo "=== Hardware Detection ==="
|
||||
|
||||
# CPU info
|
||||
if [ -f /proc/cpuinfo ]; then
|
||||
echo "CPU: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d':' -f2 | xargs)"
|
||||
echo "Cores: $(grep -c processor /proc/cpuinfo)"
|
||||
fi
|
||||
|
||||
# Memory
|
||||
if [ -f /proc/meminfo ]; then
|
||||
echo "Memory: $(grep MemTotal /proc/meminfo | awk '{printf "%.1f GB", $2/1024/1024}')"
|
||||
fi
|
||||
|
||||
# Storage
|
||||
if command -v lsblk >/dev/null 2>&1; then
|
||||
echo "Storage:"
|
||||
lsblk -d -o NAME,SIZE,TYPE | grep disk
|
||||
fi
|
||||
|
||||
# Network
|
||||
if command -v ip >/dev/null 2>&1; then
|
||||
echo "Network interfaces:"
|
||||
ip -br link show | grep -v lo
|
||||
fi
|
||||
|
||||
# PCI devices (for hardware identification)
|
||||
if command -v lspci >/dev/null 2>&1; then
|
||||
echo "PCI devices:"
|
||||
lspci | grep -E "VGA|Ethernet|Network"
|
||||
fi
|
||||
}
|
||||
|
||||
optimize_for_hardware() {
|
||||
echo "=== Hardware Optimization ==="
|
||||
|
||||
# Load Intel microcode if Intel CPU
|
||||
if grep -q Intel /proc/cpuinfo; then
|
||||
echo "Intel CPU detected, loading microcode..."
|
||||
modprobe intel_rapl_common 2>/dev/null || true
|
||||
modprobe intel_powerclamp 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Enable hardware acceleration for graphics
|
||||
if lspci | grep -q "Intel.*Graphics"; then
|
||||
echo "Intel Graphics detected"
|
||||
modprobe i915 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optimize for NVMe if present
|
||||
if [ -e /dev/nvme0n1 ]; then
|
||||
echo "NVMe SSD detected, optimizing..."
|
||||
echo none > /sys/block/nvme0n1/queue/scheduler 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optimize for SATA SSD if present
|
||||
if [ -e /dev/sda ]; then
|
||||
if hdparm -I /dev/sda 2>/dev/null | grep -q "Solid State"; then
|
||||
echo "SATA SSD detected, optimizing..."
|
||||
echo deadline > /sys/block/sda/queue/scheduler 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Run detection
|
||||
detect_hardware
|
||||
optimize_for_hardware
|
||||
@@ -0,0 +1,26 @@
|
||||
# Hardware profile for Start9 Server Pure
|
||||
# Auto-generated during build
|
||||
|
||||
[hardware]
|
||||
target = "start9-pure"
|
||||
name = "Start9 Server Pure"
|
||||
cpu_vendor = "intel"
|
||||
cpu_model = "i7-10710U"
|
||||
min_ram = "32GB"
|
||||
min_storage = "2TB"
|
||||
architecture = "x86_64"
|
||||
|
||||
[optimizations]
|
||||
enabled = intel-graphics intel-networking nvme-ssd
|
||||
|
||||
[network]
|
||||
interfaces = "1x Gigabit Ethernet"
|
||||
|
||||
[usb]
|
||||
ports = "4x USB 3.0, 2x USB 2.0, 1x USB-C 3.1"
|
||||
|
||||
[build]
|
||||
version = "0.1.0"
|
||||
alpine_version = "3.19"
|
||||
build_date = "2026-01-31T19:35:38Z"
|
||||
build_type = "iso"
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
# First boot hardware detection and optimization
|
||||
|
||||
HARDWARE_INFO="/etc/archipelago/hardware-info.sh"
|
||||
|
||||
if [ -x "$HARDWARE_INFO" ]; then
|
||||
echo "🔍 Detecting hardware..."
|
||||
$HARDWARE_INFO > /var/log/archipelago-hardware.log 2>&1
|
||||
echo "✓ Hardware detection complete"
|
||||
fi
|
||||
|
||||
# Create system info file
|
||||
cat > /etc/archipelago/system-info.txt <<INFO
|
||||
Archipelago OS System Information
|
||||
Generated: $(date)
|
||||
|
||||
$(cat /etc/archipelago/hardware.toml 2>/dev/null)
|
||||
|
||||
Runtime Detection:
|
||||
$(cat /var/log/archipelago-hardware.log 2>/dev/null)
|
||||
INFO
|
||||
@@ -1,8 +1,38 @@
|
||||
# Archipelago Node OS Configuration
|
||||
|
||||
[server]
|
||||
# Server listening configuration
|
||||
host = "0.0.0.0" # Listen on all interfaces
|
||||
port = 8100
|
||||
data_dir = "/var/lib/archipelago"
|
||||
bind_host = "0.0.0.0"
|
||||
bind_port = 5959
|
||||
log_level = "info"
|
||||
dev_mode = false
|
||||
container_runtime = "podman"
|
||||
port_offset = 0
|
||||
bitcoin_simulation = "none"
|
||||
|
||||
[network]
|
||||
# Automatic Ethernet configuration
|
||||
auto_configure = true
|
||||
dhcp = true
|
||||
dns_servers = ["8.8.8.8", "8.8.4.4", "1.1.1.1"]
|
||||
|
||||
[containers]
|
||||
# Container runtime (Podman)
|
||||
runtime = "podman"
|
||||
rootless = true
|
||||
auto_start = true
|
||||
|
||||
[apps]
|
||||
# App directory
|
||||
apps_dir = "/var/lib/archipelago/apps"
|
||||
auto_start_enabled = true
|
||||
|
||||
[security]
|
||||
# Security settings
|
||||
require_auth = false # Disable for first boot, enable after setup
|
||||
secrets_dir = "/var/lib/archipelago/secrets"
|
||||
|
||||
[logging]
|
||||
level = "info"
|
||||
dir = "/var/lib/archipelago/logs"
|
||||
|
||||
[ui]
|
||||
# Web UI settings
|
||||
enabled = true
|
||||
path = "/usr/share/archipelago/web"
|
||||
|
||||
@@ -2,13 +2,51 @@
|
||||
# Archipelago Bitcoin Node OS Backend
|
||||
|
||||
name="Archipelago"
|
||||
command="/usr/bin/archipelago"
|
||||
description="Archipelago Bitcoin Node OS Backend Server"
|
||||
command="/usr/bin/archipelago-backend"
|
||||
command_user="archipelago:archipelago"
|
||||
command_background=true
|
||||
pidfile="/var/run/archipelago.pid"
|
||||
start_stop_daemon_args="--make-pidfile"
|
||||
|
||||
# Working directory and environment
|
||||
directory="/var/lib/archipelago"
|
||||
export RUST_LOG="${RUST_LOG:-info}"
|
||||
export ARCHIPELAGO_DATA_DIR="/var/lib/archipelago"
|
||||
export ARCHIPELAGO_PORT="${ARCHIPELAGO_PORT:-8100}"
|
||||
|
||||
depend() {
|
||||
need net
|
||||
use podman
|
||||
need localmount
|
||||
after firewall
|
||||
use podman docker
|
||||
}
|
||||
|
||||
start_pre() {
|
||||
# Ensure directories exist
|
||||
checkpath --directory --mode 0755 --owner archipelago:archipelago \
|
||||
/var/lib/archipelago \
|
||||
/var/lib/archipelago/apps \
|
||||
/var/lib/archipelago/secrets \
|
||||
/var/lib/archipelago/logs \
|
||||
/var/lib/archipelago/backups
|
||||
|
||||
# Wait for network to be fully ready
|
||||
local retries=30
|
||||
while [ $retries -gt 0 ]; do
|
||||
if ping -c 1 -W 1 8.8.8.8 >/dev/null 2>&1; then
|
||||
einfo "Network is ready"
|
||||
return 0
|
||||
fi
|
||||
retries=$((retries - 1))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
ewarn "Network may not be fully ready"
|
||||
return 0
|
||||
}
|
||||
|
||||
start_post() {
|
||||
einfo "Archipelago backend started"
|
||||
einfo "Access the UI at: http://$(hostname -I | awk '{print $1}'):8100"
|
||||
}
|
||||
|
||||
32
image-recipe/alpine-profile/overlay/etc/local.d/00-boot-services.start
Executable file
32
image-recipe/alpine-profile/overlay/etc/local.d/00-boot-services.start
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
# Alpine Linux boot configuration for Archipelago
|
||||
# This runs early in the boot process
|
||||
|
||||
# Enable essential services
|
||||
rc-update add devfs sysinit 2>/dev/null || true
|
||||
rc-update add dmesg sysinit 2>/dev/null || true
|
||||
rc-update add mdev sysinit 2>/dev/null || true
|
||||
rc-update add hwdrivers sysinit 2>/dev/null || true
|
||||
|
||||
# Enable boot services
|
||||
rc-update add bootmisc boot 2>/dev/null || true
|
||||
rc-update add hostname boot 2>/dev/null || true
|
||||
rc-update add hwclock boot 2>/dev/null || true
|
||||
rc-update add modules boot 2>/dev/null || true
|
||||
rc-update add swap boot 2>/dev/null || true
|
||||
rc-update add sysctl boot 2>/dev/null || true
|
||||
rc-update add syslog boot 2>/dev/null || true
|
||||
rc-update add networking boot 2>/dev/null || true
|
||||
rc-update add urandom boot 2>/dev/null || true
|
||||
|
||||
# Enable default services
|
||||
rc-update add local default 2>/dev/null || true
|
||||
rc-update add sshd default 2>/dev/null || true
|
||||
rc-update add archipelago default 2>/dev/null || true
|
||||
|
||||
# Enable shutdown services
|
||||
rc-update add killprocs shutdown 2>/dev/null || true
|
||||
rc-update add mount-ro shutdown 2>/dev/null || true
|
||||
rc-update add savecache shutdown 2>/dev/null || true
|
||||
|
||||
echo "✓ Archipelago boot services configured"
|
||||
88
image-recipe/alpine-profile/overlay/etc/local.d/01-network-setup.start
Executable file
88
image-recipe/alpine-profile/overlay/etc/local.d/01-network-setup.start
Executable file
@@ -0,0 +1,88 @@
|
||||
#!/bin/sh
|
||||
# First boot network and service setup for Archipelago
|
||||
|
||||
# Configure hostname
|
||||
if [ ! -f /etc/hostname.configured ]; then
|
||||
echo "archipelago-node" > /etc/hostname
|
||||
hostname archipelago-node
|
||||
touch /etc/hostname.configured
|
||||
fi
|
||||
|
||||
# Configure networking - Ethernet with DHCP
|
||||
if [ ! -f /etc/network/interfaces.configured ]; then
|
||||
cat > /etc/network/interfaces <<'NETEOF'
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
# Automatic Ethernet configuration (DHCP)
|
||||
auto eth0
|
||||
iface eth0 inet dhcp
|
||||
hostname archipelago-node
|
||||
|
||||
# Fallback for other ethernet names
|
||||
auto enp0s3
|
||||
iface enp0s3 inet dhcp
|
||||
hostname archipelago-node
|
||||
|
||||
auto enp0s25
|
||||
iface enp0s25 inet dhcp
|
||||
hostname archipelago-node
|
||||
|
||||
auto ens0
|
||||
iface ens0 inet dhcp
|
||||
hostname archipelago-node
|
||||
NETEOF
|
||||
touch /etc/network/interfaces.configured
|
||||
fi
|
||||
|
||||
# Enable and start networking
|
||||
rc-update add networking boot 2>/dev/null || true
|
||||
rc-service networking start 2>/dev/null || true
|
||||
|
||||
# Wait for network to be ready
|
||||
echo "Waiting for network..."
|
||||
retries=30
|
||||
while [ $retries -gt 0 ]; do
|
||||
if ip route | grep -q default; then
|
||||
echo "✓ Network is ready"
|
||||
ip addr show | grep "inet " | grep -v "127.0.0.1"
|
||||
break
|
||||
fi
|
||||
retries=$((retries - 1))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Enable DNS
|
||||
if [ ! -f /etc/resolv.conf.configured ]; then
|
||||
cat > /etc/resolv.conf <<'DNSEOF'
|
||||
nameserver 8.8.8.8
|
||||
nameserver 8.8.4.4
|
||||
nameserver 1.1.1.1
|
||||
DNSEOF
|
||||
touch /etc/resolv.conf.configured
|
||||
fi
|
||||
|
||||
# Test internet connectivity
|
||||
echo "Testing internet connectivity..."
|
||||
if ping -c 2 8.8.8.8 >/dev/null 2>&1; then
|
||||
echo "✓ Internet connection established"
|
||||
else
|
||||
echo "⚠ Warning: No internet connection detected"
|
||||
fi
|
||||
|
||||
# Enable Archipelago service
|
||||
rc-update add archipelago default 2>/dev/null || true
|
||||
|
||||
# Display access information
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "🏝️ Archipelago Bitcoin Node OS"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "Network Configuration:"
|
||||
ip -4 addr show | grep inet | grep -v 127.0.0.1 | awk '{print " IP Address: " $2}'
|
||||
echo ""
|
||||
echo "Access the Archipelago UI at:"
|
||||
ip -4 addr show | grep inet | grep -v 127.0.0.1 | awk '{print " http://" $2}' | sed 's|/.*|:8100|'
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
Reference in New Issue
Block a user