144 lines
5.4 KiB
Bash
Executable File
144 lines
5.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# infra/sentry/install.sh
|
|
#
|
|
# Wrapper around the upstream getsentry/self-hosted installer pinned at
|
|
# 25.12.1 (see UPSTREAM.md). Run this script on the staging Hetzner host
|
|
# from the repository root or from `infra/sentry/`:
|
|
#
|
|
# cd infra/sentry && ./install.sh
|
|
#
|
|
# The script is idempotent — re-running it picks up new overlay changes and
|
|
# re-applies migrations. Volumes under /data/coolify/services/sentry/ are
|
|
# preserved across runs.
|
|
|
|
set -Eeuo pipefail
|
|
shopt -s inherit_errexit 2>/dev/null || true
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Config
|
|
# -----------------------------------------------------------------------------
|
|
UPSTREAM_REPO="https://github.com/getsentry/self-hosted.git"
|
|
UPSTREAM_TAG="25.12.1"
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
UPSTREAM_DIR="${SCRIPT_DIR}/upstream/self-hosted"
|
|
ENV_FILE="${SCRIPT_DIR}/.env"
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Helpers
|
|
# -----------------------------------------------------------------------------
|
|
log() { printf "\033[1;34m[sentry-install]\033[0m %s\n" "$*"; }
|
|
err() { printf "\033[1;31m[sentry-install:ERROR]\033[0m %s\n" "$*" >&2; }
|
|
die() {
|
|
err "$*"
|
|
exit 1
|
|
}
|
|
|
|
require_cmd() {
|
|
command -v "$1" >/dev/null 2>&1 || die "required command not found: $1"
|
|
}
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Preconditions
|
|
# -----------------------------------------------------------------------------
|
|
require_cmd git
|
|
require_cmd docker
|
|
|
|
if ! docker compose version >/dev/null 2>&1; then
|
|
die "docker compose v2 plugin not available (needs Docker Engine >= 24)"
|
|
fi
|
|
|
|
if [[ ! -f "${ENV_FILE}" ]]; then
|
|
die "${ENV_FILE} not found — copy .env.example to .env and fill in secrets first"
|
|
fi
|
|
|
|
# Load env into the current shell so the upstream installer + our overlays see
|
|
# the same values. set -a auto-exports everything sourced.
|
|
set -a
|
|
# shellcheck disable=SC1090
|
|
source "${ENV_FILE}"
|
|
set +a
|
|
|
|
: "${SENTRY_ADMIN_EMAIL:?SENTRY_ADMIN_EMAIL must be set in .env}"
|
|
: "${SENTRY_ADMIN_PASSWORD:?SENTRY_ADMIN_PASSWORD must be set in .env}"
|
|
: "${SENTRY_SECRET_KEY:?SENTRY_SECRET_KEY must be set in .env}"
|
|
: "${SENTRY_BASE_URL:?SENTRY_BASE_URL must be set in .env}"
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Step 1: clone upstream at pinned tag (or update if already cloned)
|
|
# -----------------------------------------------------------------------------
|
|
mkdir -p "${SCRIPT_DIR}/upstream"
|
|
|
|
if [[ ! -d "${UPSTREAM_DIR}/.git" ]]; then
|
|
log "cloning upstream getsentry/self-hosted @ ${UPSTREAM_TAG}"
|
|
git clone \
|
|
--branch "${UPSTREAM_TAG}" \
|
|
--depth 1 \
|
|
--single-branch \
|
|
"${UPSTREAM_REPO}" \
|
|
"${UPSTREAM_DIR}"
|
|
else
|
|
log "upstream clone exists; fetching tag ${UPSTREAM_TAG}"
|
|
git -C "${UPSTREAM_DIR}" fetch --depth 1 origin "refs/tags/${UPSTREAM_TAG}:refs/tags/${UPSTREAM_TAG}"
|
|
git -C "${UPSTREAM_DIR}" checkout --quiet "tags/${UPSTREAM_TAG}"
|
|
fi
|
|
|
|
# Sanity-check the checked-out tag matches.
|
|
ACTUAL_TAG="$(git -C "${UPSTREAM_DIR}" describe --tags --exact-match 2>/dev/null || echo unknown)"
|
|
if [[ "${ACTUAL_TAG}" != "${UPSTREAM_TAG}" ]]; then
|
|
die "upstream checkout is at '${ACTUAL_TAG}', expected '${UPSTREAM_TAG}'"
|
|
fi
|
|
log "upstream pinned at ${ACTUAL_TAG}"
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Step 2: apply our overlay files
|
|
# -----------------------------------------------------------------------------
|
|
log "applying overlays"
|
|
install -m 0644 "${SCRIPT_DIR}/docker-compose.override.yml" "${UPSTREAM_DIR}/docker-compose.override.yml"
|
|
|
|
mkdir -p "${UPSTREAM_DIR}/sentry"
|
|
install -m 0644 "${SCRIPT_DIR}/sentry/sentry.conf.py" "${UPSTREAM_DIR}/sentry/sentry.conf.py"
|
|
|
|
if [[ -f "${SCRIPT_DIR}/relay/config.yml" ]]; then
|
|
mkdir -p "${UPSTREAM_DIR}/relay"
|
|
install -m 0644 "${SCRIPT_DIR}/relay/config.yml" "${UPSTREAM_DIR}/relay/config.yml"
|
|
fi
|
|
|
|
# Also expose the .env to the upstream installer (it expects a sibling `.env`).
|
|
install -m 0600 "${ENV_FILE}" "${UPSTREAM_DIR}/.env"
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Step 3: run upstream installer (non-interactive, no telemetry-pings)
|
|
# -----------------------------------------------------------------------------
|
|
log "running upstream installer (this can take 5-10 minutes on first run)"
|
|
(
|
|
cd "${UPSTREAM_DIR}"
|
|
./install.sh --skip-user-prompt --no-report-self-hosted-issues
|
|
)
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Step 4: seed superuser (idempotent — Sentry no-ops if it already exists)
|
|
# -----------------------------------------------------------------------------
|
|
log "ensuring superuser ${SENTRY_ADMIN_EMAIL} exists"
|
|
(
|
|
cd "${UPSTREAM_DIR}"
|
|
docker compose run --rm web createuser \
|
|
--email "${SENTRY_ADMIN_EMAIL}" \
|
|
--password "${SENTRY_ADMIN_PASSWORD}" \
|
|
--superuser \
|
|
--no-input \
|
|
|| log "createuser returned non-zero — likely user already exists (safe to ignore)"
|
|
)
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Step 5: start the stack
|
|
# -----------------------------------------------------------------------------
|
|
log "starting stack (detached)"
|
|
(
|
|
cd "${UPSTREAM_DIR}"
|
|
docker compose up -d
|
|
)
|
|
|
|
log "done. Web UI: ${SENTRY_BASE_URL}"
|
|
log "next: log in, enable 2FA on the admin account, then create projects 'boilerplate-api', 'boilerplate-worker', 'boilerplate-web' and paste their DSNs into Coolify secrets."
|