Production deployment setup + feature complete

- Dockerfile + deploy.sh for Hetzner server
- Email verification via Better Auth + Resend
- Invite code flow (6-digit OTP, generate/join)
- Settlement share percent fix (payer vs debtor)
- OCR scanner fixes (date display, retry, viewfinder)
- app.json icon/splash/adaptive-icon configured
- iOS deployment target 15.5 (ML Kit requirement)
- DB migration 0014: household_invitations table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
René Schober
2026-03-20 11:54:22 +01:00
parent 4e34270786
commit 9ddc7c6d7a
194 changed files with 55961 additions and 305 deletions

101
deploy.sh Executable file
View File

@@ -0,0 +1,101 @@
#!/bin/bash
set -e
SSH_HOST="robot@116.203.252.62"
REMOTE_DIR="/home/robot/hausapp"
CONTAINER_NAME="hausapp-server"
NETWORK="robot_gitea-net"
BRANCH="main"
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
success() { echo -e "${GREEN}[OK]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
echo ""
echo -e "${GREEN}======================================${NC}"
echo -e "${GREEN} HausApp → api.app-forge.dev${NC}"
echo -e "${GREEN}======================================${NC}"
echo ""
# 1. SSH check
info "Prüfe SSH Verbindung..."
ssh -q -o BatchMode=yes -o ConnectTimeout=5 "$SSH_HOST" exit || error "SSH nicht erreichbar"
success "SSH OK"
# 2. Push to Gitea
info "Pushe Code nach Gitea..."
git push origin "$BRANCH" || error "Git push fehlgeschlagen"
success "Code gepusht"
# 3. Auf Server deployen
info "Deploye auf Server..."
ssh "$SSH_HOST" << ENDSSH
set -e
# Repo clonen oder updaten
if [ -d "$REMOTE_DIR/.git" ]; then
echo "[git] Pull latest..."
cd $REMOTE_DIR
git pull origin $BRANCH
else
echo "[git] Clone repo..."
git clone ssh://git@git.app-forge.dev:2222/robot/HausApp.git $REMOTE_DIR
cd $REMOTE_DIR
fi
# Docker Image bauen
echo "[docker] Baue Image..."
docker build -t $CONTAINER_NAME .
# Alten Container stoppen
docker stop $CONTAINER_NAME 2>/dev/null || true
docker rm $CONTAINER_NAME 2>/dev/null || true
# Migrationen
echo "[migrate] Führe Migrationen aus..."
docker run --rm \
--network $NETWORK \
--env-file ~/hausapp.env \
$CONTAINER_NAME \
sh -c "cd /app/packages/db && bun run drizzle-kit migrate"
# Container starten
echo "[run] Starte Container..."
docker run -d \
--name $CONTAINER_NAME \
--network $NETWORK \
--env-file ~/hausapp.env \
--restart unless-stopped \
$CONTAINER_NAME
# Caddy neu laden
docker exec gitea-caddy caddy reload --config /etc/caddy/Caddyfile 2>/dev/null || true
echo "[caddy] Neu geladen"
ENDSSH
success "Deployment abgeschlossen"
# 4. Health check
info "Health Check (warte 5s)..."
sleep 5
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://api.app-forge.dev/health 2>/dev/null || echo "000")
if [ "$HTTP_STATUS" = "200" ]; then
success "https://api.app-forge.dev/health → 200 OK"
else
echo -e "${YELLOW}[WARN]${NC} Health Check: HTTP $HTTP_STATUS"
fi
echo ""
echo -e "${GREEN}======================================${NC}"
echo -e "${GREEN} Fertig!${NC}"
echo -e "${GREEN}======================================${NC}"
echo ""
echo " API: https://api.app-forge.dev"
echo " Logs: ssh $SSH_HOST 'docker logs -f $CONTAINER_NAME'"
echo ""