SFTPGo: One Go Binary for SFTP, HTTP/S, FTP/S and WebDAV on Top of S3, GCS or Azure Blob
Full-featured and highly configurable SFTP, HTTP/S, FTP/S and WebDAV server - S3, Google Cloud Storage, Azure Blob
At a glance
- What is it?
- SFTPGo is an AGPL-3.0 file transfer server that speaks four protocols and stores files on a local disk, an encrypted local disk, object storage or another SFTP server. The Community edition is production-ready; the Enterprise edition is a commercial drop-in replacement, and that split is the main thing to understand before adopting it.
- Who is it for?
- Adopt the Community edition if you need SFTP, FTP/S, WebDAV and HTTP/S in front of object storage and your legal position on AGPL-3.0 is settled; skip it if you need browser-based document co-authoring, IMAP attachment ingestion or ICAP antivirus, which the README lists only for the Enterprise edition.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What SFTPGo actually replaces
Most teams that end up here have the same shape of problem. Partners and internal scripts speak SFTP, an application speaks HTTP, a legacy integration only does FTP/S, and someone wants WebDAV for a desktop client. The files themselves live in S3 or Azure Blob, not on the server. Standing up four daemons and a sync layer between them is the alternative.
SFTPGo collapses that into one process. The README describes it as a "Full-featured and highly configurable event-driven file transfer solution" with four server protocols and six storage backends: local filesystem, encrypted local filesystem, S3-compatible object storage, Google Cloud Storage, Azure Blob Storage, and other SFTP servers. The last one matters more than it looks. A storage backend that is itself SFTP means SFTPGo can act as a front door that terminates a modern protocol and forwards to a machine you cannot change.
The audience is narrower than "anyone who moves files". It fits teams that already run object storage and want legacy protocols pointed at it, and teams that want per-user quotas, per-user storage backends and an audit trail without writing that layer themselves. It does not fit someone who just wants to scp a file between two laptops.
The architecture is a protocol layer over a pluggable storage interface
The repository layout tells the story better than the README does. main.go is a thin entry point. internal/ holds the servers and the business logic. pkgs/ holds the pieces meant to be imported, and the go.mod file shows what those pieces are built on: github.com/pkg/sftp for the SFTP side, github.com/fclairamb/ftpserverlib for FTP/S, github.com/drakkan/webdav for WebDAV, and github.com/go-chi/chi/v5 for the HTTP API and the WebAdmin/WebClient interfaces.
The cloud backends are the vendor SDKs you would expect: aws-sdk-go-v2 with the s3 and sts service packages, cloud.google.com/go/storage, and the Azure azblob, azidentity and azcore packages. That is a deliberate choice with a cost. It means the binary carries three cloud SDKs, and the Dockerfile exposes a way out: the FEATURES build argument can strip them, with the comment showing --build-arg FEATURES=nos3,nogcs as the example.
State lives outside the process. Users, quotas and configuration are persisted through a database layer that go.mod shows supporting SQLite (mattn/go-sqlite3), PostgreSQL (jackc/pgx/v5), MySQL (go-sql-driver/mysql) and CockroachDB (cockroachdb/cockroach-go/v2). That is what makes the "Standard, Shared DB & Storage" high-availability row in the README's edition table possible at all: several SFTPGo instances can point at one database and one storage backend. The README does not document the coordination details beyond calling the Enterprise version's handling "Enhanced", so treat multi-instance behaviour as something to verify rather than assume.
Installing SFTPGo with Docker and creating a first user
The README points at docs.sftpgo.com for configuration and does not inline install steps, but the repository ships three Dockerfiles: Dockerfile, Dockerfile.alpine and Dockerfile.distroless. The main Dockerfile builds with Go and produces a binary, then copies it onto a debian:trixie-slim base. It creates the directories the server expects, including /etc/sftpgo, /var/lib/sftpgo and /srv/sftpgo/data, and creates a system user and group with UID and GID 1000.
The build accepts several arguments. FEATURES disables optional protocol or storage support at compile time. The Dockerfile comment gives this exact invocation as the example of dropping S3 and GCS support:
--build-arg FEATURES=nos3,nogcsThe same file defines DOWNLOAD_PLUGINS, which when set to true runs ./docker/scripts/download-plugins.sh to fetch the official plugins into /usr/local/bin, and INSTALL_OPTIONAL_PACKAGES, which installs jq. The Dockerfile also passes COMMIT_SHA through to the build so the version stamp is set.
At runtime the container needs the config and data directories mounted so state survives a restart. The Dockerfile is what defines those paths, and the repository ships a top-level sftpgo.json as the configuration template plus a docker/ directory holding the container assets. The README does not publish default port numbers, so read the bindings from your sftpgo.json rather than assuming them.
Once it is up, the WebAdmin interface is where you create a user. The README states the Community edition includes "all the core protocols, storage backends, and the WebAdmin/WebClient UIs", so user creation, quota assignment and per-user storage backend selection all happen there rather than in a config file. The repository also ships examples/bulkupdate and examples/convertusers, which are the practical way to move a user set in or out without clicking through the UI.
Where the Community edition stops
The README is unusually direct about the split, and the table is the most useful page in the project for anyone deciding. Several capabilities exist only in the commercial edition: in-memory streaming for cloud storage with no local temp files, IMAP integration that extracts email attachments into storage, automated PGP encryption, antivirus and DLP scanning through ICAP, browser-based document viewing and co-authoring, and email authentication for public shares.
The in-memory streaming row deserves attention because it is not a convenience feature. The Community edition's cloud storage engine is listed as "Standard", and the Enterprise one as using "In-memory streaming (no local temp files)". If your transfers are large and your container filesystem is small or ephemeral, the standard path is a real constraint you need to size for. The README does not state a buffer size or a temp directory location, so that is a question for the documentation rather than the README.
The licensing boundary is the other hard edge. The source is GNU AGPL-3.0-only with additional terms in the NOTICE file, and the README adds that the KeenThemes theme used in the WebAdmin and WebClient interfaces is proprietary and "allowed for use only within the SFTPGo product". If you plan to fork the UI or embed it in something you ship, read NOTICE before you start, not after.
When SFTPGo is the wrong tool
If your requirement is file synchronization with conflict resolution, version history and a desktop client that keeps a folder in step, SFTPGo is not that. It is a server. It serves bytes over protocols and enforces access rules; it does not reconcile two divergent copies of a directory. A user comparing it to Nextcloud is comparing a transfer endpoint to a collaboration platform, and the comparison only makes sense if you have already decided you want the transfer endpoint.
A second failure mode is treating the Community edition as feature-complete against the Enterprise one. The README's own table says otherwise. Teams that plan around antivirus scanning on upload, PGP encryption at rest through the product, or extracting attachments from a mailbox will discover those are commercial rows. Discovering that after building an ingestion pipeline is expensive.
Third, the build-time feature flags are a one-way door in a specific sense. If you build with FEATURES=nos3,nogcs to shrink the image, S3 and GCS support are not present at runtime. There is no plugin that adds them back later; you rebuild. That is fine for a fixed deployment and awkward for a general-purpose image you hand to other teams.
SFTPGo against a plain OpenSSH plus rclone setup
The obvious alternative is the one most teams already have: OpenSSH's internal-sftp subsystem for SFTP, plus rclone or a similar tool to move data to object storage. The difference in approach is where the storage abstraction lives. With OpenSSH and rclone, the filesystem is the filesystem and object storage is a separate process you schedule or trigger. With SFTPGo, the storage backend is a per-user configuration value, so a single SFTP endpoint can serve one user from local disk and another from Azure Blob without either user knowing.
That is the whole argument for SFTPGo, and it comes with the whole argument against it. You are adopting a Go application with three cloud SDKs, a database dependency and a web UI, in exchange for that abstraction. If every user writes to the same local disk, OpenSSH is smaller, older and has fewer moving parts. If your users need to land in different storage backends under one hostname, writing that yourself is a project, not a config change.
The other realistic alternative is a managed SaaS file transfer service. The README notes SFTPGo Enterprise is available as on-premises or "Fully managed SaaS" via sftpgo.com, so the project itself offers that path. Choosing it trades the AGPL-3.0 question for a vendor relationship, which for some legal teams is the deciding factor and for others is disqualifying.
Maintenance, releases and what the licence asks of you
The repository is not archived, and the last push was on 2026-09-19, the same day as the v2.7.6 release. Before that, v2.7.5 landed on 2026-07-17 and v2.7.4 on 2026-06-27. That is roughly a two-month cadence through the summer, with a patch release arriving alongside the most recent push.
The README describes the cadence as feature-driven and states the split plainly: the Enterprise edition "Receives major new features first and follows a faster release cadence", while the Community edition "Remains maintained, receiving bug fixes, security updates, and updates to core features". Read that as a commitment to maintenance, not to feature parity. If you adopt the Community edition, the upgrade cost is a binary swap plus whatever database migrations the release notes call for; the README does not document a rollback procedure, so testing an upgrade against a copy of your database is on you.
On licensing: AGPL-3.0-only with additional terms in NOTICE. The practical question for most teams is whether they are distributing the software or offering it as a network service, because the AGPL's network clause is what distinguishes it from the GPL. The README does not interpret this for you, and neither should a review. What the README does say clearly is that the WebAdmin and WebClient theme is proprietary and restricted to use within the SFTPGo product, which is a separate constraint from the AGPL and applies even though the rest of the code is copyleft.
Editorial conclusion
Adopt the Community edition if you need SFTP, FTP/S, WebDAV and HTTP/S in front of object storage and your legal position on AGPL-3.0 is settled; skip it if you need browser-based document co-authoring, IMAP attachment ingestion or ICAP antivirus, which the README lists only for the Enterprise edition. Before committing, confirm two things in your own environment: that your storage backend works with the standard cloud storage engine rather than the Enterprise in-memory streaming path, and that the KeenThemes licence terms in the NOTICE file are acceptable for however you plan to redistribute the WebAdmin and WebClient interfaces.
Frequently asked questions
Is SFTPGo free?
The Community edition is free and licensed under AGPL-3.0-only, and the README calls it a fully functional, production-ready solution that includes all core protocols, storage backends and the WebAdmin/WebClient UIs. A commercial Enterprise edition exists alongside it under a proprietary licence.
Is SFTPGo open source?
Yes. SFTPGo source code is licensed under the GNU AGPL-3.0-only with additional terms described in the NOTICE file. The README also notes that the theme used in the WebAdmin and WebClient interfaces is proprietary and licensed separately.
Does SFTPGo support SCP?
SCP appears in the repository's topic list, alongside sftp, ftp, webdav and sftp-server. The README itself lists SFTP, HTTP/S, FTP/S and WebDAV as the server protocols and does not describe SCP behaviour in detail.
How do I install SFTPGo on Ubuntu?
The repository does not give Ubuntu install steps in the README. It ships Dockerfile, Dockerfile.alpine and Dockerfile.distroless, and the README points to docs.sftpgo.com for supported features and configuration options.
What is SFTPGo?
It is an event-driven file transfer server written in Go that exposes SFTP, HTTP/S, FTP/S and WebDAV, and can store files on a local filesystem, an encrypted local filesystem, S3-compatible object storage, Google Cloud Storage, Azure Blob Storage or another SFTP server.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/drakkan-sftpgo)