Skip to content

feat: add Nextcloud Docker deployment with user provisioning (#146)#150

Open
t0kubetsu wants to merge 3 commits into
mainfrom
feature/nextcloud-bootstrap
Open

feat: add Nextcloud Docker deployment with user provisioning (#146)#150
t0kubetsu wants to merge 3 commits into
mainfrom
feature/nextcloud-bootstrap

Conversation

@t0kubetsu
Copy link
Copy Markdown

Summary

Closes #146

  • Two-stage Dockerfile (php:8.3-apache-bookworm builder → nextcloud:latest runtime) with a provisioner sidecar that bootstraps additional users and app passwords on first run via the Nextcloud OCS API.
  • Redis cache service added alongside Postgres for session performance.
  • App passwords written to a named Docker volume (nextcloud-tokens) and retrievable via make tokens.

Changes

  • Dockerfile: two-stage build — builder stage installs yq and jq as static Debian binaries from GitHub releases; runtime stage copies tooling and provisioning scripts into nextcloud:latest.
  • compose.yml: four-service stack (db, redis, nextcloud, provisioner) with health-chain dependencies and commented debug anchor.
  • provisioning/users.yml: declarative admins[] / users[] manifest (username, email, password, display_name).
  • provisioning/init.sh: idempotent POSIX sh bootstrap — waits for /status.php health, creates users via OCS v1 API, promotes admins to the admin group, generates app passwords via OCS v2 API, writes to /tokens/tokens.txt, stamps /tokens/.provisioned.
  • .env.example: all tunable vars with safe placeholder defaults.
  • Makefile: up / down / build / rebuild / reprovision / logs-provisioner / tokens / term targets matching the gitea reference pattern.
  • README.md: prerequisites, quick-start, build & push, user declaration, app password retrieval, WebDAV/API usage examples, env vars table, troubleshooting.
  • .dockerignore: prevents .env and key files from leaking into the build context.

Design Notes

  • Base images: php:8.3-apache-bookworm (builder) matches the official Nextcloud Dockerfile lineage; nextcloud:latest (runtime) is the official PHP/Apache/Debian image — no Ubuntu.
  • NEXTCLOUD_ADMIN_USER / NEXTCLOUD_ADMIN_PASSWORD env vars trigger Nextcloud's built-in auto-setup; no CLI bootstrap needed for the first admin.
  • OCS API provisioning: additional admins/users created via POST /ocs/v1.php/cloud/users; app passwords via POST /ocs/v2.php/core/apppassword authenticated as each provisioned user.
  • jq used for all JSON payload construction to prevent injection through display names or passwords containing special characters.
  • Idempotency: stamp at /tokens/.provisioned — safe to restart; make reprovision removes the volume to force re-run.

Testing

  • make build — provisioner image builds without errors
  • make build-up — full stack starts, Nextcloud health check passes
  • make logs-provisioner — all users created, app passwords generated
  • make tokens — tokens.txt readable, no ERROR entries
  • WebDAV access with a generated app password succeeds
  • make reprovision — removes volume, re-runs provisioner idempotently

Related Issues

t0kubetsu added 2 commits May 11, 2026 15:43
Two-stage Dockerfile (php:8.3-apache-bookworm builder → nextcloud:latest runtime)
with a provisioner sidecar that bootstraps users and app passwords on first run.

- Dockerfile: two-stage build; builder installs yq+jq static binaries, runtime inherits nextcloud
- compose.yml: db (postgres:16-alpine) + redis (redis:7-alpine) + nextcloud + provisioner with health-chain
- provisioning/users.yml: declarative admin/user manifest with display names
- provisioning/init.sh: idempotent bootstrap via OCS API (users, admin group, app passwords)
- .env.example: all tunable vars documented with safe defaults
- Makefile: up/down/build/rebuild/reprovision/tokens/term targets
- README.md: quick-start, user declaration, app password retrieval, WebDAV/API usage, env vars, troubleshooting
- .dockerignore: prevents .env and key files leaking into build context

Security: jq used for JSON construction to prevent injection via crafted display names;
wait loop has 180 s timeout; plaintext passwords marked CHANGE BEFORE DEPLOY.
App passwords written to /tokens/tokens.txt on nextcloud-tokens volume.
- Fix OCS API: use --data-urlencode form encoding (OCS rejects JSON for user creation)
- Fix OCS status: check statuscode in response, fail on unexpected codes
- Fix jq source: use jqlang/jq 1.7.1 (stedolan/jq is archived), pin yq to v4.44.1
- Add sleep before app password generation to avoid user-not-ready race
- Fix make clean: scope to project only
- Add start_period to nextcloud healthcheck
@t0kubetsu
Copy link
Copy Markdown
Author

All critical and high findings from the PR review have been addressed in commit 1a84ce0:

Fix 1 & 2 — OCS user-create: form-encoded + status code check (CRITICAL)

  • create_user() now uses --data-urlencode for all fields (userid, password, email, displayName) — OCS rejects JSON silently
  • Response is captured and ocs.meta.statuscode is checked: 100 = created, 102 = already exists (skip), anything else = fail with exit 1

Fix 1b — add_to_admin_group: form-encoded (CRITICAL)

  • Replaced -H "Content-Type: application/x-www-form-urlencoded" -d "userid=..." with --data-urlencode "userid=${username}" for correct URL encoding

Fix 3 — jq source and version pinning (HIGH)

  • Replaced archived stedolan/jq with canonical jqlang/jq at pinned version 1.7.1
  • Pinned yq to v4.44.1 (was using releases/latest which is unpinned)

Fix 4 — Sleep before app password generation (MEDIUM)

  • Moved all generate_app_password calls into a dedicated pass after all users are created
  • Added sleep 2 + log line before that pass to avoid user-not-ready race

Fix 5 — make tokens: use alpine (pattern fix)

  • Replaced multi-line busybox form with alpine cat /tokens/tokens.txt against the named volume

Fix 7 — make clean: scoped to project (MEDIUM)

  • Replaced docker system prune -a --volumes -f (system-wide) with docker compose down -v --rmi all

Fix 6 — start_period on nextcloud healthcheck (MEDIUM)

  • Already present in compose.yml (start_period: 60s) — no change needed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Deploy a standalone Nextcloud instance (Dockerized, with users & app passwords provisioned)

1 participant