Skip to main content

Nextcloud

Deploy Nextcloud hub.

Ansible hosts group: nextcloud​

Variables​

OptionTypeDescriptionDefault
cs_nc_versionstringNextcloud version34.0.4
cs_ns_version_shastringSHA512 checksum of the Nextcloud release archivesha512:...
cs_nc_public_uristringPublic URI for Nextcloudhttps://nextcloud-{{ inventory_hostname }}.<cluster domain>
cs_nc_extra_trusted_domainslistExtra domains to add to Nextcloud's trusted domains[]
cs_nc_cluster_namestringNextcloud cluster name{{ cs_cluster_name }}
cs_nc_container_rootstringRoot directory for Nextcloud/app/nextcloud
cs_nc_web_dirstringWeb directory for Nextcloud{{ cs_nc_container_root }}/www
cs_nc_data_dirstringData directory for Nextcloud{{ cs_nc_container_root }}/data
cs_nc_cert_dirstringCertificate directory{{ cs_nc_container_root }}/certs
cs_nc_docker_networkstringDocker network for Nextcloud containersnextcloud
cs_nc_php_versionstringPHP version to use8.4
cs_nc_run_userstringUser to run Nextcloudwww-data
cs_nc_run_groupstringGroup to run Nextcloudwww-data
cs_nc_logtimezonestringTimezone for logsAsia/Kolkata
cs_nc_default_phone_regionstringDefault phone regionIN
cs_nc_dns_serverslistDNS servers for NextcloudThe cluster's DNS servers (from Vault)
cs_nc_trusted_proxieslistList of trusted proxiesThe cluster CIDR and VPN CIDR (from Vault)
cs_nc_apache_template_namestringApache template name100-nextcloud
cs_nc_cron_system_timer_namestringSystemd timer for cronnextcloud-cron
cs_nc_files_scanner_systemd_timer_namestringSystemd timer for file scanningnextcloud-scanfiles
cs_nc_email_regexstringRegex for email validation(Standard email regex)
cs_nc_external_drive_mount_web_pathsdictExternal drive mounts (see below){}
cs_nc_db_databasestringDatabase namenextcloud-{{ inventory_hostname }}
cs_nc_db_cluster_namestringDatabase cluster name{{ cs_nc_cluster_name }}
cs_nc_db_cluster_nodestringDatabase cluster node{{ inventory_hostname }}
cs_nc_cache_redis_docker_imagestringRedis docker image{{ cs_vm_artifact_registry_containers_home }}/redis
cs_nc_cache_redis_docker_tagstringRedis docker tag8.10.0-trixie
cs_nc_cache_redis_container_namestringRedis container namenextcloud-redis
cs_nc_cache_redis_server_dirstringRedis data directory/app/nextcloud-redis
cs_nc_cache_redis_timeoutfloatRedis timeout0.5
cs_nc_imaginary_docker_imagestringImaginary docker image{{ cs_vm_artifact_registry_containers_home }}/nextcloud-aio-imaginary
cs_nc_imaginary_docker_image_tagstringImaginary docker tag20260929_105435
cs_nc_imaginary_docker_container_namestringImaginary container namenextcloud-aio-imaginary
cs_collabora_docker_imagestringCollabora docker image{{ cs_vm_artifact_registry_containers_home }}/nextcloud-aio-collabora
cs_collabora_docker_image_tagstringCollabora docker tag20260929_105435
cs_collabora_container_namestringCollabora container namenextcloud-aio-collabora
cs_nc_fts_imagestringFull Text Search docker image{{ cs_vm_artifact_registry_containers_home }}/nextcloud-aio-fulltextsearch
cs_nc_fts_image_tagstringFull Text Search docker tag20260929_105435
cs_nc_fts_container_namestringFTS container namenextcloud-fulltextsearch
cs_nc_fts_index_namestringFTS index namenextcloud-fulltextsearch
cs_nc_fts_systemd_workerstringFTS systemd worker namenextcloud-fulltextsearch-worker
cs_nc_fts_run_user_idintFTS run user ID1000
cs_nc_fts_run_group_idintFTS run group ID0
cs_nc_fts_data_dirstringFTS data directory/app/nextcloud-fulltextsearch/data
cs_nc_whiteboard_docker_imagestringWhiteboard docker image{{ cs_vm_artifact_registry_containers_home }}/nextcloud-whiteboard
cs_nc_whiteboard_docker_image_tagstringWhiteboard docker tagv2.0.0
cs_nc_whiteboard_docker_container_namestringWhiteboard container namenextcloud-whiteboard
cs_nc_talk_docker_imagestringTalk HPB docker image{{ cs_vm_artifact_registry_containers_home }}/nextcloud-aio-talk
cs_nc_talk_docker_image_tagstringTalk HPB docker tag20260929_105435
cs_nc_talk_container_namestringTalk HPB container namenextcloud-aio-talk
cs_nc_talk_recording_docker_imagestringTalk recording backend docker image{{ cs_vm_artifact_registry_containers_home }}/nextcloud-aio-talk-recording
cs_nc_talk_recording_docker_image_tagstringTalk recording backend docker tag20260929_105435
cs_nc_talk_recording_container_namestringTalk recording backend container namenextcloud-aio-talk-recording
cs_nc_talk_trusted_ca_dirstringTalk signaling container's trusted CA directory{{ cs_nc_cert_dir }}/talk-trusted-ca
cs_nc_restic_node_namestringRestic backup node name{{ inventory_hostname }}
cs_nc_restic_cluster_namestringRestic cluster name{{ cs_nc_cluster_name }}
cs_nc_restic_repo_namestringRestic repository namenextcloud

