feat(cms): robust api based migration endpoint for prod
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 4s
Build & Deploy / 🧪 QA (push) Failing after 31s
Build & Deploy / 🏗️ Build (push) Failing after 2m1s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 1s

This commit is contained in:
2026-02-27 15:18:10 +01:00
parent 6260b40b91
commit 3d2f240cf6
4 changed files with 34 additions and 7 deletions

View File

@@ -343,8 +343,8 @@ jobs:
ssh root@alpha.mintel.me "cd $SITE_DIR && docker compose -p '${{ needs.prepare.outputs.project_name }}' --env-file '$ENV_FILE' pull"
ssh root@alpha.mintel.me "cd $SITE_DIR && docker compose -p '${{ needs.prepare.outputs.project_name }}' --env-file '$ENV_FILE' up -d --remove-orphans"
# Apply Payload Migrations using the target app container
ssh root@alpha.mintel.me "cd $SITE_DIR && echo '→ Running Payload Migrations...' && docker compose -p '${{ needs.prepare.outputs.project_name }}' --env-file '$ENV_FILE' exec -T mb-grid-app npx payload migrate"
# Apply Payload Migrations using the target app container's programmatic endpoint
ssh root@alpha.mintel.me "cd $SITE_DIR && echo '→ Running Payload Migrations...' && docker compose -p '${{ needs.prepare.outputs.project_name }}' --env-file '$ENV_FILE' exec -T mb-grid-app sh -c 'curl -s -f -X POST -H \"Authorization: Bearer \$$PAYLOAD_SECRET\" http://localhost:3000/api/payload/migrate' || { echo 'Migration failed!'; exit 1; }"
ssh root@alpha.mintel.me "docker system prune -f --filter 'until=24h'"

View File

@@ -0,0 +1,29 @@
import { NextResponse } from "next/server";
import { getPayload } from "payload";
import configPromise from "@payload-config";
import { getServerAppServices } from "@/lib/services/create-services.server";
export async function POST(req: Request) {
const authHeader = req.headers.get("authorization");
if (authHeader !== `Bearer ${process.env.PAYLOAD_SECRET}`) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const { logger } = getServerAppServices();
try {
logger.info("Starting programmatic Payload migrations...");
const payload = await getPayload({ config: configPromise });
await payload.db.migrate({ forceAcceptWarning: true });
logger.info("Successfully executed Payload migrations.");
return NextResponse.json({
success: true,
message: "Migrations executed successfully.",
});
} catch (error: any) {
logger.error("Failed to run migrations remotely", { error });
return NextResponse.json({ error: error.message }, { status: 500 });
}
}

View File

@@ -84,7 +84,7 @@ services:
POSTGRES_USER: ${DIRECTUS_DB_USER:-directus}
POSTGRES_PASSWORD: ${DIRECTUS_DB_PASSWORD:-directus}
volumes:
- directus-db-data:/var/lib/postgresql/data
- mb-grid-db-data:/var/lib/postgresql/data
networks:
default:
@@ -93,6 +93,4 @@ networks:
external: true
volumes:
directus-db-data:
external: true
name: mb-grid-solutions-production_directus-db-data
mb-grid-db-data:

2
next-env.d.ts vendored
View File

@@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts";
import "./.next/dev/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.