Files
Nils-Johan Gynther 7713eb2fa7
Test Suite / backend-pr-quick (push) Has been skipped
Test Suite / quick-import-pr-quick (push) Has been skipped
Test Suite / backend-full (push) Successful in 2m33s
Test Suite / flutter-quality (push) Failing after 1m16s
ci(deploy): standardize docker compose env file usage across scripts
- Added --env-file .env to all docker compose commands for consistent environment variable loading
- Added MISTRAL_API_KEY validation in deploy.sh with fatal error if missing
- Added --force-recreate flag to recipe-api restarts in disable/enable receipt trace scripts
- Added .env file existence check in rebuild_flutter.sh
- Added API service recreation logic in deploy.sh when backend/importer services are updated
2026-05-24 20:30:28 +02:00

243 lines
8.9 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# deploy.sh Bygg och starta om recipe-app
# Kör från: /opt/containers/recipe-app/
# Kräver: .env-fil i samma mapp
#
# Användning:
# ./deploy.sh bygg allt (backend + flutter + importer)
# ./deploy.sh --backend bygg bara backend (snabbast, ~2-3 min)
# ./deploy.sh --flutter bygg bara flutter web-app
# ./deploy.sh --importer bygg bara importer-microservice
# ./deploy.sh --seed kör full seed på databasen (opt-in)
# ./deploy.sh --skip-migration hoppa över automatisk startup-migrering i recipe-api
# ./deploy.sh --clean-database kör migration och därefter underhålls-SQL som rensar data men behåller kategorier
# ./deploy.sh --pull-always kontrollera uppdateringar för basimages
# ./deploy.sh --backend --seed kombinera flaggor fritt (git pull körs alltid)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
START_TS="$(date +%s)"
# ── Flaggor ──────────────────────────────────────────────────────────────────
BUILD_BACKEND=false
BUILD_FLUTTER=false
BUILD_IMPORTER=false
RUN_SEED=false
RUN_CLEAN_DATABASE=false
SKIP_MIGRATION=false
PULL_IMAGES=false # --pull=false är standard (snabbt)
BUILD_ALL=true # om inga specifika tjänster anges, bygg allt
# ── Hjälpfunktioner ───────────────────────────────────────────────────────────
info() { echo "[INFO] $*"; }
warn() { echo "[WARN] $*"; }
fatal() { echo "[ERROR] $*"; exit 1; }
require_cmd() {
command -v "$1" >/dev/null 2>&1 || fatal "Kommando saknas: $1"
}
read_env_value() {
local key="$1"
local line
line=$(grep -E "^${key}=" .env | tail -n 1 || true)
line="${line#*=}"
line="${line%\"}"
line="${line#\"}"
line="${line%\'}"
line="${line#\'}"
printf '%s' "$line"
}
wait_for_backend_prisma() {
info "Väntar på att backend är redo för Prisma-kommandon..."
for i in $(seq 1 30); do
if docker exec recipe-api sh -lc "test -f /app/prisma/schema.prisma" >/dev/null 2>&1; then
return 0
fi
info " ...försök $i/30"
sleep 2
done
return 1
}
wait_for_db() {
local root_password="$1"
info "Väntar på att databasen är redo..."
for i in $(seq 1 30); do
if docker exec recipe-db mariadb-admin ping -h 127.0.0.1 -uroot -p"$root_password" --silent 2>/dev/null; then
return 0
fi
info " ...försök $i/30"
sleep 2
done
return 1
}
run_prisma_migrate_deploy() {
local output
info "Kör Prisma-migrationer (deploy)..."
info " ▶ Kör: npx prisma migrate deploy"
if ! output=$(docker exec recipe-api sh -lc "cd /app && npx prisma migrate deploy --schema prisma/schema.prisma" 2>&1); then
echo "$output"
fatal "Prisma migration misslyckades."
fi
echo "$output"
if echo "$output" | grep -qi "No pending migrations"; then
info "Migration-status: inga väntande migrationer."
elif echo "$output" | grep -qi "Applying migration"; then
info "Migration-status: minst en migration applicerades."
else
warn "Migration-status: kunde inte avgöra om nya migrationer applicerades."
fi
info "Migrationer slutförda utan fel."
}
run_prisma_generate() {
info "Uppdaterar Prisma Client..."
docker exec recipe-api sh -lc "cd /app && npx prisma generate --schema prisma/schema.prisma"
}
for arg in "$@"; do
case "$arg" in
--backend) BUILD_BACKEND=true; BUILD_ALL=false ;;
--flutter) BUILD_FLUTTER=true; BUILD_ALL=false ;;
--importer) BUILD_IMPORTER=true; BUILD_ALL=false ;;
--seed) RUN_SEED=true ;;
--skip-migration) SKIP_MIGRATION=true ;;
--clean-database) RUN_CLEAN_DATABASE=true; BUILD_BACKEND=true; BUILD_ALL=false ;;
--pull-always) PULL_IMAGES=true ;;
--help|-h)
sed -n '/^# Användning:/,/^[^#]/p' "$0" | grep '^#' | sed 's/^# \?//'
exit 0
;;
*) fatal "Okänd flagga: $arg (--help för hjälp)" ;;
esac
done
if [ "$BUILD_ALL" = true ]; then
BUILD_BACKEND=true
BUILD_FLUTTER=true
BUILD_IMPORTER=true
fi
# Om databasrensning begärs, stäng av automigrering i containern för att undvika dubbelkörning.
if [ "$RUN_CLEAN_DATABASE" = true ]; then
SKIP_MIGRATION=true
fi
# ── Validering ────────────────────────────────────────────────────────────────
[ -f ".env" ] || fatal ".env saknas. Kör: cp .env.example .env && nano .env"
require_cmd git
require_cmd docker
if [ "$BUILD_BACKEND" = true ] || [ "$RUN_SEED" = true ] || [ "$RUN_CLEAN_DATABASE" = true ]; then
require_cmd grep
fi
export SKIP_MIGRATION
COMPOSE_CMD=(docker compose --env-file .env -f compose.yml -f compose.flutter.yml)
MISTRAL_API_KEY="$(read_env_value MISTRAL_API_KEY)"
[ -n "$MISTRAL_API_KEY" ] || fatal "MISTRAL_API_KEY saknas i .env"
# ── Git pull ──────────────────────────────────────────────────────────────────
info "Hämtar senaste kod (recipe-app)..."
git pull origin main
if [ -d "$SCRIPT_DIR/../microservice-importer/.git" ]; then
info "Hämtar senaste kod (microservice-importer)..."
(cd "$SCRIPT_DIR/../microservice-importer" && git pull origin main)
else
warn "microservice-importer repo hittades inte på förväntad path, hoppar över git pull där."
fi
# ── Bygger valda tjänster ─────────────────────────────────────────────────────
SERVICES=()
[ "$BUILD_BACKEND" = true ] && SERVICES+=(recipe-api)
[ "$BUILD_FLUTTER" = true ] && SERVICES+=(recipe-flutter)
[ "$BUILD_IMPORTER" = true ] && SERVICES+=(importer-api)
if [ "${#SERVICES[@]}" -eq 0 ]; then
info "Bygger: alla tjänster..."
else
info "Bygger: ${SERVICES[*]}"
fi
if [ "$PULL_IMAGES" = true ]; then
info "(kontrollerar uppdateringar för basimages...)"
"${COMPOSE_CMD[@]}" build "${SERVICES[@]}"
else
"${COMPOSE_CMD[@]}" build --pull=false "${SERVICES[@]}"
fi
info "Startar tjänster..."
"${COMPOSE_CMD[@]}" up -d
if [ "$BUILD_BACKEND" = true ] || [ "$BUILD_IMPORTER" = true ]; then
info "Återskapar API-tjänster för att säkra uppdaterade env-variabler..."
"${COMPOSE_CMD[@]}" up -d --force-recreate recipe-api importer-api
fi
# ── Databasrensning (opt-in) ──────────────────────────────────────────────────
if [ "$RUN_CLEAN_DATABASE" = true ]; then
CLEAN_SQL_FILE="backend/prisma/maintenance/clean-database.sql"
wait_for_backend_prisma || fatal "Backend blev inte redo för Prisma-kommandon i tid."
info "Säkerställer uppdaterat databasschema före rensning..."
run_prisma_migrate_deploy
[ -f "$CLEAN_SQL_FILE" ] || fatal "Saknar $CLEAN_SQL_FILE"
MARIADB_ROOT_PASSWORD="$(read_env_value MARIADB_ROOT_PASSWORD)"
MARIADB_DATABASE="$(read_env_value MARIADB_DATABASE)"
[ -n "$MARIADB_ROOT_PASSWORD" ] || fatal "MARIADB_ROOT_PASSWORD saknas i .env"
[ -n "$MARIADB_DATABASE" ] || fatal "MARIADB_DATABASE saknas i .env"
info "Kör databasrensning från $CLEAN_SQL_FILE ..."
docker exec -i recipe-db mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" "$MARIADB_DATABASE" < "$CLEAN_SQL_FILE"
info "Databasrensning klar (kategorier bevarade enligt SQL-filen)."
run_prisma_generate
fi
# Visa Prisma Client-output även vid vanlig deploy när automigrering är aktiv.
if [ "$RUN_CLEAN_DATABASE" = false ] && [ "$SKIP_MIGRATION" = false ] && [ "$BUILD_BACKEND" = true ]; then
wait_for_backend_prisma || fatal "Backend blev inte redo för Prisma-kommandon i tid."
run_prisma_generate
fi
# ── Seed (opt-in) ─────────────────────────────────────────────────────────────
if [ "$RUN_SEED" = true ]; then
MARIADB_ROOT_PASSWORD="$(read_env_value MARIADB_ROOT_PASSWORD)"
MARIADB_DATABASE="$(read_env_value MARIADB_DATABASE)"
[ -n "$MARIADB_ROOT_PASSWORD" ] || fatal "MARIADB_ROOT_PASSWORD saknas i .env"
[ -n "$MARIADB_DATABASE" ] || fatal "MARIADB_DATABASE saknas i .env"
wait_for_db "$MARIADB_ROOT_PASSWORD" || fatal "Databasen blev inte redo i tid."
if [ -f "db/seeds/seed_all.sql" ]; then
docker exec -i recipe-db mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" "$MARIADB_DATABASE" < db/seeds/seed_all.sql
info "Full seed klar."
else
warn "Ingen db/seeds/seed_all.sql hittades — hoppar över seed."
fi
fi
info "Status:"
"${COMPOSE_CMD[@]}" ps
END_TS="$(date +%s)"
DURATION="$((END_TS - START_TS))"
info "Deploy klart på ${DURATION}s."