How to Set Up Nextcloud Upload with Automatic Directory Creation for iCloud Photos
The docker-icloudpd container automatically mirrors your local iCloud photo directory structure to Nextcloud by detecting file changes, creating remote folders via WebDAV MKCOL requests, and uploading content—requiring only five environment variables to enable.
The boredazfcuk/docker-icloudpd container downloads photos from Apple's iCloud service and can synchronise them to a Nextcloud server while preserving your folder hierarchy. Setting up Nextcloud upload with automatic directory creation involves configuring environment variables that trigger WebDAV-based directory provisioning and file streaming. This guide explains the underlying mechanics based on the actual shell script implementation and provides a complete configuration reference.
How the Automatic Nextcloud Upload Works
The synchronisation logic resides in sync-icloud.sh and executes a three-stage pipeline whenever the nextcloud_upload flag is set to true【sync‑icloud.sh line 166‑170】.
Stage 1: Detecting File Changes
The script monitors /tmp/icloudpd/icloudpd_sync.log for lines containing "Downloaded /" or "Deleted /" to identify new or removed assets【sync‑icloud.sh line 1271‑1275】. It extracts the relative file paths from these log entries to determine exactly which items need processing.
Stage 2: Creating Remote Directories
Before uploading files, the nextlcoud_create_directories function ensures the remote folder hierarchy exists:
- It parses unique sub-paths from the download log to build the required directory tree【
sync‑icloud.shline 1235‑1241】. - Each path is URL-encoded for safe WebDAV transmission【
sync‑icloud.shline 1243‑1246】. - The function probes each remote directory with
curl; if the HTTP response is not 2xx, it issues aMKCOLrequest to create the missing folder【sync‑icloud.shline 1249‑1264】.
This guarantees that structures like 2022/12/25 are replicated exactly on the Nextcloud server without manual intervention.
Stage 3: Uploading Files
Once directories exist, the nextcloud_upload function streams each file (and its associated JPEG version if applicable) to the corresponding WebDAV endpoint using curl【sync‑icloud.sh line 1296‑1332】. The upload targets the nextcloud_target_dir root with the preserved sub-folder hierarchy appended.
Required Configuration
To activate automatic Nextcloud upload, you must populate specific variables in /config/icloudpd.conf or inject them as environment variables when creating the container.
Mandatory Environment Variables
Set the following five variables to enable the integration:
nextcloud_upload: Set totrueto enable the upload workflow【CONFIGURATION.mdline 1225】.nextcloud_url: The base URL of your Nextcloud instance (e.g.,https://cloud.example.com)【CONFIGURATION.mdline 1223】.nextcloud_username: Your Nextcloud account username【CONFIGURATION.mdline 1229】.nextcloud_password: Your Nextcloud account password or app-specific token【CONFIGURATION.mdline 1230】.nextcloud_target_dir: The root folder inside Nextcloud where photos will reside (e.g.,Photos). Note: You cannot upload to the absolute root of Nextcloud; a sub-folder is mandatory【CONFIGURATION.mdline 1225‑1226】.
Optional Settings
nextcloud_delete: Set totrueto mirror local deletions to Nextcloud, removing files from the remote server when they are deleted locally【CONFIGURATION.mdline 1221】.folder_structure: Defines the local directory pattern (e.g.,{:%Y/%m/%d}). The same hierarchy will be reproduced in Nextcloud because the directory-creation step uses the exact relative paths from the log【CONFIGURATION.mdline 36】.
Step-by-Step Setup Guide
Follow these steps to configure the container for automatic Nextcloud upload with directory creation:
-
Prepare the host volume. Create a sentinel file named
.mountedin your host bind-mount directory (e.g.,/home/joe/iCloud/.mounted). Without this file, the sync loop exits immediately as a failsafe measure. -
Define the target directory. Decide on a root folder name in Nextcloud (such as
Photos). Remember that uploads cannot occur at the Nextcloud root level. -
Configure variables. Set
nextcloud_upload=trueand providenextcloud_url,nextcloud_username,nextcloud_password, andnextcloud_target_dirvia environment variables or edit/config/icloudpd.confafter the first run. -
Enable deletion sync (optional). If you want remote files deleted when local copies are removed, set
nextcloud_delete=true. -
Start the container. On initialization, the script runs
check_nextcloud_connectivityto verify it can reach the WebDAV endpoint (expecting HTTP 200)【sync‑icloud.shline 1179‑1182】. If successful, subsequent sync cycles will automatically create directories and upload files.
Docker Compose Example
Use the following docker-compose.yml configuration to deploy the container with Nextcloud integration enabled:
version: "3.8"
services:
icloudpd:
image: boredazfcuk/icloudpd
container_name: icloudpd
restart: always
environment:
TZ: Europe/London
apple_id: "my@email.com"
download_path: "/home/joe/iCloud"
folder_structure: "{:%Y/%m/%d}"
# Nextcloud integration
nextcloud_upload: "true"
nextcloud_url: "https://cloud.example.com"
nextcloud_username: "myuser"
nextcloud_password: "mysecret"
nextcloud_target_dir: "Photos"
# Optional deletion sync
# nextcloud_delete: "true"
volumes:
- icloudpd_config:/config
- /home/joe/iCloud:/home/joe/iCloud
volumes:
icloudpd_config:
Ensure you create the .mounted file on the host before starting:
touch /home/joe/iCloud/.mounted
Configuration File Reference
After the first run, the container generates /config/icloudpd.conf. You can edit this file directly to adjust Nextcloud settings:
apple_id = my@email.com
download_path = /home/joe/iCloud
folder_structure = {:%Y/%m/%d}
# Nextcloud settings
nextcloud_upload = true
nextcloud_url = https://cloud.example.com
nextcloud_username = myuser
nextcloud_password = mysecret
nextcloud_target_dir = Photos
nextcloud_delete = false
Summary
- The
nextlcoud_create_directoriesfunction insync-icloud.shautomatically provisions the remote folder structure using WebDAVMKCOLrequests before any files are transferred. - You must set
nextcloud_upload=trueand provide valid credentials plus anextcloud_target_dir(sub-folder) to enable the integration. - The script parses
/tmp/icloudpd/icloudpd_sync.logto detect new files and determine which directories need creation. - A sentinel file named
.mountedmust exist in the host download directory to allow the sync loop to run. - Optional deletion syncing via
nextcloud_delete=trueensures the remote server mirrors local removals.
Frequently Asked Questions
Does the script create the directory structure automatically on Nextcloud?
Yes. The nextlcoud_create_directories function extracts unique sub-paths from the download log and issues WebDAV MKCOL requests for any missing directories【sync‑icloud.sh line 1249‑1264】. This ensures your local folder hierarchy (e.g., 2024/06/15) is replicated exactly on the Nextcloud server without manual creation.
What happens if I don't set nextcloud_target_dir?
The upload will fail. According to the configuration documentation, nextcloud_target_dir is mandatory and must specify a sub-folder within Nextcloud (such as Photos or iCloudBackup). The script cannot upload files to the absolute root of the Nextcloud storage【CONFIGURATION.md line 1225‑1226】.
Can I sync deletions from iCloud to Nextcloud?
Yes. Set nextcloud_delete=true in your configuration. When enabled, the script parses the sync log for "Deleted /" entries and removes the corresponding files from the Nextcloud server via WebDAV DELETE requests, keeping the remote directory in sync with local deletions【CONFIGURATION.md line 1221】.
Why is the .mounted file required?
The .mounted file acts as a failsafe sentinel. The script checks for the existence of /home/<user>/iCloud/.mounted before proceeding with any synchronisation. If this file is absent, the sync loop exits early to prevent data loss or errors when the host volume is not properly mounted. Create this file with touch on your host system before starting the container.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →