This commit is contained in:
greg 2025-04-27 21:27:35 +02:00
parent ce85d62402
commit fa34440087
5 changed files with 148 additions and 1 deletions

View File

@ -0,0 +1,33 @@
# Versioning and metadata
.git
.gitignore
.dockerignore
# Build dependencies
node_modules
npm-debug.log
# Environment (contains sensitive data)
.env
.env.*
!.env.example
# Files not required for production
README.md
Dockerfile
docker-compose.yml
*.log
.next
.vscode
.idea
*.md
*.log
*.lock
# Testing
coverage
.nyc_output
test
# Misc
.DS_Store

View File

@ -0,0 +1,55 @@
# Use Node 18 Alpine as the base image for smaller size
FROM node:18-alpine AS base
# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
# Copy package.json and package-lock.json
COPY package.json package-lock.json* ./
RUN npm ci
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Set environment variables
ENV NEXT_TELEMETRY_DISABLED 1
# Build the application
RUN npm run build
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Copy necessary files from the builder stage
COPY --from=builder /app/public ./public
# Set the correct permissions
RUN mkdir .next
RUN chown nextjs:nodejs .next
# Automatically leverage output traces to reduce image size
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
ENV HOSTNAME "0.0.0.0"
# Start the application
CMD ["node", "server.js"]

View File

@ -1,7 +1,22 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
/* config options here */
output: 'standalone',
images: {
domains: [
'm.media-amazon.com',
'i.scdn.co',
'www.moma.org'
],
remotePatterns: [
{
protocol: 'https',
hostname: '**',
},
],
},
// Enable strict mode for better development experience
reactStrictMode: true,
};
export default nextConfig;

View File

@ -0,0 +1,39 @@
const { createServer } = require('http');
const { parse } = require('url');
const next = require('next');
const dev = process.env.NODE_ENV !== 'production';
const hostname = process.env.HOSTNAME || '0.0.0.0';
const port = parseInt(process.env.PORT || '3000', 10);
// Prepare the Next.js app
const app = next({ dev, hostname, port });
const handle = app.getRequestHandler();
app.prepare().then(() => {
console.log(`Next.js App is preparing to start...`);
createServer(async (req, res) => {
try {
// Parse the URL
const parsedUrl = parse(req.url, true);
// Let Next.js handle the request
await handle(req, res, parsedUrl);
} catch (err) {
console.error('Error occurred handling request:', err);
res.statusCode = 500;
res.end('Internal Server Error');
}
})
.once('error', (err) => {
console.error('Server error:', err);
process.exit(1);
})
.listen(port, hostname, () => {
console.log(`> Ready on http://${hostname}:${port}`);
});
}).catch((err) => {
console.error('Next.js app preparation failed:', err);
process.exit(1);
});

View File

@ -0,0 +1,5 @@
import { NextResponse } from 'next/server';
export async function GET() {
return NextResponse.json({ status: 'ok', timestamp: new Date().toISOString() });
}