cs_nc_external_drive_mount_web_paths​

cs_nc_external_drive_mount_web_paths:
<Nextcloud Mount point name>:
group: <Nextcloud group name>
disk_path: <Path to the disk>
enable_sharing: <true|false> # optional, defaults to true
previews: <true|false> # optional, defaults to true
filesystem_check_changes: <0|1|2> # optional, defaults to 1
encoding_compatibility: <true|false> # optional, defaults to false
readonly: <true|false> # optional, defaults to true
encrypt: <true|false> # optional, defaults to false
local_mnt_nextcloud:
disk_path: /mnt/external-hdd-15/local_mnt_nextcloud
group: local_mnt_nextcloud
readonly: false

Tasks​

Prepare (nextcloud_prepare)​

  • Installs required system packages (ffmpeg, imagemagick, php, apache2, etc.).
  • Configures PHP and Apache settings, including a 16G upload_max_filesize/post_max_size to allow large file uploads.
  • Generates SSL certificates signed by the internal Root CA.
  • Configures Apache virtual host for Nextcloud and enables the required Apache modules and the PHP-FPM configuration.
  • Creates the cs_nc_docker_network Docker network shared by the hub component containers.

Prepare DB (nextcloud_prepare_db)​

  • Provisions the Nextcloud PostgreSQL user and database through the PostgreSQL maintenance connection. See Prepare PostgreSQL Database for the shared process and Vault prerequisite.

Install (nextcloud_install)​

  • Downloads the Nextcloud binary and verifies it against a SHA512 checksum.
  • Issues a client certificate from the internal Root CA and connects to PostgreSQL with sslmode=verify-full, using the user/database created by nextcloud_prepare_db.
  • Performs initial Nextcloud installation via occ maintenance:install.
  • Writes config/server.config.php with the trusted domains, trusted proxies, and email settings.
  • Enables the featured apps (encryption, admin_audit, bruteforcesettings, files_external, suspicious_login, twofactor_totp, user_ldap), turns on server-side encryption with the master key, imports the Root CA into Nextcloud, adds missing database indices, and sets the admin audit log file.
  • Sets up systemd timers for Nextcloud cron and file scanning.

Cache (nextcloud_cache)​

  • Deploys a Redis container for caching and file locking, reachable on 127.0.0.1 over TLS with client certificates and an ACL file. The redis_cache_admin_password and redis_cache_nextcloud_user_password Vault values must contain only ASCII letters and digits.
  • Configures Nextcloud to use Redis through config/redis.config.php.

Mount (nextcloud_mount)​

  • Registers each entry of cs_nc_external_drive_mount_web_paths as a Nextcloud external storage mount (nextcloud_files_external module).

Admin (nextcloud_admin)​

  • Fetches admin credentials from Vault.
  • Enforces two-factor authentication for every group except admin.
  • Recreates the admin user from the Vault credentials (through a temporary admin user), disables every other member of the admin group, and makes sure the admin user is in the admin group.

