lumeland / cms

A framework-agnostic CMS for Deno
https://lume.land/cms/
MIT License
54 stars 5 forks source link

Run the CMS in Deno Deploy #3

Closed revgum closed 6 months ago

revgum commented 6 months ago

@oscarotero Have you run the CMS in Deno Deploy?

Its unclear to me if CMS Lume adapter would have any way around trying to use Lume to build the site locally. https://github.com/lumeland/cms/blob/main/adapters/lume.ts

The error I'm getting is:

PermissionDenied: Requires write access to '/src/_site/index.html', but the file system on Deno Deploy is read-only.
    at Object.remove (ext:deno_fs/30_fs.js:260:9)
    at https://deno.land/std@0.217.0/fs/empty_dir.ts:26:21
    at Array.map (<anonymous>)
    at emptyDir (https://deno.land/std@0.217.0/fs/empty_dir.ts:23:29)
    at async FSWriter.clear (https://deno.land/x/lume@v2.1.0/core/writer.ts:161:5)
    at async Site.clear (https://deno.land/x/lume@v2.1.0/core/site.ts:473:5)
    at async Site.build (https://deno.land/x/lume@v2.1.0/core/site.ts:483:7)
    at async lume (https://cdn.jsdelivr.net/gh/lumeland/cms@v0.2.9/adapters/lume.ts:27:3)
    at async runCms (https://deno.land/x/lume@v2.1.0/cli/cms.ts:29:15)
    at async file:///src/main.ts:5:1

Ideally, I'd like to run the CMS in Deno Deploy with it configured to use GitHub as the backend. I'm going to use GitHub actions to build the static Lume site and deploy it to a CDN.

I'm thinking about a static adapter only serves the CMS.

oscarotero commented 6 months ago

Lume adapter doesn't work on Deno Deploy because Deno Deploy doesn't have write permissions, so the website cannot be generated.

If you want to host the CMS in a server, I have this script to configure a VPS: https://github.com/lumeland/cms-deploy

We are working also on a Dockerfile (https://github.com/lumeland/cms-deploy/pull/1) but configuring the git part is the challenge.

revgum commented 6 months ago

With my PR, and the example server in the description, I have Lume CMS running on Deno Deploy (configured to use Github with environment variables). https://sad-tiger-94.deno.dev/admin

oscarotero commented 6 months ago

Great, but not sure if this is required. You have an example here: https://github.com/lumeland/cms-demo/blob/main/mod.ts#L48

LumeCMS alone works on Deno Deploy. The Lume adapter is only to run LumeCMS and Lume (the SSG) together to edit content and live-preview the results. And this is what doesn't work on Deno Deploy.

revgum commented 6 months ago

Oh nice! That's exactly what I was looking for, thanks @oscarotero.

revgum commented 6 months ago

In case anyone finds this issue and thread, using the linked solution does not support Lume CMS with Auth configurations, the underlying Hono server doesn't have the associated auth routes included.

oscarotero commented 6 months ago

The example does not have auth configured but you can do it in this way:

const app = cms({
  auth: {
    method: "basic",
    users: {
      user1: "password1",
      user2: "password2",
    },
  },
});

Docs: https://lume.land/cms/configuration/options/#auth

revgum commented 6 months ago

Oh, I mean, if you have auth enabled and configured the server isn't able to process the requests. The errors I get are;

ERROR Error: 2024-03-02T18:16:54.488Z [GET] http://localhost:3000/admin -
    at basicAuth (https://deno.land/x/hono@v4.0.8/middleware/basic-auth/index.ts:62:11)
    at dispatch (https://deno.land/x/hono@v4.0.8/compose.ts:45:23)
    at https://deno.land/x/hono@v4.0.8/compose.ts:18:12
    at https://deno.land/x/hono@v4.0.8/hono-base.ts:356:31
    at Hono.dispatch (https://deno.land/x/hono@v4.0.8/hono-base.ts:367:6)
    at fetch (https://deno.land/x/hono@v4.0.8/hono-base.ts:375:17)
    at ext:deno_http/00_serve.js:455:24
    at ext:deno_http/00_serve.js:689:29
    at eventLoopTick (ext:core/01_core.js:153:7)

I'm looking at how to wire this up properly with the basic Deno.serve API.

revgum commented 6 months ago

I suppose we might have to use Hono with the basic auth middleware in place of Deno.serve to support the CMS configured with basic auth.

oscarotero commented 6 months ago

Hmm, it seems a bug. It's using already Hono auth middleware https://github.com/lumeland/cms/blob/main/core/routes/auth.ts

Let me take a look

revgum commented 6 months ago

This works;

import cms from "./_cms.ts";
import { localIp } from "lume/core/utils/net.ts";
import { log } from "lume/core/utils/log.ts";
import { Hono } from "hono/mod.ts";
import { basicAuth } from "hono/middleware.ts";

const port = 3000;
const basePath = "/admin";

const server = new Hono({
  strict: false,
});

if (cms.options.auth?.method === "basic") {
  const users = Object.entries(cms.options.auth.users).map(
    ([user, pass]) => ({
      username: user,
      password: pass,
    }),
  );

  server.use(
    "*",
    basicAuth({
      ...users.shift()!,
    }, ...users),
  );
}

server.route("*", cms.init());

Deno.serve({
  port,
  handler: server.fetch,
  onListen() {
    const ipAddr = localIp();

    log.info("  CMS server started at:");
    log.info(`  <green>http://localhost:${port}${basePath}</green> (local)`);

    if (ipAddr) {
      log.info(
        `  <green>http://${ipAddr}:${port}${basePath}</green> (network)`,
      );
    }
  },
});
oscarotero commented 6 months ago

Okay, I found the bug. Seems that the onError callback of Hono is intercepting the unauthorized access.

I think it's fixed now. Can you upgrade to v0.3.3 and confirm?

revgum commented 6 months ago

Lemme give that a try!

revgum commented 6 months ago

Works! Thanks for the very quick response and bugfix!