From 9aac7b2dc163cbfe224b63ca2a625292316dad86 Mon Sep 17 00:00:00 2001 From: evgeny <5nybrooklyn@gmail.com> Date: Mon, 23 Feb 2026 21:10:15 +0000 Subject: [PATCH] Add n8n --- n8n | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 n8n diff --git a/n8n b/n8n new file mode 100644 index 0000000..f5e3b4c --- /dev/null +++ b/n8n @@ -0,0 +1,214 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ============================================================ +# Golden Image Builder for Ubuntu 24.x (Example: Docker + n8n) +# - Installs prerequisites, Docker, n8n +# - Cleans system for templating (cloud-init, machine-id, SSH keys, logs) +# - Powers off at the end +# ============================================================ + +APP="${APP:-n8n}" +TIMEZONE="${TIMEZONE:-America/New_York}" + +# n8n defaults inside the image (customer-specific values can be overridden later) +N8N_HOST_DEFAULT="${N8N_HOST_DEFAULT:-localhost}" +N8N_PROTOCOL_DEFAULT="${N8N_PROTOCOL_DEFAULT:-http}" +WEBHOOK_URL_DEFAULT="${WEBHOOK_URL_DEFAULT:-http://localhost:5678/}" + +LOG="/root/golden-image-${APP}.log" + +require_root() { + if [[ "${EUID}" -ne 0 ]]; then + echo "ERROR: Run as root. Example: sudo bash $0" + exit 1 + fi +} + +log() { + echo "[$(date -Is)] $*" | tee -a "$LOG" +} + +check_ubuntu() { + if [[ ! -f /etc/os-release ]]; then + log "ERROR: /etc/os-release not found." + exit 1 + fi + . /etc/os-release + if [[ "${ID}" != "ubuntu" ]]; then + log "ERROR: This script is for Ubuntu. Detected: ${ID}" + exit 1 + fi + if [[ "${VERSION_ID}" != 24.* ]]; then + log "WARN: Expected Ubuntu 24.x. Detected: ${VERSION_ID}. Proceeding anyway." + fi + log "OS: ${PRETTY_NAME}" +} + +apt_base() { + log "Updating system and installing base packages..." + export DEBIAN_FRONTEND=noninteractive + apt-get update -y + apt-get upgrade -y + apt-get install -y --no-install-recommends \ + ca-certificates curl gnupg lsb-release \ + cloud-init qemu-guest-agent \ + sudo vim-tiny unzip + systemctl enable --now qemu-guest-agent || true +} + +install_docker() { + log "Installing Docker Engine + Compose plugin (official repo)..." + install -m 0755 -d /etc/apt/keyrings + + if [[ ! -f /etc/apt/keyrings/docker.gpg ]]; then + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg + chmod a+r /etc/apt/keyrings/docker.gpg + fi + + . /etc/os-release + echo \ +"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \ +https://download.docker.com/linux/ubuntu ${VERSION_CODENAME} stable" \ + > /etc/apt/sources.list.d/docker.list + + apt-get update -y + apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + systemctl enable --now docker + docker --version | tee -a "$LOG" + docker compose version | tee -a "$LOG" +} + +setup_timezone() { + log "Setting timezone: ${TIMEZONE}" + timedatectl set-timezone "${TIMEZONE}" || true +} + +install_n8n() { + log "Installing ${APP}..." + mkdir -p /opt/n8n + cat >/opt/n8n/docker-compose.yml <<'YAML' +services: + n8n: + image: n8nio/n8n:latest + restart: always + ports: + - "5678:5678" + environment: + - N8N_HOST=${N8N_HOST} + - N8N_PROTOCOL=${N8N_PROTOCOL} + - N8N_PORT=5678 + - WEBHOOK_URL=${WEBHOOK_URL} + - TZ=${TZ} + volumes: + - n8n_data:/home/node/.n8n +volumes: + n8n_data: +YAML + + cat >/opt/n8n/.env </etc/systemd/system/ssh-hostkey-regen.service <<'UNIT' +[Unit] +Description=Regenerate SSH host keys if missing +After=network.target +Before=ssh.service +ConditionPathExists=!/etc/ssh/ssh_host_rsa_key + +[Service] +Type=oneshot +ExecStart=/usr/bin/ssh-keygen -A + +[Install] +WantedBy=multi-user.target +UNIT + systemctl daemon-reload + systemctl enable ssh-hostkey-regen.service || true +} + +cleanup_for_template() { + log "CLEANUP: preparing VM for templating..." + + log "Stopping services..." + systemctl stop docker || true + systemctl stop ssh || true + + log "Cleaning cloud-init state + logs..." + cloud-init clean --logs || true + rm -f /etc/cloud/cloud.cfg.d/99-installer.cfg 2>/dev/null || true + + log "Resetting machine-id..." + truncate -s 0 /etc/machine-id || true + rm -f /var/lib/dbus/machine-id || true + ln -sf /etc/machine-id /var/lib/dbus/machine-id || true + + log "Removing SSH host keys..." + rm -f /etc/ssh/ssh_host_* || true + + log "Clearing bash history..." + rm -f /root/.bash_history || true + for d in /home/*; do + [[ -d "$d" ]] && rm -f "$d/.bash_history" || true + done + + log "Cleaning apt cache..." + apt-get autoremove -y || true + apt-get clean || true + rm -rf /var/lib/apt/lists/* || true + + log "Vacuuming journald..." + journalctl --rotate || true + journalctl --vacuum-time=1s || true + + log "Removing logs (keeping directories)..." + find /var/log -type f -exec truncate -s 0 {} \; || true + + log "Removing temporary files..." + rm -rf /tmp/* /var/tmp/* || true + + log "Sync..." + sync +} + +poweroff_vm() { + log "DONE. Powering off now (convert VM to template in Proxmox)." + poweroff +} + +main() { + require_root + : > "$LOG" + check_ubuntu + setup_timezone + apt_base + + case "$APP" in + n8n) + install_docker + install_n8n + configure_ssh_regen + ;; + *) + log "ERROR: Unsupported APP='${APP}'. Supported: n8n" + exit 1 + ;; + esac + + cleanup_for_template + poweroff_vm +} + +main "$@" \ No newline at end of file