feat: add thumbnail API and update Docker configuration
- Implemented a new API route for serving thumbnails, allowing dynamic retrieval of image files. - Updated Dockerfile to install FFmpeg for media processing. - Enhanced docker-compose.yml to mount the thumbnails directory for easier access. - Added public/thumbnails to .dockerignore and .gitignore to prevent unnecessary file inclusion. - Created a new media database file for managing media assets.
This commit is contained in:
parent
dfef34576a
commit
9ca11a8c6d
|
|
@ -64,3 +64,5 @@ coverage
|
||||||
# Temporary folders
|
# Temporary folders
|
||||||
tmp
|
tmp
|
||||||
temp
|
temp
|
||||||
|
|
||||||
|
public/thumbnails
|
||||||
|
|
@ -41,4 +41,6 @@ yarn-error.log*
|
||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
|
|
||||||
public/thumbnails
|
public/thumbnails
|
||||||
|
docker/public/thumbnails
|
||||||
|
|
||||||
screenshots
|
screenshots
|
||||||
|
|
@ -44,7 +44,10 @@ WORKDIR /app
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
ENV NEXT_TELEMETRY_DISABLED=1
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
|
||||||
# No additional packages needed for production
|
# Install FFmpeg for media file analysis
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
ffmpeg \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
RUN groupadd --system --gid 1001 nodejs
|
RUN groupadd --system --gid 1001 nodejs
|
||||||
RUN useradd --system --uid 1001 --gid nodejs nextjs
|
RUN useradd --system --uid 1001 --gid nodejs nextjs
|
||||||
|
|
@ -56,7 +59,7 @@ RUN mkdir -p /app/data /app/media
|
||||||
RUN chown -R nextjs:nodejs /app/data /app/media
|
RUN chown -R nextjs:nodejs /app/data /app/media
|
||||||
|
|
||||||
# Copy built application
|
# Copy built application
|
||||||
COPY --from=builder /app/public ./public
|
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
|
||||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
# Copy node_modules to ensure native bindings are available
|
# Copy node_modules to ensure native bindings are available
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -10,6 +10,7 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- ${DB_PATH:-./data}:/app/data
|
- ${DB_PATH:-./data}:/app/data
|
||||||
- ${MEDIA_PATH:-./media}:/app/media
|
- ${MEDIA_PATH:-./media}:/app/media
|
||||||
|
- ${THUMBNAILS_PATH:-./public/thumbnails}:/app/public/thumbnails
|
||||||
- /mnt/data1:/mnt/data1
|
- /mnt/data1:/mnt/data1
|
||||||
command: node server.js
|
command: node server.js
|
||||||
environment:
|
environment:
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,14 @@ import type { NextConfig } from "next";
|
||||||
|
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {
|
||||||
output: 'standalone',
|
output: 'standalone',
|
||||||
|
async rewrites() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
source: '/thumbnails/:filename*',
|
||||||
|
destination: '/api/thumbnails/:filename*',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
export async function GET(
|
||||||
|
request: NextRequest,
|
||||||
|
{ params }: { params: Promise<{ filename: string }> }
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const { filename } = await params;
|
||||||
|
|
||||||
|
// Construct the path to the thumbnail file
|
||||||
|
const thumbnailPath = path.join(process.cwd(), 'public', 'thumbnails', filename);
|
||||||
|
|
||||||
|
// Check if the file exists
|
||||||
|
if (!fs.existsSync(thumbnailPath)) {
|
||||||
|
return NextResponse.json({ error: 'Thumbnail not found' }, { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the file
|
||||||
|
const fileBuffer = fs.readFileSync(thumbnailPath);
|
||||||
|
|
||||||
|
// Return the image with appropriate headers
|
||||||
|
return new NextResponse(fileBuffer, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'image/png',
|
||||||
|
'Cache-Control': 'public, max-age=31536000, immutable',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error serving thumbnail:', error);
|
||||||
|
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue