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 truesync‑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.sh line 1235‑1241】.
  • Each path is URL-encoded for safe WebDAV transmission【sync‑icloud.sh line 1243‑1246】.
  • The function probes each remote directory with curl; if the HTTP response is not 2xx, it issues a MKCOL request to create the missing folder【sync‑icloud.sh line 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 curlsync‑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 to true to enable the upload workflow【CONFIGURATION.md line 1225】.
  • nextcloud_url: The base URL of your Nextcloud instance (e.g., https://cloud.example.com)【CONFIGURATION.md line 1223】.
  • nextcloud_username: Your Nextcloud account username【CONFIGURATION.md line 1229】.
  • nextcloud_password: Your Nextcloud account password or app-specific token【CONFIGURATION.md line 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.md line 1225‑1226】.

Optional Settings

  • nextcloud_delete: Set to true to mirror local deletions to Nextcloud, removing files from the remote server when they are deleted locally【CONFIGURATION.md line 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.md line 36】.

Step-by-Step Setup Guide

Follow these steps to configure the container for automatic Nextcloud upload with directory creation:

  1. Prepare the host volume. Create a sentinel file named .mounted in your host bind-mount directory (e.g., /home/joe/iCloud/.mounted). Without this file, the sync loop exits immediately as a failsafe measure.

  2. 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.

  3. Configure variables. Set nextcloud_upload=true and provide nextcloud_url, nextcloud_username, nextcloud_password, and nextcloud_target_dir via environment variables or edit /config/icloudpd.conf after the first run.

  4. Enable deletion sync (optional). If you want remote files deleted when local copies are removed, set nextcloud_delete=true.

  5. Start the container. On initialization, the script runs check_nextcloud_connectivity to verify it can reach the WebDAV endpoint (expecting HTTP 200)【sync‑icloud.sh line 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_directories function in sync-icloud.sh automatically provisions the remote folder structure using WebDAV MKCOL requests before any files are transferred.
  • You must set nextcloud_upload=true and provide valid credentials plus a nextcloud_target_dir (sub-folder) to enable the integration.
  • The script parses /tmp/icloudpd/icloudpd_sync.log to detect new files and determine which directories need creation.
  • A sentinel file named .mounted must exist in the host download directory to allow the sync loop to run.
  • Optional deletion syncing via nextcloud_delete=true ensures 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →