Skip to content
capcom6Public

About

Command-line utility for syncing a local folder with a remote server on every change of files or directories.

Topics

Resources

Stars

13 stars

Watchers

1 watching

Forks

Repository files navigation

Code Size Contributors Forks Go Report Card Go Version Issues Last Commit License Stargazers


Logo

sftp-sync

A command-line utility for syncing a local folder with a remote FTP or SFTP server on every change of files or directories.

Report Bug · Request Feature

About The Project

sftp-sync is a command-line utility for syncing a local folder with a remote FTP or SFTP server on every change of files or directories.

Features

  • Continuous synchronization: Automatically syncs local changes to the remote FTP or SFTP server whenever files or directories are added, modified, or deleted, including recursive changes in subdirectories.
  • Exclude paths: Allows you to exclude specific paths from being synced, with support for glob patterns (*, **, ?).
  • Dry run mode: Preview what would be created, modified, or removed without uploading anything (--dry-run).
  • Easy to use: Simple and intuitive command-line interface.
  • Protocol support: Supports both FTP and SFTP (SSH File Transfer Protocol).
  • Flexible SFTP authentication: Password, SSH private key (optionally passphrase-protected), or SSH agent.
  • Graceful shutdown: Stops cleanly on Ctrl+C (SIGINT) or SIGTERM, including during a recursive sync.

(back to top)

Built With

  • Go
  • urfave/cli
  • fsnotify
  • jlaffaye/ftp
  • pkg/sftp
  • bmatcuk/doublestar
  • joho/godotenv

(back to top)

Installation

Prerequisites

  • Go 1.26.0 or higher installed on your system
  • Access to an (S)FTP server with valid credentials

Installation Methods

Method 1: Using Go Install (Recommended)

Install the latest version directly from the repository:

go install github.com/capcom6/sftp-sync@latest

This will install sftp-sync to your $GOBIN directory. Make sure your $GOBIN is in your $PATH.

Method 2: Using Release Binaries

Download the pre-compiled binaries from the GitHub Releases page:

  1. Download the binary for your operating system and architecture
  2. Make the binary executable:
    chmod +x sftp-sync
  3. Move it to a directory in your $PATH:
    sudo mv sftp-sync /usr/local/bin/

Method 3: Building from Source

If you prefer to build from source:

git clone https://github.com/capcom6/sftp-sync.git
cd sftp-sync
make build

The binary will be available in the bin/ directory.

(back to top)

Usage

Run the sftp-sync command with the necessary options and arguments:

FTP:

sftp-sync --dest=ftp://username:password@hostname:port/path/to/remote/folder \
  --exclude=.git /path/to/local/folder

SFTP (password):

sftp-sync --dest=sftp://username:password@hostname:22/path/to/remote/folder \
  --exclude=.git /path/to/local/folder

SFTP (SSH key):

sftp-sync --dest="sftp://username@hostname:22/path/to/remote/folder?key=~/.ssh/id_ed25519" \
  --exclude=.git /path/to/local/folder

SFTP (SSH agent):

sftp-sync --dest="sftp://username@hostname:22/path/to/remote/folder?agent=true" \
  --exclude=.git /path/to/local/folder

Dry run (preview without uploading):

sftp-sync --dry-run --dest=ftp://username:password@hostname:port/path/to/remote/folder \
  --exclude=.git /path/to/local/folder

Note: SFTP uses SSH port 22 by default (vs FTP port 21).

Global Options

  • --debug: Enable debug mode (can also be set via DEBUG environment variable).
  • --version: Print version information.

Options

  • --dest: The destination server URL. Supports both FTP and SFTP:
    • FTP: ftp://username:password@hostname:port/path/to/remote/folder
    • SFTP (password): sftp://username:password@hostname:22/path/to/remote/folder
    • SFTP (SSH key): sftp://username@hostname:22/path?key=~/.ssh/id_ed25519
    • SFTP (SSH key with passphrase): sftp://username@hostname:22/path?key=~/.ssh/id_ed25519&key_pass=<passphrase>
    • SFTP (SSH agent): sftp://username@hostname:22/path?agent=true

