Ctrl K
ComunidadGuías…

NASdeploy.sh

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env bash
set -euo pipefail

# BoardRipper NAS Deploy Script
# Builds Docker image locally for linux/amd64, transfers to NAS via scp,
# then SSHes in to load the image and restart the container.

# ── Configuration ──────────────────────────────────────────────
IMAGE_NAME="boardripper"
IMAGE_TAG="latest"
NAS_HOST="rd-nas"
NAS_USER="inwerp"
NAS_SSH_PORT=22
NAS_DATA_DIR="/volume1/docker/boardripper/data"
NAS_LIBRARY_DIR="/volume1/AL ZEUG/LogiCloud/Schematics-BV-EFI"
NAS_PORT=8090          # External port on NAS
CONTAINER_PORT=8080    # Internal port the Go server listens on
REMOTE="origin"
BRANCH="$(git rev-parse --abbrev-ref HEAD)"

# Read config from deploy.conf. `github_token:` is no longer read — the
# self-update path uses offline-signed manifests (Ed25519) and pulls from
# the public GHCR registry, so end-user installs need no GitHub credential.
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
NAS_PW=""
if [[ -f "${SCRIPT_DIR}/deploy.conf" ]]; then
    NAS_HOST=$(grep '^server:' "${SCRIPT_DIR}/deploy.conf" | awk '{print $2}')
    NAS_USER=$(grep '^ssh user:' "${SCRIPT_DIR}/deploy.conf" | awk '{print $3}')
    NAS_PW=$(grep '^ssh pw:' "${SCRIPT_DIR}/deploy.conf" | awk '{print $3}')
fi
APP_VERSION=$(git describe --tags --always 2>/dev/null || echo "dev")

# Self-update needs the minisign public key baked into the binary so the
# updater can verify signed manifests from ghcr.io / ripperdoc.de. Without
# this the running binary fails every update check with
#   "updater not configured: PubKey is empty (built without -ldflags)"
# Reads the same release.pub as scripts/release.sh.
PUBKEY_FILE="${PUBKEY_FILE:-${HOME}/.config/boardripper/release.pub}"
if [[ -f "${PUBKEY_FILE}" ]]; then
    PUBKEY_B64=$(grep -v '^untrusted' "${PUBKEY_FILE}" | tr -d '\n')
else
    PUBKEY_B64=""
fi
# Extra trusted keys for a rotation overlap window — same file release.sh reads.
EXTRA_PUB_FILE="${EXTRA_PUB_FILE:-${HOME}/.config/boardripper/release.pub.extra}"
if [[ -f "${EXTRA_PUB_FILE}" ]]; then
    PUBKEYS_B64=$(grep -v '^untrusted' "${EXTRA_PUB_FILE}" | grep -v '^[[:space:]]*#' | grep -v '^[[:space:]]*$' | paste -sd, -)
else
    PUBKEYS_B64=""
fi

# ── Colors ─────────────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

info()  { echo -e "${GREEN}[deploy]${NC} $*"; }
warn()  { echo -e "${YELLOW}[deploy]${NC} $*"; }
error() { echo -e "${RED}[deploy]${NC} $*" >&2; }

# SSH/SCP helpers (with optional sshpass)
ssh_cmd() {
    local cmd="ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o PubkeyAuthentication=no -p ${NAS_SSH_PORT}"
    if [[ -n "${NAS_PW}" ]] && command -v sshpass &>/dev/null; then
        cmd="sshpass -p ${NAS_PW} ${cmd}"
    fi
    echo "${cmd}"
}

scp_cmd() {
    local cmd="scp -O -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o PubkeyAuthentication=no -P ${NAS_SSH_PORT}"
    if [[ -n "${NAS_PW}" ]] && command -v sshpass &>/dev/null; then
        cmd="sshpass -p ${NAS_PW} ${cmd}"
    fi
    echo "${cmd}"
}

# ── Pre-deploy validation ──────────────────────────────────────
info "=== Pre-deploy checks ==="

