Ctrl K
ComunidadGuías…

scripts/install.sh

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

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env bash
#
# LinkBreeze — One-line installer
#
# Usage:
#   curl -fsSL https://linkbreeze.omnirise.dev/install.sh | bash
#
# Or clone and run locally:
#   bash scripts/install.sh
#
# What it does:
#   1. Detects Docker or Podman (prefers Docker)
#   2. Pulls the latest LinkBreeze image from GHCR
#   3. Runs the container with sensible defaults
#   4. Optionally creates a systemd service for auto-start on boot
#

set -euo pipefail

# ── Colors ──────────────────────────────────────────────────────────────────
if [[ -t 1 ]]; then
    BOLD='\033[1m'
    GREEN='\033[0;32m'
    YELLOW='\033[0;33m'
    BLUE='\033[0;34m'
    RED='\033[0;31m'
    NC='\033[0m'
else
    BOLD=''; GREEN=''; YELLOW=''; BLUE=''; RED=''; NC=''
fi

info()    { echo -e "${BLUE}ℹ${NC}  $*"; }
success() { echo -e "${GREEN}✓${NC}  $*"; }
warn()    { echo -e "${YELLOW}⚠${NC}  $*"; }
error()   { echo -e "${RED}✗${NC}  $*" >&2; }

# ── Config ───────────────────────────────────────────────────────────────────
IMAGE="docker.io/omnirise/linkbreeze:latest"
CONTAINER_NAME="linkbreeze"
PORT="${LINKBREEZE_PORT:-3000}"
DATA_VOLUME="linkbreeze-data"

# ── Banner ───────────────────────────────────────────────────────────────────
cat << 'EOF'

 ▐▀▀▀▀█        ▀▀▀▀▀▀▀▀▀▄          █▀▀▀▀█▐▀▀▀▀█     █▀▀▀▀█▐▀▀▀▀▀▀▀▀▀█▄▄    ▐▀▀▀▀▀▀▀▀▀█▄▄   ▐▀▀▀▀▀▀▀▀▀▀▀▀█▐▀▀▀▀▀▀▀▀▀▀▀▀█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▐▀▀▀▀▀▀▀▀▀▀▀▀█
 ▐ ████        ▀▀▀▀▀▀▀▀▄ ▀▄        ██████▐ ████     █ ████▐█████████████▄  ▐ ████████████▄ ▐ ████████████▐ ████████████▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▐ ████████████
 ▐ ████        ▀▀▀▀▀▀▀▀ ▀▄ ▀▄      ██████▐ ████     █ ████ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀  ▀▀▀▀▀▀▀▀█▀████▌▐ ████▀▀▀▀▀▀▀▀▐ ████▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▐ ████▀▀▀▀▀▀▀▀
 ▐ ████         █▀▀▀▀█ ▀▄ ▀▄ ▀▄    ██████▐ ████▄▄▄▄█▀▄███▌▐▀▀▀▀█   ▀▀▀▀▀▀▀ ▐ █ █ ▄▄▄█ ████▌▐ ████▄▄▄▄▄▄▄▄▐ ████▄▄▄▄▄▄▄▄▀▀▀▀▀▀ ▄█▀▀▀███▀▐ ████▄▄▄▄▄▄▄▄
 ▐ ████         █ ████   ▀▄ ▀▄ ▀▄  █▄████▐ █████▄▄▄▄████▀ ▐█████ ▀▀▀▀▀▀▀▀▀ ▐ █ █ ██▄▄████▀ ▐ ████▄▄▄▄▄▄▄█▐ ████▄▄▄▄▄▄▄█     ▄█▀▄████▀ ▄▐ ████▄▄▄▄▄▄▄█
 ▐ ████         █ ████ ▐█▄ ▀▄ ▀▄ ▀▄ ▀████▐ ████████████ ▄▀▐█████ ▀▀▀▀▀▀▀▀▀ ▐ █ █ ██████▀   ▐ ████████████▐ ████████████   ▄█▀▄████▀ ▄▀ ▐ ████████████
 ▐▄████         █ ████ ▐ ██▄ ▀▄ ▀▄ ▀▄ ▀██▐▄████ ▄ ▀▀████▄ ▐█████ ▀ ▄█▀▀▀▀█▌▐ █ █ ▀█▄▀███▄  ▐▄████        ▐▄████         ▄█▀▄████▀  ▀   ▐▄████        
 ▄▄▄▄▄▄▄▄▄▄▄▄▄▄ █ ████ ▐ ████  ▀▄ ▀▄ ▀▄ ▀▄▄▄▄▄▄  ▀▄  █████▐█████▀▀▀▀▄█████ ▐ █ █ ▄ ▀█ ████▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▐▀▄█████████████▄▄▄▄▄▄▄▄▄▄▄▄▄▄
 ▄▄▄▄▄▄▄▄▄▄▄▄▄▄ █ ████ ▐ ████ ▀▄ ▀▄ ▀▄ ▀▄▄▄▄▄▄▄   █ ▄▄▄▄▄▄▐█████████████▀  ▐ █ █  ▀▄▐█ ████▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▐ ██████████████▄▄▄▄▄▄▄▄▄▄▄▄▄▄
 ▄▄▄▄▄▄▄▄▄▄▄▄▄▄ █▄████ ▐▄████   ▀▄ ▀▄ █ █▄▄▄▄▄▄   █ ▄▄▄▄▄▄▐▄▄████████▀▀ ▄▀ ▐ █ █   █ █▄████▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▐▄██████████████▄▄▄▄▄▄▄▄▄▄▄▄▄▄
 ▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄ ▄▄▄▄▄▄     ▀▄▄ ▄ ▄▄▄▄▄▄▄   █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▀▀   ▄ ▄ ▄   ▀▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄

EOF

