Uploading complete directory trees to FTP or SFTP storage supports website deployment, scheduled backups, and bulk data exchange between systems. Consolidating many files into a single transfer step reduces the chance of missing content and keeps deployment and backup workflows predictable. Automated jobs also benefit from a single, repeatable command that can be scheduled or integrated into build pipelines.
The cURL tool acts as a general-purpose URL transfer client for protocols such as FTP, FTPS, and SFTP. For uploads, it sends file data to a URL formed from a scheme (ftp:// or sftp://), hostname, credentials, and a remote path. Raw directory uploads are not a native feature of these protocols, so a directory is typically packed into an archive first, then uploaded as a single file that the remote system later unpacks.
Large directory uploads can overwrite live content, exceed storage quotas, or saturate network links when sent to the wrong location or with incorrect paths. Credentials placed directly in the command line appear in shell history and process listings on multiuser systems, which can leak passwords. Safer workflows rely on restricted accounts, key-based SFTP access, and test uploads into non-critical directories before replacing production data.
Steps to upload a directory using cURL:
- Check the installed cURL version and protocol support from a terminal on Linux.
$ curl --version curl 7.81.0 (x86_64-pc-linux-gnu) libcurl/7.81.0 OpenSSL/3.0.2 zlib/1.2.11 Release-Date: 2022-02-01 Protocols: dict file ftp ftps http https imap imaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp Features: AsynchDNS GSS-API HTTPS-proxy IPv6 Kerberos Largefile NTLM SSL TLS-SRP UnixSockets ##### snipped #####
Presence of ftp, ftps, and sftp in the Protocols line confirms that FTP and SFTP uploads are available through cURL without additional components.
- Move to the parent directory that contains the folder intended for upload.
$ cd /home/user $ ls project other-data
Running commands from the parent directory keeps the archive contents relative (for example, starting at project) instead of embedding an entire absolute path inside the compressed file.
- Create a compressed archive that represents the entire directory tree as a single file.
$ tar --create --gzip --file project-2025-12-archive.tar.gz project/ $ ls other-data project project-2025-12-archive.tar.gz
The file project-2025-12-archive.tar.gz now contains the full project directory including subdirectories and regular file metadata, and can be transferred in a single upload operation.
- Upload the archive to an FTP server using an authenticated ftp:// URL.
$ curl --upload-file project-2025-12-archive.tar.gz --user ftpuser ftp://ftp.example.com/public_html/project-2025-12-archive.tar.gz % Total % Received % Xferd Average Speed Time Time Time Current ##### snipped #####
Adding a password directly to --user user:password or embedding it in the URL exposes credentials in shell history and process listings; safer patterns use password prompts, locked-down .netrc files, or limited-purpose accounts.
- Send the same archive over SFTP when encrypted transport or key-based authentication is required.
$ curl --upload-file project-2025-12-archive.tar.gz --user sftpuser sftp://sftp.example.com/home/sftpuser/project-2025-12-archive.tar.gz % Total % Received % Xferd Average Speed Time Time Time Current ##### snipped #####
SFTP operates over SSH, so authentication methods such as SSH keys and agents apply, and the default remote directory is usually the SSH account’s home directory rather than a web document root.
- Allow cURL to create missing intermediate FTP directories when targeting a nested path.
$ curl --ftp-create-dirs --upload-file project-2025-12-archive.tar.gz --user ftpuser ftp://ftp.example.com/public_html/releases/2025/12/project-2025-12-archive.tar.gz % Total % Received % Xferd Average Speed Time Time Time Current ##### snipped #####
The --ftp-create-dirs option affects only FTP URLs; directories for SFTP targets normally must be created separately with SSH commands or deployment tooling before uploading.
- Confirm that the archived directory file exists on the remote server by listing the upload location.
$ curl ftp://ftpuser@ftp.example.com/public_html/releases/2025/12/ ##### snipped ##### -rw-r--r-- 1 1000 1000 2345678 Dec 07 12:34 project-2025-12-archive.tar.gz ##### snipped ##### $ curl sftp://sftpuser@sftp.example.com/home/sftpuser/ ##### snipped #####
Appearance of project-2025-12-archive.tar.gz with the expected size and a recent timestamp indicates that the directory upload archive reached the remote system successfully and is ready to be unpacked there.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
Comment anonymously. Login not required.