The URL path (e.g., /path/to/remote/folder) is used as the remote destination prefix. All synced files and directories are placed relative to this path. The remote directory must already exist before starting the sync.

SFTP URL query parameters:

Parameter Description Example
key Path to SSH private key file (supports ~ expansion). If omitted, auto-detects a default key only when no password is set and agent auth provides no signers key=~/.ssh/custom_key
key_pass Passphrase for encrypted private keys key_pass=mysecret
agent Use SSH agent for authentication when set to true (requires SSH_AUTH_SOCK) agent=true
timeout Connection timeout as a Go duration (e.g., 30s, 1m) timeout=45s

Authentication methods are tried in order: SSH agent → private key → password. If agent setup fails, the error is returned instead of falling back to a default key. SFTP host keys are verified against ~/.ssh/known_hosts.

Security note: Avoid putting real passwords/passphrases directly in CLI arguments when possible, as they can be exposed via shell history and process listings.

  • --exclude: (Optional) Specifies paths or glob patterns to exclude from synchronization. Supports *, **, and ?. You can specify multiple --exclude options.
  • --dry-run: (Optional) Log what would be created, modified, or removed without uploading or deleting anything on the remote server.

Arguments

  • source: The local folder path to watch for changes (required positional argument).

(back to top)

Error Handling

The application uses structured error handling with specific exit codes:

  • 0: Success - operation completed successfully, including an interrupted sync stopped with Ctrl+C
  • 1: Parameters Error - invalid positional arguments (missing or extra source), or an empty --dest
  • 2: Client Error - the destination URL could not be parsed or uses an unsupported scheme (only ftp and sftp are supported)
  • 3: Output Error - reserved for logging or output system failures
  • 4: Internal Error - unexpected internal errors, including flag errors reported by the CLI framework (e.g., a missing required --dest or an unknown flag)

Failures that occur while syncing (for example, the remote server is unreachable) are logged and the watcher keeps running; the process does not exit.

(back to top)

Configuration

Environment Variables

Variable Purpose Format Default Example
DEBUG Enables debug logging (equivalent to the --debug flag). Boolean accepted by Go's strconv.ParseBool: 1, t, T, true, TRUE, True. 0/false disables. unset (disabled) DEBUG=1
SSH_AUTH_SOCK Path to the SSH agent socket. Read-only — provided by ssh-agent; used when the destination URL has ?agent=true. Unix socket path set by the system/ssh-agent /tmp/ssh-XXXXXX/agent.1234

Note: an unparseable DEBUG value (e.g. DEBUG=yes) makes the command fail at startup with exit code 4.

The .env File

On startup the application loads environment variables from a .env file in the current working directory (via godotenv); a missing file is ignored. This is a convenient way to set DEBUG without typing it on every run:

DEBUG=1

See .env.example for a documented template.

(back to top)

Roadmap

  • Support for patterns in the --exclude option.
  • Support of Secure FTP (SFTP) protocol.
  • Improved error handling and error messages.
  • Integration with Git for automatic syncing on commit or branch changes.
  • Integration with Git for linking branch to remote server.
  • Support for other remote protocols such as S3.
  • Support for syncing specific file types or file name patterns.
  • Preserve attributes (if available).
  • Parallel sync in multiple threads.
  • Batching events for more effective sync on frequently changes.

See the open issues for a full list of proposed features (and known issues).

(back to top)

Contributing

Contributions are what make the open-source community a great place to learn, inspire, and create. Any contributions you make are greatly appreciated.

If you have a suggestion to improve this project, please fork the repository and open a pull request. You can also open an issue with the enhancement label.
If this project is useful to you, consider starring it.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

(back to top)

License

Distributed under the Apache License 2.0. See LICENSE for more information.

(back to top)

Contact

Project Link: https://github.com/capcom6/sftp-sync

(back to top)

Acknowledgments

(back to top)

About

Command-line utility for syncing a local folder with a remote server on every change of files or directories.

Topics

Resources

Stars

13 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages