Files
Tomas Dvorak 4dfdd500b4
CI/CD Pipeline / Test (push) Successful in 20m59s
CI/CD Pipeline / Security Scan (push) Successful in 10m38s
CI/CD Pipeline / Build and Push Images (push) Failing after 13s
fix(frontend): resolve production API URL fallback to localhost
Problem:
The unified Docker image builds the frontend at build time without
VITE_API_URL. Vite inlined import.meta.env.VITE_API_URL as undefined,
so every API call fell back to the hardcoded 'http://localhost:8080'.
This broke Casa deployments where the frontend loaded from the public
 domain but tried to reach the backend at localhost.

Solution:
1. Centralize API URL resolution in lib/api-url.ts via getApiOrigin().
   It checks runtime window.ENV first (injected by docker-entrypoint.sh
   at container startup), then build-time import.meta.env, then dev
   fallback. In production unified deployments it returns '' so API
   calls use same-origin relative URLs (/api/v1/...) that nginx proxies
   to the backend.
2. Replace all 50+ inline import.meta.env.VITE_API_URL || 'localhost'
   usages across 14 source files with getApiOrigin() / getApiV1BaseUrl().
3. Add build args and runtime sed substitution to Dockerfile and
   docker-entrypoint.sh so the same image works for any deployment.
4. Pass VITE_API_URL through docker-compose.yml and CI/CD build-args.

Verified:
- Production bundle contains 0 occurrences of localhost:8080.
- Container health check and /api/v1/auth/check-users both return 200.
- Runtime injection correctly sets VITE_API_URL='' for same-origin
  and VITE_API_URL='https://domain' for external backend.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-22 12:34:39 +02:00

68 lines
2.0 KiB
Docker

# Multi-stage build for unified Trackeep image
# Builds both frontend and backend in one package
# Stage 1: Build Frontend
FROM node:22-alpine AS frontend-builder
WORKDIR /app/frontend
# Accept build arguments for Vite environment variables.
# If unset, the frontend falls back to same-origin relative URLs in production.
ARG VITE_API_URL
ARG VITE_DEMO_MODE=false
ENV VITE_API_URL=${VITE_API_URL}
ENV VITE_DEMO_MODE=${VITE_DEMO_MODE}
COPY frontend/package*.json ./
RUN npm install
COPY frontend/ ./
RUN npm run build
# Stage 2: Build Backend
FROM golang:1.25-alpine AS backend-builder
WORKDIR /app/backend
COPY backend/go.mod backend/go.sum ./
RUN go mod download
COPY backend/ ./
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
# Stage 3: Final unified image
FROM alpine:latest
# Install dependencies including PostgreSQL
RUN apk --no-cache add ca-certificates tzdata nginx postgresql postgresql-contrib
# Create postgres user directories and fix permissions
RUN mkdir -p /var/lib/postgresql/data /run/postgresql /var/log/postgresql && \
chown -R postgres:postgres /var/lib/postgresql /run/postgresql /var/log/postgresql
# Copy backend binary and migrations
COPY --from=backend-builder /app/backend/main /app/main
COPY --from=backend-builder /app/backend/migrations /app/migrations
# Copy frontend build
COPY --from=frontend-builder /app/frontend/dist /usr/share/nginx/html
# Copy branding assets
COPY trackeep.svg /usr/share/nginx/html/
COPY trackeepfavi.png /usr/share/nginx/html/
COPY trackeepfavi_bg.png /usr/share/nginx/html/
# Copy nginx configuration
COPY frontend/nginx.conf /etc/nginx/nginx.conf
# Create directories
RUN mkdir -p /app/uploads /data /var/log/nginx
# Expose single port
EXPOSE 8080
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
# Start script to run PostgreSQL, backend and nginx
COPY docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]