# ── Preflight: detect container runtime ──────────────────────────────────────
RUNTIME=""
if command -v docker &>/dev/null; then
    RUNTIME="docker"
    success "Docker detected: $(docker --version)"
elif command -v podman &>/dev/null; then
    RUNTIME="podman"
    success "Podman detected: $(podman --version)"
    warn "Using Podman (rootless mode). If you hit permission issues, try: podman run --userns=keep-id ..."
else
    error "Neither Docker nor Podman was found on this system."
    echo ""
    echo "  Install one of the following:"
    echo "    Docker:  https://docs.docker.com/engine/install/"
    echo "    Podman:  https://podman.io/docs/installation"
    echo ""
    exit 1
fi

# ── Preflight: check if a container with the same name exists ────────────────
if "$RUNTIME" ps -a --format '{{.Names}}' 2>/dev/null | grep -qx "$CONTAINER_NAME"; then
    warn "A container named '$CONTAINER_NAME' already exists."
    echo ""
    read -rp $'\033[0;33m?\033[0m  Stop and remove the existing container? [y/N] ' RECREATE
    RECREATE="${RECREATE:-N}"
    if [[ "${RECREATE,,}" == "y" ]]; then
        info "Stopping and removing existing container..."
        "$RUNTIME" rm -f "$CONTAINER_NAME" >/dev/null
        success "Old container removed."
    else
        info "Keeping existing container. Installation cancelled."
        exit 0
    fi
fi

# ── Pull the image ───────────────────────────────────────────────────────────
info "Pulling $IMAGE..."
"$RUNTIME" pull "$IMAGE"
success "Image pulled."

# ── Run the container ────────────────────────────────────────────────────────
info "Starting LinkBreeze on port $PORT..."

if [[ "$RUNTIME" == "docker" ]]; then
    "$RUNTIME" run -d \
        --name "$CONTAINER_NAME" \
        --restart unless-stopped \
        -p "${PORT}:3000" \
        -v "${DATA_VOLUME}:/app/data" \
        "$IMAGE"
else
    # Podman: create a volume first (podman volume create is explicit)
    "$RUNTIME" volume create "$DATA_VOLUME" >/dev/null 2>&1 || true
    "$RUNTIME" run -d \
        --name "$CONTAINER_NAME" \
        --restart unless-stopped \
        -p "${PORT}:3000" \
        -v "${DATA_VOLUME}:/app/data" \
        "$IMAGE"
fi

success "Container started."

# ── Wait for health ──────────────────────────────────────────────────────────
info "Waiting for LinkBreeze to start..."
MAX_WAIT=30
for i in $(seq 1 "$MAX_WAIT"); do
    if curl -sf "http://localhost:${PORT}/api/health" >/dev/null 2>&1; then
        success "LinkBreeze is healthy!"
        break
    fi
    if [[ "$i" -eq "$MAX_WAIT" ]]; then
        warn "LinkBreeze didn't respond to health check within ${MAX_WAIT}s."
        warn "It may still be starting. Check: $RUNTIME logs -f $CONTAINER_NAME"
    fi
    sleep 1
done

# ── Systemd service prompt ───────────────────────────────────────────────────
echo ""
if [[ "$EUID" -ne 0 ]] && [[ -z "${SUDO_USER:-}" ]]; then
    # Non-root, no sudo — skip systemd prompt
    info "Run as root (or with sudo) to optionally generate a systemd service."
else
    read -rp $'\033[0;33m?\033[0m  Generate a systemd service so LinkBreeze starts on boot? [y/N] ' SYSTEMD_ANS
    SYSTEMD_ANS="${SYSTEMD_ANS:-N}"
    if [[ "${SYSTEMD_ANS,,}" == "y" ]]; then
        info "Creating systemd service..."

        SERVICE_FILE="/etc/systemd/system/linkbreeze.service"

        # Stop the container — systemd will manage it from here
        "$RUNTIME" stop "$CONTAINER_NAME" >/dev/null 2>&1 || true
        "$RUNTIME" rm "$CONTAINER_NAME" >/dev/null 2>&1 || true

        cat > "$SERVICE_FILE" << EOF
[Unit]
Description=LinkBreeze — Self-hosted link-in-bio
Requires=${RUNTIME}.service
After=${RUNTIME}.service

[Service]
Type=simple
ExecStartPre=-/usr/bin/${RUNTIME} rm -f ${CONTAINER_NAME}
ExecStart=/usr/bin/${RUNTIME} run --name ${CONTAINER_NAME} \\
    --restart no \\
    -p ${PORT}:3000 \\
    -v ${DATA_VOLUME}:/app/data \\
    ${IMAGE}
ExecStop=/usr/bin/${RUNTIME} stop ${CONTAINER_NAME}
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

        systemctl daemon-reload
        systemctl enable linkbreeze.service >/dev/null 2>&1
        systemctl start linkbreeze.service

        success "systemd service created and enabled!"
        info "Service file: $SERVICE_FILE"
        info "Commands:"
        echo "    systemctl status linkbreeze"
        echo "    systemctl stop linkbreeze"
        echo "    systemctl restart linkbreeze"
        echo "    journalctl -u linkbreeze -f"
    else
        info "Skipping systemd service. Container will restart via Docker/Podman restart policy."
    fi
fi

# ── Done ─────────────────────────────────────────────────────────────────────
echo ""
echo -e "${GREEN}${BOLD}  ✓ LinkBreeze is live!${NC}"
echo ""
echo -e "  Open:  ${BOLD}http://localhost:${PORT}${NC}"
echo ""
echo -e "  ${BLUE}First time?${NC} The setup wizard will create your admin account."
echo -e "  ${BLUE}Docs:${NC}     https://linkbreeze.omnirise.dev/docs"
echo ""