Nextcloud Documentation

JavaScript repository by @wekan. Docker Compose & container deployment.

0 stars JavaScript JavaScript 1 file ยท ~2,129 tokens
RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy Nextcloud on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name nextcloud --restart always wekan/nextcloud:latest

File: README.md

WeKan for Nextcloud

This repository packages WeKan as a Nextcloud AppAPI External App (ExApp).
One container runs the authenticated AppAPI gateway, WeKan and the bundled
wekan/FerretDB v1 SQLite database. HaRP carries HTTP and WebSocket/DDP traffic.
No MongoDB container, Docker socket mount, or external database is required.

The implementation has local HTTP/WebSocket and authentication tests. A real
Nextcloud/HaRP installation and a Docker image build still need validation
before an App Store production release.

Requirements

  • Nextcloud 32โ€“35, AppAPI enabled, and a registered HaRP deploy daemon.
  • The Nextcloud reverse proxy must forward /exapps/ to HaRP, including
    WebSocket upgrades. Follow the HaRP installation instructions.
  • A published WeKan Docker version containing server/nextcloud.js and
    /build/nextcloud-exapp-capability.json. Existing images without that marker
    are deliberately rejected. Publish a new WeKan release with this integration
    before building its ExApp; changing metadata alone cannot retrofit old images.
  • Persistent storage and enough RAM for WeKan and FerretDB together. Start
    validation with at least 2 GiB, then size for the actual workload.

Build and install

After publishing the supporting WeKan release, from this repository:

sh
# Replace VERSION with that published WeKan version (without v).
docker buildx build --platform linux/amd64 --load \
  --build-arg WEKAN_VERSION=VERSION \
  -t ghcr.io/wekan/wekan-exapp:vVERSION .

Set appinfo/info.xml's app version to the normalized three-part version and
its image tag to vVERSION. The standalone nextcloud.yml workflow in
wekan/wekan performs these edits, tests this repository, and publishes amd64
and arm64 images. It never runs as part of release-all.yml.

For a pre-store test deployment, publish the image yourself, make the matching
appinfo/info.xml accessible to Nextcloud, then run as Nextcloud's web user:

sh
php occ app_api:app:register wekan YOUR_HARP_DAEMON \
  --info-xml /absolute/path/to/appinfo/info.xml

If the deploy daemon uses an internal NEXTCLOUD_URL for callbacks, configure
WEKAN_PUBLIC_URL as the browser-visible URL, for example
https://cloud.example/exapps/wekan/. Otherwise it is derived from NEXTCLOUD_URL.
Include Nextcloud's subdirectory when it has one. Configure the usual Node
NODE_EXTRA_CA_CERTS environment/mount if the callback server uses a private CA;
never disable TLS verification.

Configure NEXTCLOUD_ADMIN_USERS in the app's deployment environment, for
example ["admin"], using exact Nextcloud user IDs. The default [] gives
nobody WeKan site-administrator rights. Ordinary users can still use boards.
The first visiting user never gains site-administrator privileges automatically.
When changing the list, restart/redeploy the container and reconnect clients.

Enabling the app registers WeKan in Nextcloud's navigation. That menu opens
/exapps/wekan/ (under the Nextcloud subdirectory, if any). It uses Nextcloud's
existing authenticated session; no second WeKan password or OIDC setup is needed.
AppAPI routes require a logged-in Nextcloud user, including public WeKan boards.
Anonymous sharing outside Nextcloud is not enabled by this package.

Authentication

The gateway validates EX-APP-ID, EX-APP-VERSION presence and the shared
AUTHORIZATION-APP-API secret using a constant-time comparison. It strips
incoming identity headers and signs the verified Nextcloud user ID with a fresh,
private key shared only with the child WeKan process. The key is never returned
to the browser. WeKan binds login and resume to these DDP connection headers.
Accounts are identified by the Nextcloud URL and exact user ID, never linked
by matching an existing username or email. Keep NEXTCLOUD_URL stable: changing
it creates a separate identity namespace. Disabled WeKan users stay disabled.
Attachment/avatar requests resolve the same verified identity.

GET /heartbeat is public. POST /init and PUT /enabled require the system
AppAPI identity (empty user ID plus the correct secret). Initialization reports
progress to AppAPI after WeKan is ready. Disabling closes WebSocket connections
and refuses app requests. Enabled state persists across container restarts.

Storage and processes

AppAPI provides APP_PERSISTENT_STORAGE. Keep the volume and its backups private:
it also holds the FRP tunnel configuration and any injected TLS credentials. The launcher uses:

Container path Contents
$APP_PERSISTENT_STORAGE/wekan/files/db FerretDB SQLite
$APP_PERSISTENT_STORAGE/wekan/files/attachments Attachments
$APP_PERSISTENT_STORAGE/wekan/files/avatars Avatars
$APP_PERSISTENT_STORAGE/nextcloud-enabled.json AppAPI enabled state

WRITABLE_PATH is $APP_PERSISTENT_STORAGE/wekan. Back up the entire persistent
volume with the container stopped, and test restoration. Do not remove the
AppAPI volume when upgrading the image. This is a new-install package; it does
not automatically import an existing UCS, MongoDB or standalone WeKan instance.

The launcher initializes directory ownership as root and then drops to the
WeKan UID/GID for all services. WeKan and FerretDB listen only on loopback ports.
HaRP FRP mode uses /tmp/exapp.sock; direct-connect mode uses APP_HOST and
APP_PORT. FRP, WeKan or FerretDB exiting stops the container. SIGTERM shuts down
all children with a bounded grace period. The database is the FerretDB binary
already shipped in the selected WeKan image, so its version stays with that image.

Tests

sh
mkdir -p .tools/tmp
TMPDIR="$PWD/.tools/tmp" node --test tests/*.test.mjs

Before production, test two Nextcloud users, configured admin privileges, denied
anonymous access, WebSocket reconnect, private boards, attachment upload/download,
avatars, disable/re-enable, container restart, upgrade with the same volume and
backup restoration. The WeKan repository also provides
tests/playwright/specs/nextcloud.e2e.js for a real signed-in browser session.

App Store signing keys, app registration, supported-version validation and
production publication remain maintainer tasks. See
the release instructions.
AI, Deck synchronization and file/calendar integrations are separate future work.

Protocol references and licenses

The wrapper is MIT licensed. The image includes WeKan and its dependencies under
their respective licenses; the bundled FRP client is
Apache-2.0 licensed.

Acceptance tests

Run node --test tests/*.test.mjs with TMPDIR pointing to the parent WeKan
checkout's .tools/tmp. Gateway tests cover authenticated HTTP/WebSockets,
readiness, rejected identities and persistent disable state, including an OCS
failure during deregistration. Runtime tests launch real child processes and
parse the FRP configuration independently; metadata guards check USER routes and
the image's capability/privilege boundaries.

The full native Nextcloud 32โ€“35 browser matrix lives in the parent WeKan checkout:
setup, coverage and remaining container checks.
It uses real AppAPI/HaRP, WeKan and FerretDB under .tools, with UI uploads,
private-board isolation, lifecycle operations, source-built upgrades and full
volume restore. Published WeKan v12.32 needs the source transport bridge when
used as the baseline: SockJS's default header allowlist drops the custom signed
identity headers. New ExApp images must wrap a WeKan build containing that fix.

The gateway strips ordinary Authorization credentials as well as AppAPI secrets
before forwarding requests. Disabling is saved before menu deregistration, so an
unavailable Nextcloud endpoint cannot restore the previous enabled state after a
process restart.