Some checks failed
app-ci-deploy / test-build-deploy (push) Has been cancelled
app-dev built with --mode production was baking the PROD Supabase URL (.env) into the bundle, so browser auth went cross-origin to supa.classroomcopilot.ai and was CORS-blocked (and hit the wrong user store). Mirror the /__ccapi fix: - Dockerfile: nginx /__supabase/ -> dev Supabase .94:8000 (+WS upgrade for realtime) - supabaseClient.ts: resolve a leading-slash VITE_SUPABASE_URL against window.location.origin so supabase-js gets an absolute same-origin URL - docker-compose.dev.yml: bake VITE_SUPABASE_URL=/__supabase (like VITE_API_BASE) Browser now talks only to the app host (Tailscale or LAN), no CORS, dev .94 store. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
111 lines
3.8 KiB
Docker
111 lines
3.8 KiB
Docker
FROM node:20 AS builder
|
|
WORKDIR /app
|
|
COPY package*.json ./
|
|
|
|
# First generate package-lock.json if it doesn't exist, then do clean install
|
|
RUN if [ ! -f package-lock.json ]; then npm install --package-lock-only; fi && npm ci
|
|
|
|
COPY . .
|
|
|
|
# Vite bakes VITE_* values at build time. Pass the public VITE_* values as
|
|
# build args (docker compose --env-file .env.dev) instead of COPYing an env file;
|
|
# service-host worktrees keep .env.dev as a symlink outside the Docker context.
|
|
ARG VITE_API_BASE
|
|
ARG VITE_API_URL
|
|
ARG VITE_APP_NAME
|
|
ARG VITE_APP_HMR_URL
|
|
ARG VITE_DEV
|
|
ARG VITE_FRONTEND_SITE_URL
|
|
ARG VITE_SEARCH_URL
|
|
ARG VITE_SUPABASE_ANON_KEY
|
|
ARG VITE_SUPABASE_URL
|
|
ARG VITE_SUPER_ADMIN_EMAIL
|
|
ARG VITE_TLSYNC_URL
|
|
ARG VITE_WHISPERLIVE_URL
|
|
# Run build with production mode. Keep these as build-step environment values
|
|
# rather than final-image ENV entries; Vite still embeds the public client config
|
|
# into the static bundle, but nginx image metadata does not need them.
|
|
RUN VITE_API_BASE="${VITE_API_BASE}" \
|
|
VITE_API_URL="${VITE_API_URL}" \
|
|
VITE_APP_NAME="${VITE_APP_NAME}" \
|
|
VITE_APP_HMR_URL="${VITE_APP_HMR_URL}" \
|
|
VITE_DEV="${VITE_DEV}" \
|
|
VITE_FRONTEND_SITE_URL="${VITE_FRONTEND_SITE_URL}" \
|
|
VITE_SEARCH_URL="${VITE_SEARCH_URL}" \
|
|
VITE_SUPABASE_ANON_KEY="${VITE_SUPABASE_ANON_KEY}" \
|
|
VITE_SUPABASE_URL="${VITE_SUPABASE_URL}" \
|
|
VITE_SUPER_ADMIN_EMAIL="${VITE_SUPER_ADMIN_EMAIL}" \
|
|
VITE_TLSYNC_URL="${VITE_TLSYNC_URL}" \
|
|
VITE_WHISPERLIVE_URL="${VITE_WHISPERLIVE_URL}" \
|
|
npm run build -- --mode production
|
|
|
|
FROM nginx:alpine
|
|
# Copy built files
|
|
COPY --from=builder /app/dist /usr/share/nginx/html
|
|
|
|
# .mjs files (pdfjs worker) must be served as application/javascript for module workers
|
|
RUN sed -i 's|application/javascript\s*js;|application/javascript js mjs;|' /etc/nginx/mime.types
|
|
|
|
# Create a simple nginx configuration
|
|
RUN echo 'server { \
|
|
listen 3000; \
|
|
root /usr/share/nginx/html; \
|
|
index index.html; \
|
|
location = /index.html { \
|
|
expires -1; \
|
|
add_header Cache-Control "no-store, no-cache, must-revalidate"; \
|
|
} \
|
|
location = /health { \
|
|
proxy_pass http://192.168.0.64:18000/health; \
|
|
proxy_set_header Host $host; \
|
|
proxy_set_header X-Real-IP $remote_addr; \
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; \
|
|
} \
|
|
location /__ccapi/ { \
|
|
proxy_pass http://192.168.0.64:18000/; \
|
|
proxy_set_header Host $host; \
|
|
proxy_set_header X-Real-IP $remote_addr; \
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; \
|
|
} \
|
|
location /__supabase/ { \
|
|
proxy_pass http://192.168.0.94:8000/; \
|
|
proxy_set_header Host $host; \
|
|
proxy_set_header X-Real-IP $remote_addr; \
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; \
|
|
proxy_set_header Upgrade $http_upgrade; \
|
|
proxy_set_header Connection "upgrade"; \
|
|
proxy_http_version 1.1; \
|
|
} \
|
|
location /api/ { \
|
|
proxy_pass http://192.168.0.64:18000/api/; \
|
|
proxy_set_header Host $host; \
|
|
proxy_set_header X-Real-IP $remote_addr; \
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; \
|
|
} \
|
|
location / { \
|
|
try_files $uri $uri/ /index.html; \
|
|
expires 30d; \
|
|
add_header Cache-Control "public, no-transform"; \
|
|
} \
|
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ { \
|
|
expires 30d; \
|
|
add_header Cache-Control "public, no-transform"; \
|
|
} \
|
|
location /searxng-api/ { \
|
|
proxy_pass https://search.kevlarai.com/; \
|
|
proxy_ssl_server_name on; \
|
|
proxy_set_header Host search.kevlarai.com; \
|
|
} \
|
|
location ~ /\. { \
|
|
deny all; \
|
|
} \
|
|
error_page 404 /index.html; \
|
|
}' > /etc/nginx/conf.d/default.conf
|
|
|
|
# Set up permissions
|
|
RUN chown -R nginx:nginx /usr/share/nginx/html \
|
|
&& chown -R nginx:nginx /var/log/nginx
|
|
|
|
# Expose HTTP port (NPM will handle HTTPS)
|
|
EXPOSE 3000
|