Ctrl K
ComunidadGuías…

deploy.sh

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

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env bash
# deploy.sh — Deploys this repo to a remote Docker host over SSH.
#
# Reads HOST and SUDO_PASS from .env.deploy (gitignored). Example .env.deploy:
#   HOST=user@1.2.3.4
#   REMOTE_DIR=/home/user/patzer
#   SUDO_PASS=...
#   HOST_PORT=8800
#
# Usage:
#   ./deploy.sh              # tar source → ssh, build & start
#   ./deploy.sh --no-build   # restart without rebuilding the image
#   ./deploy.sh --logs       # tail logs after deploy

set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
env_file="$script_dir/.env.deploy"

if [[ ! -f "$env_file" ]]; then
  echo ".env.deploy not found. Create it with HOST=user@host, REMOTE_DIR=/path, SUDO_PASS=... (optional)" >&2
  exit 1
fi

# Parse .env.deploy without source'ing it (values may contain shell metacharacters)
HOST_TARGET=""
REMOTE_DIR=""
SUDO_PASS=""
HOST_PORT="8800"
while IFS= read -r line || [[ -n "$line" ]]; do
  [[ "$line" =~ ^[[:space:]]*# ]] && continue
  [[ "$line" =~ ^[[:space:]]*$ ]] && continue
  if [[ "$line" =~ ^[[:space:]]*([A-Z_][A-Z0-9_]*)[[:space:]]*=[[:space:]]*(.*)$ ]]; then
    key="${BASH_REMATCH[1]}"
    value="${BASH_REMATCH[2]}"
    # Strip surrounding quotes if present and trailing whitespace
    value="${value%$'\r'}"
    value="${value%\"}"; value="${value#\"}"
    value="${value%\'}"; value="${value#\'}"
    case "$key" in
      HOST) HOST_TARGET="$value" ;;
      REMOTE_DIR) REMOTE_DIR="$value" ;;
      SUDO_PASS) SUDO_PASS="$value" ;;
      HOST_PORT) HOST_PORT="$value" ;;
    esac
  fi
done < "$env_file"

if [[ -z "$HOST_TARGET" || -z "$REMOTE_DIR" ]]; then
  echo "HOST and REMOTE_DIR must be set in .env.deploy" >&2
  exit 1
fi

no_build=0
tail_logs=0
for arg in "$@"; do
  case "$arg" in
    --no-build|-NoBuild) no_build=1 ;;
    --logs|-Logs)        tail_logs=1 ;;
    -h|--help)
      sed -n '2,16p' "$0"; exit 0 ;;
    *) echo "Unknown argument: $arg" >&2; exit 1 ;;
  esac
done

cyan='\033[0;36m'; green='\033[0;32m'; reset='\033[0m'
log()   { printf "${cyan}→ %s${reset}\n" "$*"; }
done_() { printf "${green}%s${reset}\n" "$*"; }

remote_exec() {
  # shellcheck disable=SC2029
  ssh "$HOST_TARGET" "$1"
}

remote_sudo_script() {
  local script="$1"
  local local_script remote_script rc
  local_script="$(mktemp -t patzer-remote-XXXXXX.sh)"
  remote_script="/tmp/patzer-remote-$RANDOM-$$.sh"
  {
    printf '#!/usr/bin/env bash\nset -e\n'
    printf '%s\n' "$script"
  } > "$local_script"
  scp -q "$local_script" "${HOST_TARGET}:${remote_script}"
  if [[ -n "$SUDO_PASS" ]]; then
    # shellcheck disable=SC2029
    ssh "$HOST_TARGET" "chmod +x '$remote_script' && echo '$SUDO_PASS' | sudo -S -p '' bash '$remote_script'; rc=\$?; rm -f '$remote_script'; exit \$rc"
  else
    # shellcheck disable=SC2029
    ssh "$HOST_TARGET" "chmod +x '$remote_script' && sudo bash '$remote_script'; rc=\$?; rm -f '$remote_script'; exit \$rc"
  fi
  rc=$?
  rm -f "$local_script"
  return $rc
}

log "Ensuring remote dir $REMOTE_DIR exists"
remote_exec "mkdir -p '$REMOTE_DIR'"

log "Syncing source to ${HOST_TARGET}:${REMOTE_DIR}"
local_tar="$(mktemp -t patzer-deploy-XXXXXX.tar.gz)"
remote_tar="/tmp/patzer-deploy-$RANDOM-$$.tar.gz"
trap 'rm -f "$local_tar"' EXIT

tar \
  --exclude='node_modules' --exclude='.git' --exclude='dist' \
  --exclude='build'        --exclude='data' --exclude='bin' \
  --exclude='.env'         --exclude='.env.deploy' \
  -czf "$local_tar" -C "$script_dir" .

scp -q "$local_tar" "${HOST_TARGET}:${remote_tar}"
remote_exec "tar -xzf '$remote_tar' -C '$REMOTE_DIR' && rm -f '$remote_tar'"

if [[ $no_build -eq 0 ]]; then
  log "Building image on remote (this can take a few minutes)"
  remote_sudo_script "cd '$REMOTE_DIR'
HOST_PORT=$HOST_PORT docker compose build"
fi

log "Starting container"
remote_sudo_script "cd '$REMOTE_DIR'
HOST_PORT=$HOST_PORT docker compose up -d
sleep 2
docker compose ps"

if [[ $tail_logs -eq 1 ]]; then
  remote_sudo_script "cd '$REMOTE_DIR'
docker compose logs --tail=50"
fi

server_ip="${HOST_TARGET##*@}"
echo
done_ "Deployed. Open http://${server_ip}:${HOST_PORT}"