import type { NextConfig } from "next";
const nextConfig: NextConfig = {
// The Docker image runs the self-contained server from .next/standalone (see Dockerfile).
output: process.env.NEXT_OUTPUT === "standalone" ? "standalone" : undefined,
// ssh2 has optional native bindings and must be loaded by Node, not bundled.
serverExternalPackages: ["ssh2"],
// Container clients request /v2/ and /v2/<name>/blobs/uploads/ with a trailing slash and don't
// follow redirects for uploads, so the built-in redirect is replaced by one that skips /v2.
skipTrailingSlashRedirect: true,
// The OAuth consent page must not be framed, or another site could trick a click on "Authorize".
async headers() {
return [
{
source: "/oauth/authorize",
headers: [
{ key: "X-Frame-Options", value: "DENY" },
{ key: "Content-Security-Policy", value: "frame-ancestors 'none'" },
],
},
];
},
async redirects() {
return [{ source: "/:path((?!v2(?:/|$)).+)/", destination: "/:path", permanent: true }];
},
experimental: {
authInterrupts: true,
serverActions: {
// Large enough for file uploads through the web UI.
bodySizeLimit: "25mb",
},
},
};
export default nextConfig;