Remove ecosystem configuration file, add Docker entrypoint script, and update deployment workflow to build and push Docker images. Enhance AdminPage with Docker export functionality and improve post management API to use dynamic posts directory path.

This commit is contained in:
2025-06-20 17:13:52 +02:00
parent 803b9899df
commit fb8f7f43ee
24 changed files with 529 additions and 174 deletions

View File

@@ -1,6 +1,7 @@
import { NextRequest, NextResponse } from 'next/server';
import fs from 'fs/promises';
import path from 'path';
import { getPostsDirectory } from '@/lib/postsDirectory';
export async function POST(request: NextRequest) {
try {
@@ -16,7 +17,7 @@ export async function POST(request: NextRequest) {
// Construct the full path to the item
const basePath = process.cwd();
const postsDir = path.join(basePath, 'posts');
const postsDir = getPostsDirectory();
// Ensure the posts directory exists
try {

View File

@@ -0,0 +1,10 @@
import { existsSync } from 'fs';
import path from 'path';
import { NextResponse } from 'next/server';
export async function GET() {
const rootDir = process.cwd();
const dockerDir = path.join(rootDir, 'docker');
const isDocker = existsSync(dockerDir);
return NextResponse.json({ docker: isDocker });
}

View File

@@ -0,0 +1,69 @@
import tar from 'tar';
import { NextResponse } from 'next/server';
import { statSync, createReadStream, existsSync } from 'fs';
import path from 'path';
export async function GET() {
try {
const rootDir = process.cwd();
const dockerDir = path.join(rootDir, 'docker');
const postsDir = path.join(rootDir, 'posts');
let tarballName: string;
let tarballPath: string;
let tarCwd: string;
let tarItems: string[];
let tarOptions: any = {
gzip: true,
portable: true,
noMtime: true,
};
if (existsSync(dockerDir)) {
// Docker is in use: export the entire root directory (excluding node_modules, .next, etc)
tarballName = 'root-export.tar.gz';
tarballPath = path.join('/tmp', tarballName);
tarCwd = rootDir;
tarItems = ['.'];
tarOptions.file = tarballPath;
tarOptions.cwd = tarCwd;
tarOptions.filter = (filepath: string) => {
// Exclude node_modules, .next, .git, /tmp, and tarball itself
const excludes = [
'node_modules', '.next', '.git', 'tmp', 'docker.sock', tarballName
];
// Only check top-level folders/files
const rel = filepath.split(path.sep)[0];
return !excludes.includes(rel);
};
} else {
// Not docker: export only the posts directory
tarballName = 'posts-export.tar.gz';
tarballPath = path.join('/tmp', tarballName);
tarCwd = rootDir;
tarItems = ['posts'];
tarOptions.file = tarballPath;
tarOptions.cwd = tarCwd;
}
// Create tarball
await tar.c(
tarOptions,
tarItems
);
// Stream the tarball as a response
const stat = statSync(tarballPath);
const stream = createReadStream(tarballPath);
return new Response(stream as any, {
status: 200,
headers: {
'Content-Type': 'application/gzip',
'Content-Disposition': `attachment; filename="${tarballName}"`,
'Content-Length': stat.size.toString(),
},
});
} catch (error) {
console.error('Error exporting tarball:', error);
return NextResponse.json({ error: 'Error exporting tarball' }, { status: 500 });
}
}

View File

@@ -1,8 +1,9 @@
import { NextResponse } from 'next/server';
import fs from 'fs';
import path from 'path';
import { getPostsDirectory } from '@/lib/postsDirectory';
const postsDirectory = path.join(process.cwd(), 'posts');
const postsDirectory = getPostsDirectory();
function getFolderStats(folderPath: string) {
const fullPath = path.join(postsDirectory, folderPath);

View File

@@ -1,8 +1,9 @@
import { NextResponse } from 'next/server';
import fs from 'fs';
import path from 'path';
import { getPostsDirectory } from '@/lib/postsDirectory';
const postsDirectory = path.join(process.cwd(), 'posts');
const postsDirectory = getPostsDirectory();
export async function POST(request: Request) {
try {

View File

@@ -1,8 +1,9 @@
import { NextResponse } from 'next/server';
import fs from 'fs';
import path from 'path';
import { getPostsDirectory } from '@/lib/postsDirectory';
const postsDirectory = path.join(process.cwd(), 'posts');
const postsDirectory = getPostsDirectory();
export async function POST(request: Request) {
try {

View File

@@ -1,8 +1,9 @@
import { NextRequest, NextResponse } from 'next/server';
import fs from 'fs';
import path from 'path';
import { getPostsDirectory } from '@/lib/postsDirectory';
const postsDirectory = path.join(process.cwd(), 'posts');
const postsDirectory = getPostsDirectory();
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);

View File

@@ -2,8 +2,9 @@ import { NextResponse } from 'next/server';
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { getPostsDirectory } from '@/lib/postsDirectory';
const postsDirectory = path.join(process.cwd(), 'posts');
const postsDirectory = getPostsDirectory();
export async function POST(request: Request) {
try {

View File

@@ -1,8 +1,9 @@
import { NextResponse } from 'next/server';
import fs from 'fs';
import path from 'path';
import { getPostsDirectory } from '@/lib/postsDirectory';
const postsDirectory = path.join(process.cwd(), 'posts');
const postsDirectory = getPostsDirectory();
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);

View File

@@ -2,8 +2,9 @@ import { NextResponse } from 'next/server';
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { getPostsDirectory } from '@/lib/postsDirectory';
const postsDirectory = path.join(process.cwd(), 'posts');
const postsDirectory = getPostsDirectory();
export async function POST(request: Request) {
try {