feat(storage): add local storage framework
This commit is contained in:
parent
228da8f814
commit
964b545bc5
24 changed files with 890 additions and 98 deletions
33
scripts/backup.sh
Executable file
33
scripts/backup.sh
Executable file
|
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
BACKUP_DIR="${BACKUP_DIR:-./backups}"
|
||||
STORAGE_HOST_PATH="${STORAGE_HOST_PATH:-./storage}"
|
||||
TIMESTAMP="$(date +%Y%m%d-%H%M%S)"
|
||||
TARGET_DIR="${BACKUP_DIR}/${TIMESTAMP}"
|
||||
|
||||
mkdir -p "${TARGET_DIR}"
|
||||
|
||||
echo "==> Creating backup in ${TARGET_DIR}"
|
||||
|
||||
if [[ -n "${POSTGRES_CONTAINER:-}" ]]; then
|
||||
echo "==> Creating PostgreSQL dump from container ${POSTGRES_CONTAINER}"
|
||||
docker exec "${POSTGRES_CONTAINER}" pg_dump -U "${POSTGRES_USER:-olympus}" "${POSTGRES_DB:-olympus}" > "${TARGET_DIR}/postgres.sql"
|
||||
elif command -v pg_dump >/dev/null 2>&1 && [[ -n "${DATABASE_URL:-}" ]]; then
|
||||
echo "==> Creating PostgreSQL dump from DATABASE_URL"
|
||||
pg_dump "${DATABASE_URL}" > "${TARGET_DIR}/postgres.sql"
|
||||
else
|
||||
echo "WARN: PostgreSQL dump skipped. Set POSTGRES_CONTAINER or install pg_dump with DATABASE_URL."
|
||||
fi
|
||||
|
||||
if [[ -d "${STORAGE_HOST_PATH}" ]]; then
|
||||
echo "==> Archiving storage directory"
|
||||
tar -czf "${TARGET_DIR}/storage.tar.gz" -C "${STORAGE_HOST_PATH}" .
|
||||
else
|
||||
echo "WARN: Storage directory ${STORAGE_HOST_PATH} not found; storage backup skipped."
|
||||
fi
|
||||
|
||||
echo "INFO: .env is not copied automatically. Store production secrets separately and securely."
|
||||
echo "==> Backup completed"
|
||||
18
scripts/deploy.sh
Executable file
18
scripts/deploy.sh
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
echo "==> Building Docker images"
|
||||
docker compose build
|
||||
|
||||
echo "==> Starting services"
|
||||
docker compose up -d
|
||||
|
||||
echo "==> Running migrations"
|
||||
scripts/migrate.sh
|
||||
|
||||
echo "==> Running healthcheck"
|
||||
scripts/healthcheck.sh
|
||||
|
||||
echo "==> Deployment completed"
|
||||
26
scripts/healthcheck.sh
Executable file
26
scripts/healthcheck.sh
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
ATHENA_URL="${ATHENA_URL:-http://localhost:3001}"
|
||||
|
||||
request_url() {
|
||||
local url="$1"
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -fsS "$url" >/dev/null
|
||||
else
|
||||
python3 -c "import urllib.request; urllib.request.urlopen('${url}', timeout=10).read()"
|
||||
fi
|
||||
}
|
||||
|
||||
echo "==> Checking docker compose services"
|
||||
docker compose ps
|
||||
|
||||
echo "==> Checking Hermes health endpoint inside Docker network"
|
||||
docker compose exec -T hermes python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/health', timeout=10).read()"
|
||||
|
||||
echo "==> Checking Athena at ${ATHENA_URL}"
|
||||
request_url "${ATHENA_URL}"
|
||||
|
||||
echo "==> Healthcheck completed"
|
||||
15
scripts/migrate.sh
Executable file
15
scripts/migrate.sh
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
echo "==> Running database migrations"
|
||||
|
||||
if docker compose ps --services --filter "status=running" | grep -qx "hermes"; then
|
||||
docker compose exec -T hermes uv run alembic upgrade head
|
||||
else
|
||||
cd backend/hermes
|
||||
uv run alembic upgrade head
|
||||
fi
|
||||
|
||||
echo "==> Migrations completed"
|
||||
46
scripts/restore.sh
Executable file
46
scripts/restore.sh
Executable file
|
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
BACKUP_SOURCE="${1:-}"
|
||||
STORAGE_HOST_PATH="${STORAGE_HOST_PATH:-./storage}"
|
||||
|
||||
if [[ -z "${BACKUP_SOURCE}" || ! -d "${BACKUP_SOURCE}" ]]; then
|
||||
echo "Usage: scripts/restore.sh <backup-directory>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "This restore can overwrite database and storage state."
|
||||
echo "Backup source: ${BACKUP_SOURCE}"
|
||||
echo "Storage target: ${STORAGE_HOST_PATH}"
|
||||
read -r -p "Type RESTORE to continue: " confirmation
|
||||
|
||||
if [[ "${confirmation}" != "RESTORE" ]]; then
|
||||
echo "Restore cancelled"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -f "${BACKUP_SOURCE}/postgres.sql" ]]; then
|
||||
if [[ -n "${POSTGRES_CONTAINER:-}" ]]; then
|
||||
echo "==> Restoring PostgreSQL dump into container ${POSTGRES_CONTAINER}"
|
||||
docker exec -i "${POSTGRES_CONTAINER}" psql -U "${POSTGRES_USER:-olympus}" "${POSTGRES_DB:-olympus}" < "${BACKUP_SOURCE}/postgres.sql"
|
||||
elif command -v psql >/dev/null 2>&1 && [[ -n "${DATABASE_URL:-}" ]]; then
|
||||
echo "==> Restoring PostgreSQL dump from DATABASE_URL"
|
||||
psql "${DATABASE_URL}" < "${BACKUP_SOURCE}/postgres.sql"
|
||||
else
|
||||
echo "WARN: PostgreSQL restore skipped. Set POSTGRES_CONTAINER or install psql with DATABASE_URL."
|
||||
fi
|
||||
else
|
||||
echo "WARN: postgres.sql not found; database restore skipped."
|
||||
fi
|
||||
|
||||
if [[ -f "${BACKUP_SOURCE}/storage.tar.gz" ]]; then
|
||||
mkdir -p "${STORAGE_HOST_PATH}"
|
||||
echo "==> Restoring storage archive"
|
||||
tar -xzf "${BACKUP_SOURCE}/storage.tar.gz" -C "${STORAGE_HOST_PATH}"
|
||||
else
|
||||
echo "WARN: storage.tar.gz not found; storage restore skipped."
|
||||
fi
|
||||
|
||||
echo "==> Restore completed"
|
||||
Loading…
Add table
Add a link
Reference in a new issue