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
Contributor

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
Contributor 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

@hyde-repo hyde-repo added the track_axis-03 Student-facing infrastructure services label May 19, 2026
@hyde-repo hyde-repo self-assigned this May 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tests-wave_03 track_axis-03 Student-facing infrastructure services

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)

2 participants