Hub components​

  • Imaginary (nextcloud_imaginary): Docker-based image processing service.
  • Collabora (nextcloud_collabora): Online office suite integration.
  • Full Text Search (nextcloud_fulltextsearch): ElasticSearch-based search service.
  • Whiteboard (nextcloud_whiteboard): Collaborative whiteboard service. Every run generates a new JWT secret, passes it to the Whiteboard container, and stores the same value in the whiteboard app's jwt_secret_key setting, which the app keeps lazy-loaded and encrypted. The run deletes any existing jwt_secret_key row first and writes the new one with occ config:app:set --type=string --lazy --sensitive --no-interaction. Without --type=string, occ exits 0 without storing the value, because it derives the type of this setting as string plus the sensitive flag and matches none of its type cases. --no-interaction auto-confirms the type prompt that --type=string triggers.
  • Hub Bundle (nextcloud_hub_bundle): Installs the Nextcloud apps of the hub bundle (calendar, contacts, mail, spreed, deck, groupfolders, forms, notes, notify_push, and others) that are not already installed.
  • Talk (nextcloud_talk): High-performance backend (HPB) for Nextcloud Talk video calls, including signaling server, TURN relay, and the call recording backend (registered with SSL validation on, and recording consent required for all calls). The signaling server and recording backend build their config from NC_DOMAIN/HPB_DOMAIN with no separate port variable, so both carry cs_nc_public_uri's host and port together; the TURN relay gets a bare hostname instead (TALK_HOST, TURN_DOMAIN), since Janus's TURN config rejects anything but a plain hostname or IP. The signaling container bind-mounts cs_nc_talk_trusted_ca_dir (a Nextcloud-managed copy of the internal Root CA, separate from the host-wide /usr/local/share/ca-certificates the linux_patching role maintains) read-only onto the container's own /usr/local/share/ca-certificates, so its callback to Nextcloud's HTTPS endpoint trusts that CA instead of failing verification.

Users (nextcloud_users)​

  • Creates every user in the Vault users_dict that does not exist yet (with a generated password), sets its email and display name, and enables TOTP two-factor authentication for it.
  • Creates the groups named in users_dict and adds or removes users so their group membership matches.
  • Disables every Nextcloud user that is neither in users_dict nor the admin user.
  • Fails before changing anything when the admin user is listed in users_dict, an email address does not match cs_nc_email_regex, groups is not a dict, or a user is in the admin group.

Post install (nextcloud_post_install)​

  • Verifies the installed version matches cs_nc_version.
  • Applies the theming (name, slogan, colors, logos, background) and the server info monitoring token.
  • Opens the Apache port in UFW and adds the Nextcloud fail2ban filter and jail.
  • Adds missing database indices and runs occ maintenance:repair --include-expensive.

Backup (nextcloud_restic_backup)​

  • Performs Restic backups of Nextcloud web directory and database: a PostgreSQL dump is written to db_backup.sql inside cs_nc_container_root for the duration of the backup.
  • Backs up only cs_nc_container_root. Few things sit outside it and are left out on purpose: cs_nc_cache_redis_server_dir and the Full Text Search data directory (cs_nc_fts_data_dir) hold only a cache and a search index rebuilt from Nextcloud's real data, so backing them up would just waste space; and any path under cs_nc_external_drive_mount_web_paths holds the operator's own files mounted from external storage, already stored and protected independently of this repo, not data Nextcloud itself generates.
  • Turns maintenance mode on, then stops the apache2 / php{{ cs_nc_php_version }}-fpm services, the cron, file scanner, and full text search worker systemd units, and the Nextcloud hub component containers (Redis cache, Full Text Search, Imaginary, Whiteboard, Collabora, Talk, Talk recording) for the duration of the backup. Afterwards it removes the database dump, restarts them, and turns maintenance mode back off, even if the backup itself fails.

Restore (nextcloud_restic_restore)​

  • Runs the Prepare tasks first, so the packages, PHP, Apache, certificates, and Docker network exist on a fresh host.
  • Removes the Nextcloud hub component containers (Redis cache, Full Text Search, Imaginary, Whiteboard, Collabora, Talk, Talk recording), and stops and disables the apache2 / php{{ cs_nc_php_version }}-fpm services and the Nextcloud cron timer, file scanner timer, and full text search worker systemd units, tolerating any of those units not being present on the host.
  • Restores the latest Restic snapshot into a temporary directory under /app/tmp (restores can exceed 50GB, too large for the default /tmp).
  • Imports db_backup.sql from the restored snapshot through the shared task, see Restore PostgreSQL Database for the process.
  • Rsyncs the restored web directory into cs_nc_container_root, removes the temporary directory, and resets ownership/permissions recursively.