# 1. Verify Docker image builds locally
info "Building image..."
docker build --build-arg APP_VERSION="${APP_VERSION}" --build-arg PUBKEY="${PUBKEY_B64}" --build-arg PUBKEYS="${PUBKEYS_B64}" -t boardripper:deploy-check . || { error "FAIL: Docker build failed"; exit 1; }
if [[ -z "${PUBKEY_B64}" ]]; then
    warn "WARN: PUBKEY empty (${PUBKEY_FILE} missing). Self-update on the NAS will be disabled until you re-deploy with the key."
fi

# 2. Smoke-test the image locally
info "Smoke-testing image..."
docker run -d --name br-deploy-check -p 18080:8080 boardripper:deploy-check
sleep 3
if ! curl -sf http://localhost:18080/ > /dev/null; then
    error "FAIL: Container does not serve HTTP"
    docker logs br-deploy-check
    docker rm -f br-deploy-check
    exit 1
fi
docker rm -f br-deploy-check
info "OK: Image serves HTTP"

# 3. Verify NAS is reachable
info "Checking NAS connectivity..."
if ! $(ssh_cmd) "${NAS_USER}@${NAS_HOST}" "echo ok" 2>/dev/null; then
    error "FAIL: Cannot reach NAS at ${NAS_HOST}"
    exit 1
fi
info "OK: NAS reachable"

# 4. Backup existing data volume
info "Backing up NAS data..."
$(ssh_cmd) "${NAS_USER}@${NAS_HOST}" "cp -r /volume1/docker/boardripper/data /volume1/docker/boardripper/data.bak.$(date +%Y%m%d)" || warn "WARN: backup failed (first deploy?)"

info "=== All pre-deploy checks passed ==="

# ── Step 1: Push to GitHub ─────────────────────────────────────
info "Pushing branch '${BRANCH}' to ${REMOTE}..."
git push "${REMOTE}" "${BRANCH}" || {
    error "Git push failed. Commit your changes first?"
    exit 1
}
info "Push complete."

# ── Step 2: Build Docker image for linux/amd64 ────────────────
TAR_FILE="/tmp/${IMAGE_NAME}.tar.gz"
info "Building Docker image ${IMAGE_NAME}:${IMAGE_TAG} for linux/amd64..."
docker buildx build --platform linux/amd64 --build-arg APP_VERSION="${APP_VERSION}" --build-arg PUBKEY="${PUBKEY_B64}" --build-arg PUBKEYS="${PUBKEYS_B64}" -t "${IMAGE_NAME}:${IMAGE_TAG}" --load . || {
    error "Docker build failed."
    exit 1
}
info "Build complete."

# ── Step 3: Export image to tar.gz ─────────────────────────────
info "Exporting image to ${TAR_FILE}..."
docker save "${IMAGE_NAME}:${IMAGE_TAG}" | gzip > "${TAR_FILE}"
info "Image exported ($(du -h "${TAR_FILE}" | awk '{print $1}'))."

# ── Step 4: Transfer to NAS via scp ───────────────────────────
info "Uploading image to NAS (${NAS_USER}@${NAS_HOST})..."
$(scp_cmd) "${TAR_FILE}" "${NAS_USER}@${NAS_HOST}:/tmp/${IMAGE_NAME}.tar.gz" || {
    error "SCP upload failed."
    exit 1
}
info "Upload complete."

# ── Step 5: Upload deploy script and run on NAS ──────────────
info "Uploading deploy script to NAS..."
$(scp_cmd) "${SCRIPT_DIR}/deploy-remote.sh" "${NAS_USER}@${NAS_HOST}:/tmp/deploy-remote.sh" || {
    error "Failed to upload deploy script."
    exit 1
}

info "Deploying on NAS..."
$(ssh_cmd) "${NAS_USER}@${NAS_HOST}" "bash /tmp/deploy-remote.sh '${NAS_PW}'"

# Clean up local tar
rm -f "${TAR_FILE}"
info "Deployment finished successfully."
info "BoardRipper available at http://${NAS_HOST}:${NAS_PORT}/"