Files
gw-svelte/scripts/deploy-remote.sh
T

143 lines
3.8 KiB
Bash
Raw Normal View History

2026-05-02 12:39:55 +12:00
#!/usr/bin/env bash
set -Eeuo pipefail
ARCHIVE_PATH=""
DEPLOY_PATH=""
COMPOSE_FILE=""
PROJECT_NAME=""
usage() {
cat <<'EOF'
Usage:
deploy-remote.sh --archive <path> --deploy-path <path> --compose-file <name> --project-name <name>
This script only updates the main Goodwalk compose project at the specified
deployment path. It does not touch unrelated Docker projects or global Docker
state.
EOF
}
fail() {
echo "[deploy-remote] ERROR: $*" >&2
exit 1
}
while [[ $# -gt 0 ]]; do
case "$1" in
--archive)
ARCHIVE_PATH="${2:-}"
shift 2
;;
--deploy-path)
DEPLOY_PATH="${2:-}"
shift 2
;;
--compose-file)
COMPOSE_FILE="${2:-}"
shift 2
;;
--project-name)
PROJECT_NAME="${2:-}"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
fail "Unknown argument: $1"
;;
esac
done
[[ -n "$ARCHIVE_PATH" ]] || fail "--archive is required"
[[ -n "$DEPLOY_PATH" ]] || fail "--deploy-path is required"
[[ -n "$COMPOSE_FILE" ]] || fail "--compose-file is required"
[[ -n "$PROJECT_NAME" ]] || fail "--project-name is required"
[[ "$DEPLOY_PATH" != "/" ]] || fail "Refusing to deploy to /"
[[ -f "$ARCHIVE_PATH" ]] || fail "Archive not found: $ARCHIVE_PATH"
if docker compose version >/dev/null 2>&1; then
COMPOSE_CMD=(docker compose)
elif command -v docker-compose >/dev/null 2>&1; then
COMPOSE_CMD=(docker-compose)
else
fail "Docker Compose is not installed on the server"
fi
STAGING_DIR="$(mktemp -d "${TMPDIR:-/tmp}/goodwalk-deploy.XXXXXX")"
cleanup() {
rm -rf "$STAGING_DIR"
}
trap cleanup EXIT
echo "[deploy-remote] Deploying main Goodwalk stack"
echo "[deploy-remote] Target deployment path: $DEPLOY_PATH"
echo "[deploy-remote] Compose file: $COMPOSE_FILE"
echo "[deploy-remote] Docker project: $PROJECT_NAME"
echo "[deploy-remote] Staging archive in: $STAGING_DIR"
mkdir -p "$DEPLOY_PATH"
tar -xzf "$ARCHIVE_PATH" -C "$STAGING_DIR"
[[ -f "$STAGING_DIR/$COMPOSE_FILE" ]] || fail "Compose file missing from uploaded archive: $COMPOSE_FILE"
if [[ -f "$DEPLOY_PATH/.env" ]]; then
echo "[deploy-remote] Preserving existing $DEPLOY_PATH/.env"
fi
echo "[deploy-remote] Copying application files into $DEPLOY_PATH"
if command -v rsync >/dev/null 2>&1; then
rsync -a \
--exclude '.env' \
--exclude '.env.*' \
"$STAGING_DIR"/ "$DEPLOY_PATH"/
else
while IFS= read -r -d '' item; do
relative_path="${item#"$STAGING_DIR"/}"
if [[ "$relative_path" == ".env" || "$relative_path" == .env.* ]]; then
continue
fi
destination="$DEPLOY_PATH/$relative_path"
if [[ -d "$item" ]]; then
mkdir -p "$destination"
continue
fi
mkdir -p "$(dirname "$destination")"
cp -f "$item" "$destination"
done < <(find "$STAGING_DIR" -mindepth 1 -print0)
fi
[[ -f "$DEPLOY_PATH/$COMPOSE_FILE" ]] || fail "Compose file missing after copy: $DEPLOY_PATH/$COMPOSE_FILE"
if [[ ! -f "$DEPLOY_PATH/.env" ]]; then
if [[ -f "$DEPLOY_PATH/deploy.env.template" ]]; then
echo "[deploy-remote] No remote .env found. Creating $DEPLOY_PATH/.env from deploy.env.template"
cp "$DEPLOY_PATH/deploy.env.template" "$DEPLOY_PATH/.env"
else
fail "Remote .env is missing and deploy.env.template was not uploaded"
fi
fi
cd "$DEPLOY_PATH"
echo "[deploy-remote] Validating compose configuration"
"${COMPOSE_CMD[@]}" -p "$PROJECT_NAME" -f "$COMPOSE_FILE" config >/dev/null
echo "[deploy-remote] Stopping only the Goodwalk project containers"
"${COMPOSE_CMD[@]}" -p "$PROJECT_NAME" -f "$COMPOSE_FILE" stop || true
echo "[deploy-remote] Rebuilding and starting only the Goodwalk project containers"
"${COMPOSE_CMD[@]}" -p "$PROJECT_NAME" -f "$COMPOSE_FILE" up -d --build --remove-orphans
echo "[deploy-remote] Current Goodwalk container status"
"${COMPOSE_CMD[@]}" -p "$PROJECT_NAME" -f "$COMPOSE_FILE" ps
echo "[deploy-remote] Remote deployment finished"