- vite-plugin-pwa (registerType prompt): manifest with relative start_url/scope/id so one build works on both uat. and prod origins - 192/512 maskable icons generated from favicon.svg - OfflineBanner + /offline route + UpdateToast (prompt-based SW update) - SW: precache hashed assets + icons, navigation fallback to index.html, /api/** NetworkOnly (no stale/leaked data), Google Fonts CacheFirst - nginx: no-cache rules for /sw.js + /manifest.webmanifest (correct MIME) - compose: VITE_APP_VERSION build arg mirrored in uat + prod - CI: PWA artifact assertions in deploy-uat.yml + ci.yml, smoke-test-uat job, static validation guard for nginx rules + vite-plugin-pwa dep
74 lines
2.7 KiB
YAML
74 lines
2.7 KiB
YAML
# SAPL Garment Intelligence — Dokploy Docker Compose
|
|
# Backend (FastAPI) + Frontend (nginx) + persistent volume
|
|
#
|
|
# Deploy in Dokploy:
|
|
# 1. Dokploy → Services → Docker Compose → Create
|
|
# 2. Source: Gitea → sapl/sapl → docker-compose.yml
|
|
# 3. Branch: main
|
|
# 4. Add env vars from backend/.env in Dokploy UI
|
|
# 5. Add domains for frontend (sapl.ai-automation-hub.tech) via Dokploy UI
|
|
# 6. Deploy
|
|
#
|
|
# Data migration (one-time):
|
|
# Copy backend/sapl_garment_intel.db → persistent volume
|
|
# Copy backend/data/ → persistent volume
|
|
|
|
services:
|
|
backend:
|
|
build:
|
|
context: ./backend
|
|
dockerfile: Dockerfile
|
|
env_file: ./.env
|
|
environment:
|
|
DATABASE_URL: "sqlite:////app/data/sapl_garment_intel.db"
|
|
CHROMADB_PATH: "/app/data/chromadb"
|
|
IMAGES_PATH: "/app/data/images"
|
|
CORS_ORIGINS: "https://sapl.ai-automation-hub.tech"
|
|
QR_BASE_URL: "https://sapl.ai-automation-hub.tech"
|
|
# Google Workspace SSO. The client ID is a PUBLIC identifier (exposed to the
|
|
# browser via the "Sign in with Google" button) — safe to commit. The client
|
|
# secret is NOT needed by the ID-token flow, so it stays out of the repo.
|
|
# NOTE: prod origin must be in the OAuth client's Authorized JavaScript origins.
|
|
GOOGLE_CLIENT_ID: "800260541735-6o4rechdhoufgjann9scs57gi8a73fas.apps.googleusercontent.com"
|
|
GOOGLE_ALLOWED_DOMAIN: "saplind.com"
|
|
volumes:
|
|
- sapl_data:/app/data
|
|
expose:
|
|
- "8000"
|
|
restart: unless-stopped
|
|
|
|
frontend:
|
|
build:
|
|
context: ./frontend
|
|
dockerfile: Dockerfile
|
|
args:
|
|
VITE_APP_VERSION: "${VITE_APP_VERSION:-uat-${GIT_SHA:-dev}}"
|
|
depends_on:
|
|
- backend
|
|
restart: unless-stopped
|
|
labels:
|
|
# HTTP → HTTPS redirect
|
|
- traefik.http.routers.sapl-prod-web.rule=Host(`sapl.ai-automation-hub.tech`)
|
|
- traefik.http.routers.sapl-prod-web.entrypoints=web
|
|
- traefik.http.services.sapl-prod-web.loadbalancer.server.port=80
|
|
- traefik.http.routers.sapl-prod-web.service=sapl-prod-web
|
|
- traefik.http.routers.sapl-prod-web.middlewares=redirect-to-https@file
|
|
# HTTPS — custom domain with Let's Encrypt
|
|
- traefik.http.routers.sapl-prod-websecure.rule=Host(`sapl.ai-automation-hub.tech`)
|
|
- traefik.http.routers.sapl-prod-websecure.entrypoints=websecure
|
|
- traefik.http.services.sapl-prod-websecure.loadbalancer.server.port=80
|
|
- traefik.http.routers.sapl-prod-websecure.service=sapl-prod-websecure
|
|
- traefik.http.routers.sapl-prod-websecure.tls.certresolver=letsencrypt
|
|
- traefik.enable=true
|
|
- traefik.docker.network=dokploy-network
|
|
networks:
|
|
- dokploy-network
|
|
- default
|
|
|
|
volumes:
|
|
sapl_data:
|
|
|
|
networks:
|
|
dokploy-network:
|
|
external: true
|