Cleanup (dangerously_cleanup_nextcloud)​

Destructive. Only runs when this exact tag is passed explicitly (it is intentionally excluded from the plain nextcloud tag) and permanently deletes Nextcloud and all of its hub component data on the host:

  • Stops, disables, and deletes the Nextcloud cron, file scanner, and full text search worker systemd units.
  • Removes every Docker container whose name starts with nextcloud (Redis cache, Collabora, Imaginary, Whiteboard, Talk, Talk recording, Full Text Search) and the shared nextcloud Docker network.
  • Disables the Apache site and deletes its sites-available config file (the apache2 service itself is left running).
  • Deletes the PHP-FPM systemd override config (the php{{ cs_nc_php_version }}-fpm service itself is left running).
  • Deletes the Nextcloud fail2ban filter and jail config files only.
  • Deletes the UFW rules opened for the Apache port and the Talk TURN port (TCP and UDP), and the UFW rules denying the Imaginary, Whiteboard, Collabora, Talk signaling, and Talk recording ports.
  • Drops the Nextcloud database through the shared task, see Delete PostgreSQL Database for the process.
  • Deletes cs_nc_container_root, cs_nc_cache_redis_server_dir, and the parent directory of the Full Text Search data directory (cs_nc_fts_data_dir).

Tags​

  • nextcloud: Full Nextcloud deployment.
  • nextcloud_prepare: Prepare a system for Nextcloud.
  • nextcloud_prepare_db: Provision the Nextcloud PostgreSQL user and database.
  • nextcloud_install: Install Nextcloud.
  • nextcloud_cache: Configure caching.
  • nextcloud_mount: Register the external drive mounts.
  • nextcloud_admin: Admin configuration.
  • nextcloud_imaginary: Setup Imaginary.
  • nextcloud_collabora: Setup Collabora Online.
  • nextcloud_whiteboard: Setup Whiteboard.
  • nextcloud_talk: Setup Talk High-performance backend (signaling + TURN) and the call recording backend.
  • nextcloud_fulltextsearch: Setup Full Text Search.
  • nextcloud_hub_bundle: Install the hub bundle apps.
  • nextcloud_users: Manage users and groups from Vault.
  • nextcloud_post_install: Final verification, theming, monitoring, firewall, and fail2ban setup.
  • nextcloud_restic_backup: Run Restic backup for Nextcloud.
  • nextcloud_restic_restore: Restore Nextcloud's web directory and database from the latest Restic snapshot.
  • dangerously_cleanup_nextcloud: Destructive. Stops/removes Nextcloud systemd units, Docker containers/network, Apache site, PHP-FPM override, fail2ban files, UFW rules, the PostgreSQL database, and data directories. Never included by the plain nextcloud tag.

Vault configurations​

  • key: {{ cs_project_code }}/application-deployer/clusters/{{ Lab Name or Cluster name }}/hosts/{{ hostname }}/apps/nextcloud/config
{
"admin_password": "<Admin Password>",
"users_dict": {
"<User Name>": {
"display_name": "Optional",
"email": "<Proper Email mandatory>",
"groups": {
"<Group Name>": {}
}
},
"user1": {
"display_name": "My Name",
"email": "email@localhost",
"groups": {
"sd_user": {}
}
}
},
"admin_user": "<Admin Username>",
"server_info_app_token": "<Monitoring application token>",
"redis_cache_admin_password": "<Redis admin password.>",
"redis_cache_nextcloud_user_password": "<Actual password used in nextcloud>",
"apache_port": "Apache listen port for Nextcloud",
"cache_redis_server_port": "Redis server port",
"collabora_http_port": "Collabora port",
"fts_servlet_port": "FTS servlet port",
"fts_transport_port": "FTS transport port",
"imaginary_port": "Imaginary port",
"talk_port": "Talk signaling server port (localhost)",
"talk_turn_port": "Talk TURN server port (public)",
"talk_recording_port": "Talk recording backend port (localhost)",
"whiteboard_port": "Whiteboard port"
}

Deployment​

uv sync --all-extras --all-packages --no-progress
uv --offline run --no-sync --no-progress ansible-galaxy install -r requirements.yml
uv --offline run --no-sync --no-progress ansible-playbook playbook.yml --tags nextcloud