import { SandboxInstance } from "@blaxel/core";
const sandboxName = "my-nextjs-sandbox";
const responseHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS, PATCH",
"Access-Control-Allow-Headers":
"Content-Type, Authorization, X-Requested-With, X-Blaxel-Workspace, X-Blaxel-Preview-Token, X-Blaxel-Authorization",
"Access-Control-Allow-Credentials": "true",
"Access-Control-Expose-Headers": "Content-Length, X-Request-Id",
"Access-Control-Max-Age": "86400",
Vary: "Origin",
};
async function startDevServer(sandbox: SandboxInstance) {
await sandbox.process.exec({
name: "dev-server",
command: "npm run dev -- --port 3000",
workingDir: "/app",
waitForPorts: [3000],
restartOnFailure: true,
maxRestarts: 25,
});
}
async function main() {
try {
// Create or reuse the sandbox
const sandbox = await SandboxInstance.createIfNotExists({
name: sandboxName,
labels: {
framework: "nextjs",
},
image: "nextjs-template:latest",
memory: 4096,
ports: [
{ name: "preview", target: 3000, protocol: "HTTP" },
]
});
// Create preview
const preview = await sandbox.previews.createIfNotExists({
metadata: { name: "preview" },
spec: {
responseHeaders,
public: false,
port: 3000,
},
});
// Generate preview token
const expiresAt = new Date(Date.now() + 1000 * 60 * 60 * 24);
const token = await preview.tokens.create(expiresAt);
// Start dev server if not already running
const processes = await sandbox.process.list();
if (!processes.find((p) => p.name === "dev-server")) {
await startDevServer(sandbox);
}
// Print access URL
const webUrl = `${preview.spec?.url}?bl_preview_token=${token.value}`;
console.log(`Next.js Preview URL: ${webUrl}`);
// Stream logs
const logStream = sandbox.process.streamLogs("dev-server", {
onLog(log) {
console.log(log)
},
});
// Keep running until interrupted
process.on("SIGINT", () => {
logStream.close();
process.exit(0);
});
} catch (error) {
console.error("Error:", error);
process.exit(1);
}
}
main();