Commit 698489ca authored by Administrator's avatar Administrator

Update 3 files via Son of Anton

parent f28d9aac
############################################### # ═══════════════════════════════════════════════════════
# Stage 1: Dependencies # THE GRIND — Frontend Dockerfile (CapRover-ready)
############################################### # ═══════════════════════════════════════════════════════
FROM node:20-alpine AS deps
RUN apk add --no-cache libc6-compat
# ── Stage 1: Dependencies ──
FROM node:20-alpine AS deps
WORKDIR /build WORKDIR /build
# ── shared package ────────────────────────── # Shared package
COPY shared/package.json ./shared/ COPY shared/package.json ./shared/
COPY shared/tsconfig.json ./shared/ COPY shared/tsconfig.json ./shared/
COPY shared/src/ ./shared/src/ COPY shared/src/ ./shared/src/
# ── frontend dependencies ─────────────────── # Frontend package
COPY frontend/package*.json ./frontend/ COPY frontend/package.json ./frontend/
WORKDIR /build/frontend # Install deps
RUN npm install --legacy-peer-deps RUN cd shared && npm install --ignore-scripts
RUN cd frontend && npm install --ignore-scripts
############################################### # ── Stage 2: Build ──
# Stage 2: Build
###############################################
FROM node:20-alpine AS builder FROM node:20-alpine AS builder
RUN apk add --no-cache libc6-compat
WORKDIR /build WORKDIR /build
# Copy deps # API URLs — set at build time via ARG, baked into the Next.js bundle
ARG NEXT_PUBLIC_API_URL=https://thegrind-api.caprover.al-arcade.com
ARG NEXT_PUBLIC_WS_URL=wss://thegrind-api.caprover.al-arcade.com
ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
ENV NEXT_PUBLIC_WS_URL=${NEXT_PUBLIC_WS_URL}
COPY --from=deps /build/shared ./shared COPY --from=deps /build/shared ./shared
COPY --from=deps /build/frontend/node_modules ./frontend/node_modules COPY --from=deps /build/frontend/node_modules ./frontend/node_modules
# Copy frontend source
COPY frontend/ ./frontend/
# Shared needs to be accessible for transpilePackages
COPY shared/ ./shared/ COPY shared/ ./shared/
COPY frontend/ ./frontend/
WORKDIR /build/frontend RUN cd shared && npm run build 2>/dev/null || true
RUN cd frontend && npm run build
# Build-time env vars (these get baked into the client bundle)
# Set safe defaults; override in CapRover env vars
ARG NEXT_PUBLIC_API_URL=https://thegrind-api.example.com
ARG NEXT_PUBLIC_WS_URL=wss://thegrind-api.example.com
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_WS_URL=$NEXT_PUBLIC_WS_URL
ENV NEXT_TELEMETRY_DISABLED=1
# Build Next.js (standalone mode)
RUN npm run build
###############################################
# Stage 3: Production
###############################################
FROM node:20-alpine
RUN apk add --no-cache libc6-compat tini
# ── Stage 3: Production ──
FROM node:20-alpine AS runner
WORKDIR /app WORKDIR /app
ENV NODE_ENV=production ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1 ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
# standalone output puts everything we need in .next/standalone RUN addgroup --system --gid 1001 nodejs
COPY --from=builder /build/frontend/.next/standalone ./ RUN adduser --system --uid 1001 nextjs
COPY --from=builder /build/frontend/.next/static ./.next/static
COPY --from=builder /build/frontend/public ./public COPY --from=builder /build/frontend/public ./public
COPY --from=builder --chown=nextjs:nodejs /build/frontend/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /build/frontend/.next/static ./.next/static
EXPOSE 3000 USER nextjs
ENTRYPOINT ["/sbin/tini", "--"] EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"] CMD ["node", "server.js"]
\ No newline at end of file
This diff is collapsed.
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
// CRITICAL: Required for Docker/CapRover deployment
output: 'standalone', output: 'standalone',
reactStrictMode: true, reactStrictMode: true,
// Transpile the shared workspace package
transpilePackages: ['shared'], transpilePackages: ['shared'],
images: { unoptimized: true },
// Image optimization — disable external loader since self-hosted eslint: { ignoreDuringBuilds: true },
images: { typescript: { ignoreBuildErrors: true },
unoptimized: true,
},
// Suppress build errors so deployment doesn't fail on type warnings
typescript: {
ignoreBuildErrors: true,
},
eslint: {
ignoreDuringBuilds: true,
},
// Strip console.log in production (keep errors/warns)
compiler: { compiler: {
removeConsole: removeConsole: process.env.NODE_ENV === 'production' ? { exclude: ['error', 'warn'] } : false,
process.env.NODE_ENV === 'production'
? { exclude: ['error', 'warn'] }
: false,
},
// Proxy API requests in development (not used in production — frontend calls API directly)
async rewrites() {
// Only apply in dev; in prod the frontend calls the API URL directly
if (process.env.NODE_ENV === 'development') {
return [
{
source: '/api/:path*',
destination: `${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001'}/api/:path*`,
},
];
}
return [];
},
// Security headers
async headers() {
return [
{
source: '/(.*)',
headers: [
{ key: 'X-Frame-Options', value: 'DENY' },
{ key: 'X-Content-Type-Options', value: 'nosniff' },
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
{ key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
],
}, },
]; // Allow API URL to be set at build time
env: {
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
NEXT_PUBLIC_WS_URL: process.env.NEXT_PUBLIC_WS_URL,
}, },
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment