Add n8n
This commit is contained in:
214
n8n
Normal file
214
n8n
Normal file
@@ -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 <<ENV
|
||||
N8N_HOST=${N8N_HOST_DEFAULT}
|
||||
N8N_PROTOCOL=${N8N_PROTOCOL_DEFAULT}
|
||||
WEBHOOK_URL=${WEBHOOK_URL_DEFAULT}
|
||||
TZ=${TIMEZONE}
|
||||
ENV
|
||||
|
||||
(cd /opt/n8n && docker compose up -d)
|
||||
docker ps | tee -a "$LOG"
|
||||
}
|
||||
|
||||
# Optional: ensure SSH host keys are regenerated on first boot (after we delete them)
|
||||
configure_ssh_regen() {
|
||||
log "Ensuring SSH host keys will be generated on first boot..."
|
||||
# Ubuntu normally generates keys if missing, but we make it explicit.
|
||||
cat >/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 "$@"
|
||||
Reference in New Issue
Block a user