diff --git a/Dockerfile b/Dockerfile index 3ee1f75..900d4d2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,4 @@ -# Stage 1: Install dependencies -FROM node:20-alpine AS deps -WORKDIR /app - -# Copy package files -COPY package.json package-lock.json ./ - -# Install dependencies -RUN npm ci --only=production && \ - npm cache clean --force - -# Stage 2: Build the application +# Stage 1: Build the application FROM node:20-alpine AS builder WORKDIR /app @@ -19,45 +8,40 @@ ENV NEXT_TELEMETRY_DISABLED=1 # Copy package files COPY package.json package-lock.json ./ -# Install all dependencies (including devDependencies) +# Install dependencies RUN npm ci # Copy source code COPY . . -# Build Next.js application +# Build Next.js application (static export to /app/out) RUN npm run build -# Stage 3: Production runtime -FROM node:20-alpine AS runner -WORKDIR /app +# Stage 2: Serve static files with nginx +FROM nginx:alpine AS runner -# Set environment to production -ENV NODE_ENV=production -# Disable Next.js telemetry -ENV NEXT_TELEMETRY_DISABLED=1 +# Copy custom nginx config for SPA routing +RUN echo 'server { \ + listen 80; \ + listen [::]:80; \ + root /usr/share/nginx/html; \ + index index.html; \ + location / { \ + try_files $uri $uri/ $uri.html /index.html; \ + } \ + location /_next/static/ { \ + expires 1y; \ + add_header Cache-Control "public, immutable"; \ + } \ + gzip on; \ + gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript; \ +}' > /etc/nginx/conf.d/default.conf -# Create non-root user for security -RUN addgroup --system --gid 1001 nodejs && \ - adduser --system --uid 1001 nextjs - -# Copy necessary files from builder -COPY --from=builder /app/public ./public -COPY --from=builder /app/.next/standalone ./ -COPY --from=builder /app/.next/static ./.next/static - -# Set correct permissions -RUN chown -R nextjs:nodejs /app - -# Switch to non-root user -USER nextjs +# Copy static files from builder +COPY --from=builder /app/out /usr/share/nginx/html # Expose port -EXPOSE 3000 +EXPOSE 80 -# Set environment variable for port -ENV PORT=3000 -ENV HOSTNAME="0.0.0.0" - -# Start the application -CMD ["node", "server.js"] +# Start nginx +CMD ["nginx", "-g", "daemon off;"] diff --git a/docker-compose.yml b/docker-compose.yml index cdbf10d..c17aa53 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,15 +8,11 @@ services: image: ghcr.io/retrozenith/tuxmate:latest container_name: tuxmate ports: - - "3000:3000" - environment: - - NODE_ENV=production - - PORT=3000 - - NEXT_TELEMETRY_DISABLED=1 + - "3000:80" restart: unless-stopped healthcheck: - test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000"] + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:80"] interval: 30s timeout: 10s retries: 3 - start_period: 40s + start_period: 10s diff --git a/next.config.ts b/next.config.ts index 611e4c2..afcbe7e 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,8 +1,7 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - // Use 'export' for static hosting (CF Pages), 'standalone' for Docker/self-hosting - output: process.env.STATIC_EXPORT === 'true' ? 'export' : 'standalone', + output: 'export', images: { unoptimized: true, }, diff --git a/package.json b/package.json index 4bd1e86..55936b9 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,6 @@ "scripts": { "dev": "next dev", "build": "next build", - "build:static": "STATIC_EXPORT=true next build", - "pages:build": "STATIC_EXPORT=true npm run build", "start": "next start", "lint": "eslint", "test": "vitest run",