See Casnode in production: Casbin Forum, with hundreds of real questions about Casbin, Casdoor, OpenAgent and Casvisor. Visit →
C

There's a general importer now, tools/import_topics. It reads an import.json with categories, users and topics (each post with its author, time and files in a media/ folder) and brings them in with their original authors and times, without notifying anyone:

go run ./tools/import_topics <dir>          # shows what it would do
go run ./tools/import_topics -apply <dir>   # does it

Run it in the forum's folder so it uses the forum's database and uploads. Every user and topic carries an externalId, so running it again skips what was already imported.

There's no ready-made converter for Discourse yet: you'd write a small script that turns Discourse's data into that import.json. The format is described at the top of tools/import_topics/main.go.

C

Casnode sends them now. An admin turns them on in Admin → Site Settings → Email: email_enabled, the SMTP server (smtp_host, smtp_port, smtp_security, smtp_username, smtp_password) and the sender address notification_email.

It works like Discourse: a notification is emailed a few minutes after it happens (email_delay_minutes, 5 by default) and only if it's still unread by then. Replies and mentions are emailed when the member hasn't been on the site recently, personal messages always; each member can change that in their preferences.

There's no daily or weekly digest yet.

C

Yes, you can combine these with your words:

Filter Finds
@maria_dev posts by that user
#configuration topics in that category
tags:docker topics with that tag
in:title matches in titles only
in:messages your personal messages
status:open topics that are not closed
order:latest, order:likes, order:views sorting

For example postgres #configuration order:likes.

C

Every topic, category, tag and profile page is rendered on the server, so the full text is in the HTML. On top of that:

  • canonical URLs, Open Graph tags and DiscussionForumPosting structured data on topics
  • /sitemap.xml, and RSS at /latest.rss and /top.rss
  • robots.txt that keeps private pages out
  • ?page= links on lists and long topics that crawlers can follow
  • a topic URL with an old slug redirects to the current one

Set site_url on the Site Settings page, so that canonical URLs and the sitemap use your domain.

C

Yes, all of it is on Admin → Site Settings → Branding:

  • logo and favicon
  • brand, accent and header colors, each with a dark-mode variant
  • fonts
  • header links (Label,URL|Label,URL)
  • the homepage banner: title, text, image and whether it shows the search box
  • custom CSS for anything else

This demo uses the logo, the banner and the header links. Changes on that page apply right away.

C

@lena_h three ways:

  1. On Admin → Users, open the user and turn on admin or moderator.
  2. Put their user names in admins in conf/app.local.conf (comma-separated).
  3. Admins of the Casdoor organization are forum admins automatically.

Moderators handle the review queue and flags and can close, pin, archive and move topics; admins can also change site settings, categories and users.

C

Casnode sends https://<the address in the browser>/callback, so that exact URL has to be in the application's Redirect URLs in Casdoor. http vs https and www vs no www count as different addresses.

Also check casdoorOrganization and casdoorApplication: only users of that organization can sign in.

C

conf/app.local.conf: same format as conf/app.conf, ignored by git, and every item in it overrides app.conf. Pulling a new version never conflicts with it.

Every item can also be set as an environment variable of the same name (clientSecret=...), which is what the Docker example does.

C

Turn on trustProxyHeader = true in conf/app.local.conf, so that Casnode takes the client IP from X-Forwarded-For, and make sure Nginx sets it:

location / {
    proxy_pass http://127.0.0.1:16900;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Only proxy to httpport. The Next.js server on httpport + 1 listens on 127.0.0.1 and gets its requests through the Go backend.

Leave trustProxyHeader off when nothing is in front of Casnode, otherwise anyone could pick their own IP with that header.

C

Put this in conf/app.local.conf:

driverName = postgres
dataSourceName = user=casnode password=secret host=localhost port=5432 sslmode=disable
dbName = casnode

On the first start Casnode creates the database if it's missing, then the tables. For MySQL it's driverName = mysql with dataSourceName = casnode:secret@tcp(localhost:3306)/, and mssql works for SQL Server.

Casnode doesn't move the data of the SQLite file into the new database, so either start fresh or copy it over with your own tools.

C

No Casdoor needed. You need Go 1.25+, Node.js 20+ and Yarn 1:

git clone https://github.com/casnode/casnode
cd casnode
echo "devSignin = true" > conf/app.local.conf
go run .          # backend on http://localhost:16900, SQLite file casnode.db
cd web
yarn install
yarn dev          # frontend on http://localhost:13900 with hot reload

Open http://localhost:13900/login and sign in as admin (or any user name). devSignin only answers requests from the same computer; never turn it on on a server.

The pages are in web/src/app, the components in web/src/components, and the translations in web/src/lib/locales.

C

Docker is the quickest. The repository has a Dockerfile, so build the image and run it:

git clone https://github.com/casnode/casnode
cd casnode
docker build -t casnode .
docker run -d -p 16900:16900 -v casnode-data:/app/data \
  -e casdoorEndpoint=https://door.casdoor.com -e clientId=<client id> -e clientSecret=<client secret> \
  -e casdoorOrganization=<organization> -e casdoorApplication=<application> -e admins=<your user name> \
  casnode

Then open http://your-server:16900. The only other thing you need is a Casdoor application for sign-in: its client ID and secret go in the variables above, and https://<your forum>/callback goes in its redirect URLs.

By default the data is a SQLite file kept, together with the uploads, in the casnode-data volume, which is fine for a trial.